Compare commits

...
495 Commits
Author SHA1 Message Date
Awasum YannickandGitHub 5c9028fcd0 Merge pull request #563 from mohitsinha/develop
JdbcSupport added utility function for getting localDateTime after considering timezone of tenant
2019-07-07 20:09:17 +01:00
Awasum YannickandGitHub 18517f53d7 Merge pull request #616 from vorburger/upgrade-drizzle
upgrade Drizzle JDBC from 1.3 to 1.4
2019-07-05 16:57:40 +01:00
Steve ConradandGitHub dcaf9fc212 Merge pull request #603 from vorburger/improve-OpenJPA-Version
make OpenJPA version easier to change
2019-07-04 08:26:24 -05:00
Michael Vorburger.ch dd4923888b upgrade Drizzle JDBC from 1.3 to 1.4 2019-07-04 10:43:05 +02:00
Michael Vorburger.ch d3e977cc99 use slf4j instead Apache Commons Logging in CustomAuthenticationFailureHandler 2019-07-04 08:44:30 +02:00
Michael Vorburger.ch e478b02931 ditch un-used import of (very old) serp.util.Strings 2019-07-04 08:43:02 +02:00
Michael Vorburger.ch e97b12a3f9 make OpenJPA version, used twice, a variable, instead of repeating it 2019-07-03 23:40:17 +02:00
Michael Vorburger.ch c296c314b3 move versions in build.gradle
so that the buildscript block can already use them
2019-07-03 23:40:17 +02:00
Steve ConradandGitHub 0d3a70db24 Merge pull request #600 from vorburger/develop
add missing license header to .dockerignore
2019-07-03 15:22:02 -05:00
Michael Vorburger.ch 629cd4da12 add missing license header to .dockerignore 2019-07-03 21:57:28 +02:00
Steve ConradandGitHub 4e16f328c5 Merge pull request #599 from vorburger/dockerignore
add suitable .dockerignore
2019-07-02 07:54:04 -05:00
Michael Vorburger.ch dd438f9b36 add suitable .dockerignore
This reduces the `docker build` time spent in
`STEP 6: COPY . fineract` from about 6m to 3m,
because it avoids copying locally built artifacts
into the container (which we don't need there, we're
just about to re-build them in the container anyway).

This also provides better isolation from the local dev
environment and the should lead to more reproducible
container builds.
2019-07-02 08:46:13 +02:00
conradspandMichael Vorburger ⛑️ 21f50ef132 Set host to fineractmysql when running in docker 2019-07-01 19:21:58 +02:00
Steve ConradandGitHub ea29fac9f5 Merge pull request #565 from marta-jankovics/mojaloop-fineract_1.0.1
FINERACT-706: Interoperation Mojaloop integration 1.0.1
2019-06-30 14:28:37 -05:00
conradspandMichael Vorburger ⛑️ b8dadd0419 Added license, moved db init file 2019-06-29 15:38:33 +02:00
conradspandMichael Vorburger ⛑️ ec0c9dc0eb Update readme - removed unnecessary instruction 2019-06-29 15:38:33 +02:00
conradspandMichael Vorburger ⛑️ 7574daf79e Change port from 443 to 8443 2019-06-29 15:38:33 +02:00
conradspandMichael Vorburger ⛑️ 21cc14c9f2 Simplify docker process - run from root directory 2019-06-29 15:38:33 +02:00
conradspandMichael Vorburger ⛑️ 357820a7a7 Create one-touch deploy with docker 2019-06-29 15:38:33 +02:00
Vishwas Babu A JandGitHub 900cdcbf4c Merge pull request #594 from vorburger/fix-V271__accounting_for_client_charges.sql
fix minor SQL syntax problem in V271__accounting_for_client_charges.sql
2019-06-20 12:51:34 -07:00
Michael Vorburger.ch fc01dd25b7 fix minor SQL syntax problem in V271__accounting_for_client_charges.sql 2019-06-20 21:06:48 +02:00
Michael Vorburger.ch 720a39d9d2 rename SQL Query Parameters (fixes FINERACT-766) 2019-06-16 23:47:15 +02:00
Vishwas Babu A JandGitHub bbfa2d080d Merge pull request #591 from vorburger/clarify-readme-gradle-wrapper
clarify README doc re. downloading the Gradle wrapper
2019-06-15 18:28:05 -07:00
Vishwas Babu A JandGitHub f10bff2665 Merge pull request #584 from mohitsinha/repaymentbatch
Batch Repayment strategy - New feature
2019-06-14 13:05:52 -07:00
Vishwas Babu A JandGitHub 694920d403 Merge pull request #587 from apache/rm-readme-gradle-wrapper
minor README clean up to remove more left over Gradle wrapper mentions
2019-06-14 13:01:12 -07:00
Vishwas Babu A JandGitHub 5a1158a58d Merge pull request #590 from vorburger/develop
run integrationTest on Travis without gradlew migrateTenantDB/migrateTenantListDB (re. FINERACT-765)
2019-06-14 12:57:03 -07:00
Mohit Sinha 86e105ff15 FINERACT-767: Batch Repayment for loans 2019-06-14 23:26:17 +07:00
Michael Vorburger.ch 4bd29f9b4d Clarify instructions to download gradle wrapper (see #587) 2019-06-14 14:45:06 +02:00
Michael Vorburger.ch 4a94b8b6b8 Revert "remove Instructions to download gradle wrapper from README" (see #587)
This reverts commit 92bdd539e5.
2019-06-14 14:45:06 +02:00
Michael Vorburger.ch 0d246d44a1 run integrationTest on Travis without gradlew migrateTenantDB/migrateTenantListDB (re. FINERACT-765) 2019-06-14 14:11:20 +02:00
Vishwas Babu A JandGitHub a4a3a779c3 Merge pull request #586 from apache/doc-docker-mysql
fix ./gradlew createDB && document how to run mysql in docker container in README
2019-06-13 22:23:31 -07:00
Michael Vorburger.ch 34e6a4f81e fix ./gradlew createDB / dropDB / setBlankPassword 2019-06-14 01:29:10 +02:00
Michael Vorburger ⛑️andGitHub fc7a5dd5fc add link to .travis.yaml and fix typo in README 2019-06-13 23:55:56 +02:00
Michael Vorburger ⛑️andGitHub 878cade280 minor README clean up to remove more left over Gradle wrapper mentions 2019-06-13 23:45:04 +02:00
Michael Vorburger ⛑️andGitHub 3cf395da72 document how to run mysql in docker container in README 2019-06-13 23:41:21 +02:00
Vishwas Babu A JandGitHub ffc4a8b398 Merge pull request #582 from apache/FINERACT-761_LEGAL-462_use-MariaDB-ConnectorJ-instead-Drizzle-in-build
use MariaDB ConnectorJ instead of Drizzle MySQL JDBC driver -only- during build for Flyway (fixes FINERACT-761)
2019-06-12 21:27:13 -07:00
Vishwas Babu A JandGitHub 4bc82a20fe Merge pull request #580 from mohitsinha/batchfix
Fineract-759: Thread unsafe bug in batch transactions
2019-06-12 20:21:55 -07:00
Michael Vorburger.ch b8397a4304 add blurb re. LGPL JDBC Driver to README (fixes LEGAL-462) 2019-06-12 21:17:29 +02:00
Michael Vorburger.ch 82d79b91fe use MariaDB ConnectorJ instead of Drizzle MySQL JDBC driver -only- during build for Flyway (fixes FINERACT-761) 2019-06-12 21:17:29 +02:00
Michael Vorburger.ch 02d51b115a use Ubuntu Trusty instead of Xenial on Travis CI (fixes FINERACT-763)
see https://issues.apache.org/jira/browse/FINERACT-763

re. https://changelog.travis-ci.com/xenial-as-the-default-build-environment-99476
2019-06-12 21:15:49 +02:00
Awasum YannickandGitHub aea7ee74b3 Merge pull request #581 from apache/rm-gradle-wrapper-doc
remove Instructions to download gradle wrapper from README
2019-06-12 09:52:39 +01:00
Michael Vorburger ⛑️andGitHub 92bdd539e5 remove Instructions to download gradle wrapper from README
as already removed from Requirements in previous commit 2f80674a2c

because the Gradle Wrapper is available in fineract-provider/gradle/wrapper and therefore not a pre-requisite to contribute
2019-06-12 09:28:36 +02:00
Michael Vorburger ⛑️andGitHub 2f80674a2c remove gradle-wrapper.jar requirement from README
because it is available in fineract-provider/gradle/wrapper and therefore not a pre-requisite to contribute
2019-06-12 09:24:09 +02:00
Mohit Sinha 48687a3103 Fineract-759: Thread unsafe bug in batch transactions 2019-06-12 14:05:44 +07:00
Vishwas Babu A JandGitHub 93e0137d4f Merge pull request #573 from vishwasbabu/develop
FINERACT-758
2019-05-28 10:55:29 -07:00
Vishwas Babu A J 61045cabad FINERACT-758 2019-05-28 10:07:16 -07:00
Vishwas Babu A JandGitHub cc05940517 Merge pull request #572 from angelboxes/FINERACT-757
FINERACT-757: Client list retrieval returns emtpy result when using search parameter
2019-05-28 09:52:15 -07:00
Vishwas Babu A JandMohit Sinha 7ffed1db76 Revert "Adding a compress response filter,registering filter"
This reverts commit eb5ad448fa.
2019-05-28 17:25:46 +07:00
Awasum YannickandMohit Sinha c5f3689289 FINERACT-751 Fix CenterIntegrationTest Case 2019-05-28 17:25:46 +07:00
Angel Cajas 82568d93bf FINERACT-757: Use of sqlEncodeString function isn't needed as parameters are passed as an array of Objects and SqlInjection validation is done by Spring JdbcTemplate. 2019-05-27 23:00:41 -06:00
Vishwas Babu A J 7bf648aa96 Revert "Adding a compress response filter,registering filter"
This reverts commit eb5ad448fa.
2019-05-09 12:57:40 -07:00
Marti 2f22da0e6c FINERACT-706: Interoperation Mojaloop integration 1.0.1 2019-05-07 14:57:28 +02:00
Vishwas Babu A JandGitHub 57b73034a5 Merge pull request #564 from awasum/develop
FINERACT-751 Fix CenterIntegrationTest Case
2019-04-29 12:34:53 -07:00
Awasum Yannick bbb32f501f FINERACT-751 Fix CenterIntegrationTest Case 2019-04-26 13:35:45 +01:00
Mohit Sinha aab294f4a8 JdbcSupport added utility function for getting localDateTime after considering the timezone of the tenant. 2019-04-23 23:46:32 +07:00
Vishwas Babu A JandGitHub 67ba10fc2e Merge pull request #561 from apoorva-mk/FINERACT-748
#748 : Fixed typos in SPM API Java Files
2019-04-22 21:52:42 -07:00
Vishwas Babu A JandGitHub 22716d7353 Merge pull request #558 from bd2019us/FINERACT-747-PATCH
[FINERACT-747] change String.replaceAll() to replace() to improve performance
2019-04-18 10:56:53 -07:00
Apoorva b8d4afe2ff Fixed typos in SPM API Java Files 2019-04-17 22:52:21 +05:30
bd2019us f8c5de3e96 [FINERACT-747] change String.replaceAll() to replace() to improve performance 2019-04-13 19:52:58 -05:00
Vishwas Babu A JandGitHub 8af4943427 Merge pull request #553 from kangbreder/fix-tag
Placed break tag appropriately and removed blank spaces in create cl…
2019-04-10 14:24:46 -07:00
Mohit SinhaandMichael Vorburger ⛑️ 2ae916618b LocalDate check should be according to timezone of tenant. 2019-04-10 23:03:43 +02:00
Mohit SinhaandMichael Vorburger ⛑️ 3ee051cf57 Loan Disbursement validation - timezone of tenant 2019-04-10 15:13:12 +02:00
Kang Breder 746090cd49 Placed break tag appropriately and removed blank spaces in create client section, corrected grammatical errors and added punctuation to sentences. 2019-04-06 20:24:02 +01:00
Vishwas Babu A JandGitHub 80ae332aea Merge pull request #552 from muarachmann/FINERACT-738
Fixed broken link and closing tag
2019-03-28 15:17:25 -07:00
muarachmann b3320b7393 fixed broken link to section and closed tags appropriately 2019-03-25 02:48:45 +01:00
Vishwas Babu A JandGitHub 210e380df3 Merge pull request #551 from vishwasbabu/develop
FINERACT-718
2019-03-24 00:04:02 -07:00
Vishwas Babu A J b03e70fa9e FINERACT-718 2019-03-22 12:48:09 -07:00
Myrle KrantzandGitHub b70e540ec6 Remove requirement for single commit
Based on discussion here: 
 https://lists.apache.org/thread.html/0cd7baec95e7b2b937aeec8c39afd6eb78d36708cb848a26e7b397af@%3Cdev.fineract.apache.org%3E

Removed requirement for single commit contributions in order to make development process easier to understand and participate in.
2019-03-22 08:27:10 +01:00
Vishwas Babu A JandGitHub 201cbf82f6 Merge pull request #549 from hungnguyen2712/recommit-create-approve-loan-on-batch-mode
FINERACT-684
2019-03-14 15:23:22 -07:00
unknownandMichael Vorburger ⛑️ eb5ad448fa Adding a compress response filter,registering filter 2019-03-14 20:03:20 +01:00
Hung Nguyen b921e3e0c7 Fix issue FINERACT-684
Update Integration test
2019-03-14 14:45:08 +07:00
hungnguyen2712andGitHub 8dc8166876 Merge pull request #1 from apache/develop
sync from original repo
2019-03-14 10:58:17 +07:00
Michael Vorburger ⛑️andGitHub 2cb760f5e8 Use gradlew --console=plain, hoping to reduce output (FINERACT-732) (#548) 2019-03-12 13:58:40 +01:00
Michael Vorburger 977b74d6d1 remove gradle --info in .travis.yml (FINERACT-732) 2019-03-11 15:38:50 +01:00
Vishwas Babu A JandGitHub d6d5f4a96f Merge pull request #545 from awasum/develop
Prevent Apache rat task from failing subsequently after building project: FINERACT-731
2019-03-11 00:34:26 -07:00
Awasum Yannick 534ee9b7ab Prevent Apache rat task from failing subsequently after building project 2019-03-10 23:43:37 +01:00
Vishwas Babu A JandGitHub e0cb00315b Merge pull request #542 from vorburger/policy-governance-README
add new Governance and Policies section to Readme
2019-03-08 02:50:33 -08:00
Michael Vorburger 85de3db37d link to (new) "Pull Request Size Limit" page on Wiki
from the new Governance and Policies section in the README
2019-03-08 11:44:12 +01:00
Michael Vorburger ea49d9d17b link to (existing) Committer page on Wiki
from the new Governance and Policies section in the README
2019-03-08 11:25:44 +01:00
Vishwas Babu A JandGitHub 789db21462 Merge pull request #472 from pwairuru/bug_import_tool_repayments_download
Make repayments file download for bulk import tool
2019-03-07 22:45:06 -08:00
Michael Vorburger 002f969eef Revert "add new Governance and Policies section to Readme"
This reverts commit 20402e6d27.

I meant to raise that as Pull Request for discussion, not
force push it directly (just pressed the wrong button).
2019-03-08 03:33:01 +01:00
Michael Vorburger ⛑️andGitHub 20402e6d27 add new Governance and Policies section to Readme
With wording prohibiting PRs of thousands of lines.
2019-03-08 03:31:03 +01:00
Vishwas Babu A JandGitHub 68a1e87a51 Merge pull request #540 from vishwasbabu/develop
Update PULL_REQUEST_TEMPLATE.MD
2019-03-05 15:59:08 -08:00
Vishwas Babu A JandGitHub 592ee1930e Update PULL_REQUEST_TEMPLATE.MD
By adding link to guidelines for code reviews
2019-03-05 15:58:12 -08:00
Vishwas Babu A JandGitHub 0921e1e008 Merge pull request #539 from vishwasbabu/develop
FINERACT-719 and FINERACT-720
2019-03-05 15:05:43 -08:00
Vishwas Babu A J dd09003f5f FINERACT-720 updating test cases to reflect changes to Annual fees functionality 2019-03-05 15:04:55 -08:00
Vishwas Babu A J 655155ae54 FINERACT-719 2019-03-04 16:32:04 -08:00
Vishwas Babu A J 906fedfc6c FINERACT-720 2019-03-04 15:58:08 -08:00
Vishwas Babu A JandGitHub 2363f6767c Merge pull request #538 from vishwasbabu/develop
Fineract-719 and Fineract-707
2019-03-03 21:52:26 -08:00
Vishwas Babu A JandGitHub 1b9e23f695 Merge pull request #537 from vishwasbabu/develop
fineract-provider/src/integrationTest/java/org/apache/fineract/integr…
2019-03-02 13:17:10 -08:00
Vishwas Babu A JandGitHub 414893ca38 Merge pull request #536 from vishwasbabu/develop
FINERACT-717
2019-03-01 20:45:30 -08:00
Vishwas Babu A JandGitHub d4d5427522 Merge pull request #535 from vishwasbabu/develop
FINERACT-716
2019-03-01 11:22:01 -08:00
Vishwas Babu A J 576c8ccf9f FINERACT-716 2019-03-01 11:20:11 -08:00
Vishwas Babu A JandGitHub 17d8be9edb Merge pull request #534 from vishwasbabu/develop
FINERACT-710
2019-03-01 10:09:58 -08:00
Vishwas Babu A J 5103c38da9 FINERACT-710 2019-03-01 10:06:33 -08:00
Vishwas Babu A JandGitHub 117b46afe7 Merge pull request #533 from vishwasbabu/develop
FINERACT-708 , exclude .github from RAT checks
2019-03-01 00:29:50 -08:00
Vishwas Babu A J f437c2aba3 FINERACT-708 , exculde .github from RAT checks 2019-03-01 00:28:22 -08:00
Vishwas Babu A JandGitHub a2adc77ac3 Merge pull request #532 from vishwasbabu/develop
FINERACT-708
2019-03-01 00:01:18 -08:00
Vishwas Babu A J e22216e0cb FINERACT-708 2019-02-28 23:56:23 -08:00
Vishwas Babu A JandGitHub f11543693e Merge pull request #531 from vishwasbabu/develop
FINERACT-711
2019-02-28 23:53:49 -08:00
Vishwas Babu A JandGitHub dba938b076 Fixing typos in PULL_REQUEST_TEMPLATE 2019-02-28 23:53:40 -08:00
Vishwas Babu A JandGitHub 7888ef1f1c FINERACT-711 2019-02-28 23:49:43 -08:00
Vishwas Babu A J ab09ba8718 Fineract-707 2019-02-28 16:47:47 -08:00
Vishwas Babu A J 0258d22e63 FINERACT-719 Ignoring test cases over Excel imports of loans and savings 2019-02-28 15:58:24 -08:00
Vishwas Babu A J 8bfc1f63ab Bumping spring boot version 2019-02-28 15:52:07 -08:00
Vishwas Babu A J 4372bb53fa fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java 2019-02-28 13:14:46 -08:00
Vishwas Babu A J fd8121fe64 FINERACT-717 Lazy load child collections for Interest posting batch job 2019-02-27 20:36:28 -08:00
Vishwas Babu A JandGitHub fa05d5a30e Merge pull request #529 from apache/revert-526-create-and-approve-loan-on-batch-mode
Revert "FINERACT-684: Create and approve loan on batch mode "
2019-02-26 01:12:42 -08:00
Vishwas Babu A JandGitHub dd0771b24f Revert "FINERACT-684: Create and approve loan on batch mode " 2019-02-26 01:12:24 -08:00
Vishwas Babu A JandGitHub 5c782832b3 Merge pull request #516 from aasaru/develop
FINERACT-699 - new configuration parameters 'fromEmail' and 'fromName'
2019-02-26 01:03:14 -08:00
Vishwas Babu A JandGitHub 0534f371e7 Merge pull request #526 from hungnguyen2712/create-and-approve-loan-on-batch-mode
FINERACT-684: Create and approve loan on batch mode
2019-02-26 00:55:12 -08:00
Vishwas Babu A JandGitHub 6615613b20 Merge pull request #176 from emmanuelnnaa/FINERACT-52
commit for FINERACT-52 (Null value not handled in 'ClientWritePlatformServiceJpaRepositoryImpl.CloseClient' date comparison)
2019-02-26 00:27:48 -08:00
Vishwas Babu A JandGitHub 0a245701d8 Merge pull request #507 from ShruthiRajaram/Fineract-646
FINERACT-646 Pockets API
2019-02-26 00:12:30 -08:00
Vishwas Babu A JandGitHub 26d54592eb Merge pull request #528 from vishwasbabu/travis
Update Travis to run integration tests
2019-02-25 16:23:17 -08:00
Vishwas Babu A J 484f1d9430 Update Travis to run integration tests 2019-02-25 16:17:44 -08:00
ShruthiRajaram 3a67d01305 FINERACT-646 Pockets API 2019-02-25 11:00:22 +05:30
Vishwas Babu A JandGitHub 8b14bb88a7 Update README.md
clarifying the "About" and "Instructions to download gradle wrapper" sections and fixing typos
2019-02-22 14:17:56 -08:00
Hung Nguyen 39657247c6 - Fix issue FINERACT-684 (approve loan on batch mode return null pointer exception)
- Add integration test to cover the fix
2019-02-21 11:41:43 +07:00
Juhan Aasaru e6ab02e119 FINERACT-699 - fix failing build 2019-02-18 17:04:10 +02:00
Michael Vorburger fa41f0cc7a Merge branch 'naman-kapoor-patch-1' into develop
* naman-kapoor-patch-1:
  Update README.md
2019-02-16 00:21:05 +01:00
Michael Vorburger ⛑️andGitHub e340e34f60 Merge branch 'develop' into patch-1 2019-02-16 00:20:20 +01:00
Michael Vorburger e55b093cab remove 'clean' from .travis.yml 2019-02-14 00:11:37 +01:00
Michael Vorburger 42aaf54945 FINERACT-697: add Travis CI 'badge' to README 2019-02-13 23:52:14 +01:00
Michael Vorburger ⛑️andGitHub 20e4c8e527 FINERACT-697: add .travis.yml (and rm old un-used *build.sh) (#518) 2019-02-13 23:24:48 +01:00
Michael Vorburger 35a9b7b47e fix missing & bad license headers and config (req. for TravisCI FINERACT-697) 2019-02-13 22:36:17 +01:00
Juhan Aasaru 0800bb7522 FINERACT-699 - create new configuration parameters 'fromEmail' and 'fromName' and default their values to whatever 'username' is set to. 2019-02-11 15:42:52 +02:00
dingfanandMichael Vorburger ⛑️ 4784223a35 Initial contribution about Fineract project (#449)
* Update README to make first-time contributor easy to get started.

* Update the integration test part of README.
1. There is a lack of space of the command to access mysql db.
2. The name of mysql database should not contain "-", so I change "-" to "_" in order to avoid the syntax error.
2019-02-04 16:22:22 +01:00
ShruthiRajaramandGitHub 97ed2549de Merge pull request #457 from wkk91193/fixing-formular-cell-evaluation-npe
Fixing Apache POI issue - Formula Cell evaluation nullpointer exception
2019-02-04 16:27:56 +05:30
Steve ConradandGitHub cd5b3804a6 Merge pull request #511 from Anh3h/notification
Fix bug in generating notification.
2019-01-25 09:31:18 -06:00
ShruthiRajaramandGitHub 3c21ae1483 Merge pull request #508 from ShruthiRajaram/FINERACT-682
FINERACT-682: SQL injection impact fixes
2019-01-23 15:56:19 +05:30
Anh3h f63a8dea81 Fix bug in generating notification.
When querying the users required to get a notification, add new topic subscribers
to the current set of subscribers, instead of replacing the currents set of subscribers
with the new topic subscribers.
2019-01-21 12:21:24 -05:00
Myrle KrantzandGitHub 4fd584c87f Merge pull request #509 from wenance/fix_doc
Remove typo in doc
2019-01-11 17:21:03 +01:00
Mauricio 2c030edded remove typo un apiLive.htm 2019-01-11 11:47:37 -03:00
MauricioandGitHub dbb482f872 Merge pull request #1 from apache/develop
Update from upstream
2019-01-11 11:45:42 -03:00
ShruthiRajaram 40b24272ed FINERACT-682: SQL injection impact fixes 2019-01-10 12:17:31 +05:30
ShruthiRajaramandGitHub f6502b56a7 Merge pull request #506 from ShruthiRajaram/FINERACT--669
FINERACT-669 client transfer details
2019-01-02 11:40:19 +05:30
ShruthiRajaram 85fae55595 FINERACT-669 client transfer details 2019-01-02 11:33:22 +05:30
ShruthiRajaramandGitHub ed5c696103 Merge pull request #505 from apache/revert-501-FINERACT-669
Revert "FINERACT-669 back dated client transfer changes"
2018-12-31 17:35:54 +05:30
ShruthiRajaramandGitHub 5702ce878c Revert "FINERACT-669 back dated client transfer changes" 2018-12-31 17:34:58 +05:30
ShruthiRajaramandGitHub db389a03c5 Merge pull request #501 from ShruthiRajaram/FINERACT-669
FINERACT-669 back dated client transfer changes
2018-12-31 17:28:47 +05:30
ShruthiRajaramandGitHub bff995f008 Merge pull request #503 from ShruthiRajaram/FINERACT-680
FINERACT-680 market price update issue in share product
2018-12-31 17:19:07 +05:30
ShruthiRajaramandGitHub 80261d0f10 Merge pull request #470 from wkk91193/bulkimport-integration-loanrepayment-added-total-outstanding-amount-col
FINERACT:681 Added total outstanding amount to loan repayment workbook
2018-12-31 17:16:26 +05:30
ShruthiRajaramandGitHub 9324aafe31 Merge pull request #458 from wkk91193/performance-and-scalability-enhancements
FINERACT-637: Implementing Trial balance job
2018-12-28 12:58:07 +05:30
unknown eeb68c3dbd Renaming the script file 2018-12-27 15:53:55 +05:30
unknown bf1eee7c3c Removing collate,engine details and adding index to transaction_date column 2018-12-27 15:49:52 +05:30
unknown cdd0a12575 Implementing Trial balance job 2018-12-27 15:49:52 +05:30
ShruthiRajaramandGitHub 5eed2882c8 Merge pull request #500 from ShruthiRajaram/FINERACT-671
FINERACT-671 loan charge specific due date fix
2018-12-26 13:27:33 +05:30
ShruthiRajaram 3846ea6a25 FINERACT-186 batch job optimisation 2018-12-25 18:16:26 +05:30
ShruthiRajaram 73f1e71980 FINERACT-680 market price update issue in share product 2018-12-25 16:13:50 +05:30
ShruthiRajaram 356817762c FINERACT-669 back dated client transfer changes 2018-12-20 18:23:28 +05:30
ShruthiRajaram 37b61d156c FINERACT-671 loan charge specific due date fix 2018-12-19 18:38:25 +05:30
MexinaDandGitHub 9c24d6b41f Merge pull request #499 from ShruthiRajaram/FINERACT-536
FINERCAT-536 correcting report categories
2018-12-19 12:46:23 +03:00
ShruthiRajaram b3c36f1707 FINERCAT-536 correcting report categories 2018-12-19 14:34:06 +05:30
ShruthiRajaramandGitHub 525ac83268 Merge pull request #483 from ShruthiRajaram/sqlFix
sql fix
2018-12-18 15:01:18 +05:30
ShruthiRajaram 3105ec0439 sql fix 2018-12-18 14:56:20 +05:30
ShruthiRajaramandGitHub 22bf2cdde8 Merge pull request #498 from ShruthiRajaram/FINERACT-574
FINERACT-574 share account reject issues
2018-12-12 17:58:58 +05:30
ShruthiRajaramandGitHub b2257485a7 Merge pull request #496 from ShruthiRajaram/FINERACT-668
FINERACT-668 Download bulk import templates fix
2018-12-12 11:31:23 +05:30
MexinaDandGitHub 5e56d93101 Merge pull request #495 from ShruthiRajaram/FINERACT-665
FINERACT-665 activation date validation for group and center
2018-12-05 14:00:10 +03:00
Myrle KrantzandGitHub 749a730144 Merge pull request #497 from itzamnamx/patch-2
Update README.md
2018-12-05 11:48:37 +01:00
ShruthiRajaram 3bdfa5abe1 FINERACT-574 share account reject issues 2018-12-04 18:23:08 +05:30
ShruthiRajaramandGitHub 5db61a2e4d Merge pull request #441 from Nenge1/FINERACT-574
FINERACT-574
2018-12-04 17:37:39 +05:30
FinTECHeandoandGitHub b217c8388f Update README.md 2018-12-03 20:12:37 -06:00
ShruthiRajaramandGitHub c113ef4b89 Merge pull request #493 from m-sameer/FINERACT-632
FINERACT-632 Make description field non mandatory in saving product
2018-12-03 12:05:59 +05:30
Mohammad Sameer 1ec13dd0ef FINERACT-632 Make description field non mandatory in saving product 2018-11-30 19:01:26 +05:30
ShruthiRajaram ce87284f0a FINERACT-668 Download bulk import templates fix 2018-11-30 18:33:22 +05:30
ShruthiRajaram 6b38a121c3 FINERACT-665 activation date validation for group and center 2018-11-30 15:23:27 +05:30
ShruthiRajaramandGitHub 989e1f0402 Merge pull request #494 from m-sameer/FINERACT-618
FINERACT-618 Allow for Submitted On Date to be Edited for Groups
2018-11-30 12:43:44 +05:30
Mohammad Sameer a149185459 FINERACT-618 Allow for Submitted On Date to be Edited for Groups 2018-11-29 00:55:56 +05:30
ShruthiRajaramandGitHub f5a0146800 Merge pull request #479 from ShruthiRajaram/FINERACT-628-reports
FINERACT-628 self service user reports
2018-11-27 16:03:30 +05:30
ShruthiRajaram 11b6296352 FINERACT-628 self service user reports 2018-11-27 11:18:28 +05:30
ShruthiRajaramandGitHub cb83166153 Merge pull request #484 from ShruthiRajaram/FINERACT-628_Surveys
FINERACT-628 Self service APIs for Surveys
2018-11-26 18:38:15 +05:30
ShruthiRajaram be49522fb3 FINERACT-628 Self service APIs for Surveys 2018-11-26 18:33:47 +05:30
ShruthiRajaramandGitHub 26302b52ff Merge pull request #485 from ShruthiRajaram/FINERACT_628_Products
FINERACT-628 Products APIs
2018-11-26 18:07:55 +05:30
ShruthiRajaram ec3ae1449c FINERACT-628 Products APIs 2018-11-26 18:04:12 +05:30
MexinaDandGitHub 47e7f7e5c4 Merge pull request #455 from MexinaD/FINERACT-630
FINERACT-630 Allow decimal interest in a sheet to import loan
2018-11-22 12:39:16 +03:00
MexinaDandGitHub ccaec28d34 Merge pull request #436 from MexinaD/FINERACT-416
FINERACT-416 Interest of the whole term
2018-11-22 11:48:56 +03:00
ShruthiRajaramandGitHub d4abf17d47 Merge pull request #409 from Sanyam96/swagger-documentation-integration
GSOC'17:swagger and swagger UI integration on fineract-provider
2018-11-16 17:26:12 +05:30
Sanyam GoelandGitHub d68e49e540 Merge branch 'develop' into swagger-documentation-integration 2018-11-16 16:49:36 +05:30
ShruthiRajaramandGitHub 7956ce7108 Merge pull request #471 from ShruthiRajaram/FINERACT-627
FINERACT-627 back dated client transfer
2018-11-16 15:17:59 +05:30
ShruthiRajaram ec57197809 FINERACT-627 Back dated client transfer 2018-11-16 15:13:07 +05:30
Sanyam96 e46dc3230e removed .idea from .gitignore 2018-11-16 00:24:31 +05:30
ShruthiRajaramandGitHub b0fbc6e6bc Merge pull request #490 from ShruthiRajaram/FINERACT-662
FINERACT-662 activation date null check
2018-11-13 11:05:58 +05:30
ShruthiRajaramandGitHub e486e80406 Merge pull request #488 from ShruthiRajaram/FINERACT--656
FINERACT-656 and FINERACT-655 unable to import client via bulk import…
2018-11-13 11:00:32 +05:30
Sanyam96 f030262f58 updated response.json and removed iml file 2018-11-12 22:00:13 +05:30
ShruthiRajaramandGitHub 00b973fd97 Merge pull request #489 from ShruthiRajaram/FINERACT-659
FINERACT-659 Account Id issue while importing loan transaction
2018-11-12 14:57:58 +05:30
Sanyam96 a22297e3cb solve merge conflicts 2018-11-10 20:34:21 +05:30
ShruthiRajaram 0888d8bd36 FINERACT-662 activation date null check 2018-11-08 18:24:22 +05:30
ShruthiRajaram 15cb800609 FINERACT-659 Account Id issue while importing bulk loan transaction 2018-11-07 16:04:58 +05:30
ShruthiRajaramandGitHub 9b5c913a06 Merge pull request #478 from ShruthiRajaram/FINERACT-628-client-image
FINERACT-628 self service APIs for client image management
2018-11-05 17:16:24 +05:30
ShruthiRajaram 6ded9eb750 FINERACT-628 self service APIs for client image management 2018-11-05 16:59:01 +05:30
ShruthiRajaramandGitHub 99aa2b5bb2 Merge pull request #480 from ShruthiRajaram/FINERACT-628-Guarantors-Support
FINERACT-628 guarantor api for self service user
2018-11-05 16:27:20 +05:30
ShruthiRajaram 2a772b18eb FINERACT-656 and FINERACT-655 unable to import client via bulk import when address is enabled 2018-11-02 16:03:12 +05:30
Naman KapoorandGitHub 06d61f54a5 Update README.md 2018-10-27 12:43:17 +05:30
ShruthiRajaramandGitHub f811fa32bc Merge pull request #481 from wenance/develop
FINERACT-658 : Fix sql error
2018-10-25 16:47:53 +05:30
ShruthiRajaramandGitHub 836c0945b8 Merge pull request #475 from ShruthiRajaram/FINERACT-651
FINERACT-651 unable to delete client mobile number
2018-10-22 12:01:48 +05:30
ShruthiRajaramandGitHub 7f84f55a79 Merge pull request #467 from ShruthiRajaram/develop_FINERACT_638
FINERACT-628 Savings account APIs for Self Service App
2018-10-18 17:40:08 +05:30
drarko 77ffe267c4 fix sql error 2018-10-10 12:38:55 -03:00
ShruthiRajaram ab10eccb0e FINERACT-628 guarantor api for self service user 2018-10-10 17:12:28 +05:30
ShruthiRajaramandGitHub 7cef5edc25 Merge pull request #466 from ShruthiRajaram/develop_FINERACT_628.1
FINERACT:628 API support for self share accounts
2018-10-08 18:08:52 +05:30
ShruthiRajaramandGitHub f45dda47a0 Merge pull request #461 from ShruthiRajaram/develop_FINERACT_611
FINERACT-611 unable to create share product
2018-10-04 18:45:09 +05:30
ShruthiRajaramandGitHub a5168bfc0c Merge pull request #448 from conradsp/mysql-5.7
Migration to MySQL 5.7 - ensure all group by clauses are valid
2018-10-04 11:21:59 +05:30
Steve ConradandGitHub add8795025 Merge branch 'develop' into mysql-5.7 2018-10-03 10:59:26 -05:00
ShruthiRajaramandGitHub b5213c0bcd Merge pull request #477 from ShruthiRajaram/FINERACT_546
FINERACT-546 remove group from center
2018-10-03 18:26:56 +05:30
ShruthiRajaramandGitHub b71ed1cb6a Merge pull request #454 from MexinaD/FINERACT-623
FINERACT-623 - Restriction of product mix fix
2018-09-26 11:41:47 +05:30
ShruthiRajaram a569fefb40 FINERACT-546 remove group from center 2018-09-24 17:24:31 +05:30
ShruthiRajaramandGitHub b608444a9d Merge pull request #476 from apache/revert-474-fineract-546
Revert "FINERACT-546 disassociate group from center"
2018-09-24 16:54:42 +05:30
ShruthiRajaramandGitHub 308766600f Revert "FINERACT-546 disassociate group from center" 2018-09-24 16:53:03 +05:30
ShruthiRajaramandGitHub 8cc7d5e39c Merge pull request #474 from ShruthiRajaram/fineract-546
FINERACT-546 disassociate group from center
2018-09-24 16:52:42 +05:30
ShruthiRajaram 7e8e3ced19 FINERACT-651 unable to delete client mobile number 2018-09-11 13:47:37 +05:30
ShruthiRajaram 7887612937 FINERACT-546 disassociate group from center 2018-09-07 19:07:20 +05:30
Mexina M Daniel e8ad0736ba FINERACT-623 - Restrict of product mix fix 2018-08-28 16:05:47 +03:00
Mexina M Daniel 54470db56e Merge branch 'MexinaD-Loan-greater-than-expected' into develop 2018-08-24 07:53:41 +03:00
Mexina M Daniel bc52819529 Merge branch 'FINERACT-431' of https://github.com/MexinaD/incubator-fineract into MexinaD-Loan-greater-than-expected 2018-08-24 07:52:47 +03:00
conradsp 9398afda4d Merge branch 'tonic889-community-app-1863' into develop 2018-08-21 15:45:27 -05:00
conradsp 9642e0e383 Merge branch 'community-app-1863' of https://github.com/tonic889/incubator-fineract into tonic889-community-app-1863 2018-08-21 15:24:06 -05:00
conradsp e29e37ebbc Merge branch 'conradsp-fix-integration-tests' into develop 2018-08-21 15:18:47 -05:00
conradsp 693c7f2c9c Fixes for integration tests 2018-08-21 14:47:04 -05:00
unknown 7a77cfd193 Fixing loan summary null pointer 2018-08-21 22:41:54 +05:30
unknown d3eed8d57d Added total outstanding amount to loan repayment workbook 2018-08-19 18:17:51 +05:30
wairuru bccdd1a416 Make repayments file download for bulk import tool 2018-08-15 19:16:25 +03:00
tonic889 fbf9d1e7d0 FINERACT-642 Include Guarantor Accounts in Client Accounts Overview 2018-08-06 22:54:31 -04:00
ShruthiRajaram 2d6a19a998 FINERACT:628 API support for self share accounts 2018-07-31 19:01:04 +05:30
ShruthiRajaram 424bd0884e FINERACT-628 Savings account APIs for Self Service App 2018-07-17 17:05:55 +05:30
ShruthiRajaram 683c767e3f FINERACT-611 unable to create share product 2018-07-13 18:07:29 +05:30
unknown 650e1ddd8b Fixing Apache POI issue - Formula Cell evaluation nullpointer exception 2018-06-15 23:13:38 +05:30
Mexina M Daniel 2e5aaf72de FINERACT-630 Allow decimal interest in a sheet to import loan 2018-06-13 12:34:53 +03:00
conradsp 2a3aaecf6a Merge branch 'FINERACT-613' into develop 2018-06-11 14:04:00 -05:00
conradsp 7832e66958 FIx for ClientSummary stretchy report 2018-06-09 16:25:33 -05:00
conradsp 0918ba8346 Update for scheduled_email_campaigns 2018-05-23 14:07:58 -05:00
Madhukar a847b81792 FINERACT-613:500 Internal Server Errors on Data Tables 2018-04-11 10:44:34 +05:30
conradsp dfabdcc71e Fixes for stretchy reports to ensure compatibility with MySQL 5.7 2018-03-29 15:23:22 -05:00
Sanyam GoelandGitHub 8817e7fa81 Gci swagger integration (#33)
* Swagger Documentation of StandingInstructionApiResource.java

* Swagger Documentation of StandingInstructionHistoryApiResource.java

* Swagger Documentation for ChargesApiResource.java

* Swagger Documentation of EntityFieldConfigurationApiResources.java and LoanChargesApiResource.java

* Swagger Documentation for CollateralsApiResource.java and InterestRateChartsApiResource.java (#5)

* Swagger Documentation for InterestRateChartSlabsApiResource.java (#8)

* Swagger Documentation for FundsApiResource.java (#9)

* Swagger Documentation for LoansApiResource.java (#10)

* Swagger Documentation for TaxGroupApiResource.java (#12)

* Swagger Documentation for FixedDepositAccountsApiResource.java (#13)

* Swagger Documentation for FixedDepositAccountsApiResource.java

* Added Example Request in GET Endpoint {accountId}

Added Example Request in GET Endpoint in "fixeddepositaccounts/{accountId}"

* Swagger Documentation for AccountTransfersApiResource.java (#14)

* Swagger Documentation for CollectionSheetApiResource.java and FloatingRatesApiResource.java (#15)

* Swagger Documentation for CentersApiResource.java (#16)

* Swagger documentation for GroupsApiResource.java (#11)

* Swagger Documentation for SelfBeneficiariesTPTApiResource.java and SelfAuthenticationApiResource.java (#21)

* Swagger Documentation for SelfClientsApiResource.java (#20)

* Swagger Documentation for AccountsApiResource.java (#19)

* Swagger Documentation for SelfUserApiResource.java, TaxComponentApiResource.java & SelfUserDetailsApiResource.java (#18)

* Swagger Documentation for FixedDepositProductsApiResource.java (#22)

* Swagger Documentation for SelfSavingsApiResource.java (#23)

* Swagger Documentation for RecurringDepositAccountsApiResource.java (#24)

* Swagger Documentation for SelfLoansApiResource.java (#17)

* Swagger Documentation for SelfLoansApiResource.java
* Added documentation for POST endpoint

* Swagger Documentation for SavingsAccountsApiResource.java (#26)

* Swagger Documentation for RecurringDepositAccountTransactionsApiResource.java (#29)

* Swagger Documentation for LoanProductsApiResource.java and NotesApiResource,java (#25)

* Swagger Documentation for RecurringDepositProductsApiResource.java & SavingAccountChargesApiResource.java (#27)

* Swagger Documenatation for LoanScheduleApiResource.java & LoanTransactionsApiResource.java (#28)

* Swagger Documentation for PaymentTypeApiResource.java and ProductsApiResource.java (#31)

* Swagger Documentation for SavingsProductsApiResource.java (#30)

* Swagger Documentation for Clients API (#32)

* Swagger Documentation for Clients API

* Changed the file name

* Fixed minor bugs/errors

* Requested Changes

* Some more changes
2018-03-18 01:43:21 +05:30
conradsp 9688f38ed3 Migration to MySQL 5.7 - ensure all group by clauses are valid 2018-03-07 13:04:42 -06:00
Avik Ganguly d2b341159c Merge branch 'injection' into develop 2018-03-05 06:38:31 +05:30
Avik Ganguly 8c60476bd1 CVE-2018-1290-1291-1292 2018-03-05 06:14:10 +05:30
conradsp f28aadf312 For a triggered SMS message, check if notification flag is set. If so, send to GCM service. 2018-02-16 08:27:05 -06:00
conradsp e2ae145a11 For a triggered SMS message, check if notification flag is set. If so, send to GCM service. 2018-02-16 08:26:25 -06:00
Vishwas Babu A J e3ce5f3ae0 handling null pointer exception and updating integration tests for changes made as a part of FINERACT-590 2018-02-09 18:02:56 -08:00
Nenge 613b802c0d FINERACT-574 2018-02-08 15:05:39 +03:00
Terence Denzil Monteiro 8ac5485544 Merge branch 'i601-create-cashier-teller-end-date' into develop 2018-02-06 21:45:03 +05:30
Terence Denzil Monteiro e13616b0e9 Only compare Teller and Cashier endDate if its not null 2018-02-06 20:42:32 +05:30
conradsp 8e7bd01ed4 FINERACT-590 2018-02-03 14:29:02 -06:00
Vishwas Babu A J 1d38bd25d0 fixes for CVE-2018-1289 2018-02-02 15:36:07 -08:00
Avik Ganguly e7035d1f39 Injection fix 2018-01-20 10:00:51 +05:30
Mexina M Daniel dc43072362 FINERACT-431 - Loan term greater than expected 2018-01-03 12:00:50 +03:00
Mexina M Daniel 5235b7ebc9 FINERACT-416 Interest of the whole term 2017-12-29 15:37:19 +03:00
Nazeer Hussain Shaik 17fd243ae3 Resolving 3 integration tests related to bulk import and remoing some sysouts and correcting 322.2 migration script 2017-12-15 13:16:00 +05:30
Avik Ganguly 95ff9ab3c0 Close #424 2017-12-13 19:37:33 +05:30
Avik Ganguly bd5225b747 Close #405 2017-12-13 19:37:14 +05:30
Avik Ganguly b3c94ebca2 Close #135 2017-12-13 19:32:31 +05:30
Anh3handAvik Ganguly 0b0212966c Add Spring Events to be used when activemq is not available 2017-12-13 18:04:36 +05:30
Anh3handAvik Ganguly 7395d6c543 Notification sub-system 2017-12-13 18:04:36 +05:30
Avik Ganguly 58184a5219 Removing unnecessary constructors 2017-12-13 18:04:36 +05:30
Myrle Krantz 06932137b5 Close #380 2017-12-13 11:32:01 +01:00
Myrle Krantz 3c69754f25 Close #116 2017-12-13 11:12:48 +01:00
Avik Ganguly 1c0af3ba2f Close #256 2017-12-13 15:01:19 +05:30
Avik Ganguly 07a465c6e4 Close #401 2017-12-13 14:36:14 +05:30
Avik Ganguly 98f5612ac5 Merge DIT branch 2017-12-13 14:31:55 +05:30
Avik Ganguly bc129440fd Missing licenses 2017-12-13 13:35:54 +05:30
Avik Ganguly 4c3028657a Merge branch 'extend-mifos-data-import-tool-branch-all-modules' of https://github.com/wkk91193/incubator-fineract into dit 2017-12-13 12:16:13 +05:30
Nazeer Hussain Shaik bf894732da Renaming sql migration scripts 2017-12-11 15:56:37 +05:30
Nazeer Hussain Shaik 4e97776e62 Merge branch 'PR432' into develop 2017-12-11 15:30:14 +05:30
Nazeer Hussain Shaik 504f679c8f Correcting V322_1 migration script 2017-12-11 15:14:30 +05:30
Nazeer Hussain Shaik a9a29e51c1 Changing device regration API to return id instead of entity 2017-12-11 13:16:11 +05:30
unknown 210647d415 all modules populate & import 2017-12-06 18:32:51 +05:30
Nazeer Hussain Shaik 84927eb5b6 TemplateMergeServiceTest.compileLoanSummary always fails on windows environment 2017-12-05 11:56:49 +05:30
Nazeer Hussain Shaik b756fb70b1 License Header is added in V322_1 and V322_2 migration scripts 2017-12-05 11:36:07 +05:30
Nazeer Hussain Shaik 7368b1f047 FINERACT-241 Include Add Note to Deposit and Withdrawal screen in savings account 2017-12-05 10:24:19 +05:30
Nazeer Hussain Shaik cef41855a2 FINERACT-571 Unable to transfer clients from one group to another group even though both groups are under same center and office 2017-12-04 10:46:13 +05:30
Nazeer Hussain Shaik a42f9d5268 SSU device regration API is falinging 2017-12-01 14:34:10 +05:30
Sanyam96 a13887bd06 Solving Merge Conflicts Before Google CodeIn'17 2017-11-27 21:00:18 +05:30
Nazeer Hussain Shaik c689c143e4 Changing the migration script numberand resolving a compilation issue 2017-11-27 17:40:14 +05:30
Nazeer Hussain Shaik 1a50128757 Merge branch 'TwoFactor' into develop 2017-11-27 15:04:28 +05:30
Nazeer Hussain Shaik 4dbecc7f0e Resolving compilation issues with Email Campaigns Feature and resolving 322.2 migration script issue 2017-11-21 18:51:18 +05:30
Nazeer Hussain Shaik 2614ffdb29 Merge branch 'PR428' into develop 2017-11-20 19:02:57 +05:30
Nazeer Hussain Shaik a4c0a6826f Merge branch 'PR399' into develop 2017-11-20 16:13:30 +05:30
Nazeer Hussain Shaik e5dbd4acfc Merge branch 'FINERACT-554' into develop 2017-11-20 16:07:12 +05:30
Nazeer Hussain Shaik a3e8c5e5b7 Merge branch 'PR426' into develop 2017-11-20 16:05:01 +05:30
Nazeer Hussain Shaik 6b113cc188 Merge branch 'FINERACT-491' into develop 2017-11-20 16:01:35 +05:30
Nazeer Hussain Shaik a5a88dc916 Merge branch 'PR422' into develop 2017-11-20 16:00:14 +05:30
Nazeer Hussain Shaik e23ff94dde Merge branch 'PR421' into develop 2017-11-20 15:58:35 +05:30
Nazeer Hussain Shaik fdac5fa6e3 Merge branch 'FINERACT-467' into develop 2017-11-20 15:56:19 +05:30
Nazeer Hussain Shaik b2aeb81be1 Merge branch 'Fineract-521' into develop 2017-11-20 15:54:39 +05:30
Avik Ganguly 585a791b4e Close #341 2017-11-16 07:09:56 +05:30
Avik Ganguly 0eda746fb4 Close #315 2017-11-16 07:09:29 +05:30
Avik Ganguly 82df77cd8a Close #282 2017-11-16 07:09:06 +05:30
Avik Ganguly 4605d237ce Close #273 2017-11-16 07:08:37 +05:30
Avik Ganguly e29463b023 Close #272 2017-11-16 07:08:13 +05:30
Avik Ganguly e595529af9 Close #257 2017-11-16 07:08:10 +05:30
Avik Ganguly b5d15e4679 Close #227 2017-11-16 07:07:07 +05:30
Avik Ganguly c855b90648 Close #208 2017-11-16 07:06:54 +05:30
Avik Ganguly 60c4632ed8 Close #175 2017-11-16 07:05:30 +05:30
Avik Ganguly c1c5b8aaac Close #172 2017-11-16 07:05:25 +05:30
Avik Ganguly 29402a3a0d Close #170 2017-11-16 07:05:23 +05:30
Avik Ganguly a92f36961b Close #161 2017-11-16 07:04:49 +05:30
Avik Ganguly f7316e45e6 Close #124 2017-11-16 07:04:43 +05:30
Avik Ganguly 2140fd8d1c Close #93 2017-11-16 07:03:02 +05:30
Avik Ganguly c58b067965 Close #67 2017-11-16 07:02:42 +05:30
Avik Ganguly 8371c791c0 Close #65 2017-11-16 07:02:34 +05:30
Avik Ganguly 2d111f21c2 Close #60 2017-11-16 07:02:27 +05:30
avikganguly01 ac49b4c09e Close #40 2017-11-16 06:49:49 +05:30
Ippez RobertandGitHub c338c1758e Email Campaigns PR 2017-11-14 15:53:34 +03:00
nazeer shaik db59e8cd7a Survey bug fix 529, 530 2017-11-14 14:56:38 +05:30
nikpawar89 f1e6716f76 FINERACT-554 2017-11-11 00:57:51 -06:00
nazeer shaik 630c942fa3 FINERACT-491 :fiscal month compounding 2017-11-07 18:12:07 +05:30
nazeer shaik 7eea2dc302 failing integration test case fixed 2017-11-03 18:48:52 +05:30
nazeer shaik 8f30c2102f notification sms 2017-11-02 16:24:28 +05:30
nazeer shaik 2e00bff557 FINERACT-467 : equal amortization 2017-10-31 19:10:14 +05:30
Konstantin Golub 749ec055e9 SQL injection validator fix 2017-10-17 08:23:18 -03:00
Sanyam96 741607a305 Merging Develop: Merge Conflict Solved 2017-10-11 17:43:05 +05:30
Konstantin Golub 87e0c59fb3 Conditional ad hoc job service 2017-10-05 11:28:18 -03:00
Konstantin Golub f47e0fb2fb Optional e-mauk field of the AdHoc page 2017-10-04 20:59:27 -03:00
Konstantin Golub 5cfea884ce ReportRunFrequncy parameter was added 2017-10-04 17:22:26 -03:00
avikganguly01 81b2ba1c31 Fineract-521 Undo Transaction 2017-09-22 22:17:34 +05:30
Nazeer Hussain Shaik d6accae348 Issue in survey creation 2017-09-22 19:34:25 +05:30
Alex Ivanov 1a966e8e73 Two-Factor Authentication
Technical Spec: https://mifosforge.jira.com/wiki/spaces/projects/pages/185277689/GSoC+2017+-+Two-Factor+Authentication
2017-09-22 14:24:52 +01:00
Nazeer Hussain Shaik b56cc43543 Merge branch 'Fineract-521' into develop 2017-09-22 13:55:10 +05:30
Nazeer Hussain Shaik fcb5ba30c3 Merge branch 'FINERACT-494' into develop 2017-09-22 13:51:20 +05:30
Nazeer Hussain Shaik d857d8b47a survey enhancement 2017-09-22 12:37:17 +05:30
avikganguly01 e81d810b24 Fineract-521 2017-09-19 18:39:48 +05:30
Nazeer Hussain Shaik 61e6214fa6 FINERACT-494 Issue when selecting savings account on client creation page 2017-09-13 19:49:45 +05:30
Sanyam96 b5d9429926 GSOC'17:swagger and swagger UI integration on fineract-provider 2017-08-27 23:22:52 +05:30
Nazeer Hussain Shaik df16dc3cad Self user role and report access 2017-08-21 17:42:19 +05:30
Nazeer Hussain Shaik 6e95f88d7b Merge branch 'PR398' into develop 2017-08-21 16:55:19 +05:30
Nazeer Hussain Shaik 3e1705a477 Removing autoincrement values from 15 in V334__notification_module_tables.sql 2017-08-21 16:17:52 +05:30
Adhyan c60c6601c0 Added Notification Module
Added Notification Module

Added Notification Module

Added Notification Module

Added license file for jar analyzer

Added entry into LICENSE_RELEASE file

Added gradle wrapper
2017-08-20 21:21:24 +05:30
nikpawar89 b8d61412e0 validation fixed 2017-08-03 18:47:48 +05:30
nikpawar89 6ed747130a family members migration fix 2017-08-03 14:07:59 +05:30
Nazeer Hussain Shaik 455ef98276 Chaing migration script file extention from txt to sql 2017-08-02 18:33:42 +05:30
Nazeer Hussain Shaik b831fa5203 Merge branch 'PR378' into develop 2017-08-02 18:28:26 +05:30
nikpawar89 d4672f9beb family members 2017-08-02 14:19:42 +05:30
Kasem 2e259b1583 Adhoc Query 2017-07-29 18:05:46 +06:00
nazeer shaik afdc665b52 self service registration 2017-07-25 20:22:10 +05:30
Nazeer Hussain Shaik 0f98cbbed8 Merge branch 'PR393' into develop 2017-07-24 17:24:27 +05:30
nazeer shaik 39d1f74cca holiday bug fix 2017-07-24 16:22:48 +05:30
Nazeer Hussain Shaik 1b4147409a Merge branch 'PR392' into develop 2017-07-24 12:48:46 +05:30
Nazeer Hussain Shaik c3a602ced8 Merge branch 'FINERACT-37' into develop 2017-07-20 18:50:02 +05:30
ShruthiRajaram fa5cae625b FINERACT-482 : allow blocking credits when debits are blocked and vice-versa 2017-07-20 18:49:35 +05:30
Nazeer Hussain Shaik 0373ce4672 FINERACT-499 2017-07-20 18:44:47 +05:30
nazeer shaik b9017e2be2 holiday changes for next repayment date 2017-07-20 17:10:11 +05:30
Nazeer Hussain Shaik a41bd8a84d FINERACT-498 2017-07-20 15:16:35 +05:30
Nazeer Hussain Shaik ee21ab8c5b FINERACT-439 2017-07-18 12:42:22 +05:30
Nazeer Hussain Shaik 12f80f4adb Merge branch 'FINERACT-482' into develop 2017-07-13 19:34:07 +05:30
Nazeer Hussain Shaik 5b808fecc1 Merge branch 'FINERACT-475' into develop 2017-07-13 16:05:42 +05:30
Nazeer Hussain Shaik 1ef276be54 Merge branch 'FINERACT-470' into develop 2017-07-13 15:02:33 +05:30
ShruthiRajaram 7368c3f11a FINERACT-482 block account changes 2017-07-12 17:59:18 +05:30
nazeer shaik 77b0625a5d 475 tranche waive charge 2017-07-05 16:21:44 +05:30
ThisuraThejith e590ed61c4 resolved the rest of the issues related to FINERACT-470 2017-07-05 06:45:06 +05:30
Nazeer Hussain Shaik 6946f1c3fd Merge branch 'PR375' into develop 2017-07-02 11:23:13 +05:30
ThisuraThejith cfd52da659 Added general specific exceptions to accept errorCodes and exceptions 2017-06-29 18:22:49 +05:30
Nazeer Hussain Shaik ee150b1a44 Changing migration script number V329__savings_account_transaction_releaseId V330__savings_account_transaction_releaseId 2017-06-28 15:46:40 +05:30
Nazeer Hussain Shaik 6711a145a1 Merge branch 'PR373' into develop 2017-06-28 15:39:22 +05:30
Nazeer Hussain Shaik 781689c8de Merge branch 'PR372' into develop 2017-06-28 15:33:24 +05:30
Nazeer Hussain Shaik 037440916a Changing 329 migration script file name to follow existing convension 2017-06-28 15:16:06 +05:30
Nazeer Hussain Shaik 0594cd5163 Merge branch 'PR366' into develop 2017-06-28 14:38:40 +05:30
ShruthiRajaram fe3741c2ce block account/amount/credit/debit 2017-06-21 13:21:36 +05:30
nazeer shaik aec7f9fa6c reschedule bulk loan 149 and 481 2017-06-20 14:58:40 +05:30
Alex Ivanov dfc168d3d7 Allow predefined SMS messages and Emails to be sent via existing SMS/Email implementations
Allow SMS messages without SMS campaign to be saved
2017-06-19 20:42:27 +01:00
Nazeer Hussain Shaik 18e85856fc Merge branch 'PR367' into develop 2017-06-16 20:24:16 +05:30
Nazeer Hussain Shaik 0cd1e39655 Merge branch 'FINERACT-470' into develop 2017-06-16 20:10:54 +05:30
nazeer shaik 17ff4b54c5 self saving account path param changes 2017-06-14 19:08:40 +05:30
nazeer shaik 03b564f116 324 , 325 2017-06-13 14:47:29 +05:30
ThisuraThejith d0fa56dd00 Resolving merge conflicts 2017-06-13 06:20:34 +05:30
Nazeer Hussain Shaik cbfdfa001a Merge branch 'PR363' into develop 2017-06-09 16:09:57 +05:30
nazeer shaik f537bae699 saving for collection sheet and 347,251,360 2017-06-09 15:38:41 +05:30
Nazeer Hussain Shaik 06c959ebb6 Merge branch 'PR356' into develop 2017-06-09 15:27:39 +05:30
nikpawar89 34de03e045 formatted creditbureau configuration 2017-06-09 14:36:53 +05:30
Nazeer Hussain Shaik 5473e37133 Merge branch 'PR355' into develop 2017-06-09 10:53:33 +05:30
Nazeer Hussain Shaik cfd02e9189 Adding license text in 404.css 2017-06-08 14:38:28 +05:30
ThisuraThejith 50048151a8 Completed the sonar fixes in FINERATC-436 2017-06-08 13:27:45 +05:30
Nazeer Hussain Shaik 6777645117 Merge branch 'PR358' into develop 2017-06-06 14:14:28 +05:30
Nazeer Hussain Shaik 35ec9d877e Merge branch 'FINRACT-456' into develop 2017-06-06 12:02:28 +05:30
Nazeer Hussain Shaik 4ee30b6d55 Merge branch 'PR332' into develop 2017-06-06 11:39:44 +05:30
nazeer shaik 3ddde49564 439, 454, 473, 476 edit data table, bulk jlg,modify application 2017-06-02 11:02:59 +05:30
nazeer1100126 e5f1e9093d collection sheet 2017-05-23 16:34:35 +05:30
Nazeer Hussain Shaik 20db9d4373 Removing Disclaimer file and updating the release version 2017-05-19 06:39:19 +05:30
Raj Metgiri af9fecb72c FINRACT-456 Javadoc generation possible now 2017-05-18 18:52:23 +02:00
Nazeer Hussain Shaik 3f0d653d3a Fixing Connection abandoned with Column Validator 2017-05-18 16:10:11 +05:30
Nazeer Hussain Shaik 0d7cf3a284 FINERACT-158 FINERACT-166 Fix 2017-05-18 11:21:41 +05:30
Nazeer Hussain Shaik 582ef5de6c Fixing Regression issues of loan and savings creation 2017-05-17 13:40:16 +05:30
Nazeer Hussain Shaik ce0ff78a44 Fixing Integration failure in Provisioning module due to recent query params sanitization changes 2017-05-16 16:01:10 +05:30
Nazeer Hussain Shaik d93885b555 Merge branch 'PR353' into develop 2017-05-16 12:53:47 +05:30
Nazeer Hussain Shaik cf9af2ec3a Merge branch 'FINERACT-453' into develop 2017-05-16 11:14:37 +05:30
Nazeer Hussain Shaik fc1bb3b4a2 License format issue with ColumnValidator 2017-05-16 11:12:04 +05:30
Nazeer Hussain Shaik 4f63b051de Merge branch 'SQLINJ' into develop 2017-05-16 10:55:20 +05:30
nazeer1100126 d70618d7d1 bugs fixed 458,310,453,158,166 2017-05-15 20:59:18 +05:30
nazeer1100126 bc91489fc1 loan integration test case fixes 453 2017-05-10 18:11:20 +05:30
nazeer1100126 b7a5e67b9e sql injections fixes 2017-05-08 18:03:47 +05:30
Nazeer Hussain Shaik a8ac5555c9 Merge branch 'FINERACT-436' into develop 2017-05-08 11:59:18 +05:30
Nazeer Hussain Shaik 0c658956b9 Merge branch 'FINERACT-205' into develop 2017-05-05 18:35:09 +05:30
nazeer1100126 2efae80c1d license for file 326 data migration 2017-05-05 18:28:50 +05:30
Nazeer Hussain Shaik 5c9729af3c Merge branch 'bulk_jlg' into develop 2017-05-05 17:52:09 +05:30
Nazeer Hussain Shaik 00e785860d Merge branch 'FINERACT-359' into develop 2017-05-05 17:34:01 +05:30
Nazeer Hussain Shaik da567018cc Merge branch 'FINERACT-417' into develop 2017-05-05 17:30:16 +05:30
Nazeer Hussain Shaik cb28f2a018 Merge branch 'FINERACT-261' into develop 2017-05-05 17:21:48 +05:30
Nazeer Hussain Shaik 516160bf41 Merge branch 'FINERACT-317' into develop 2017-05-05 17:19:12 +05:30
Nazeer Hussain Shaik 75f51a1619 Merge branch 'FINERACT-423' into develop 2017-05-05 17:16:01 +05:30
Nazeer Hussain Shaik f85239b1a8 Merge branch 'FINERACT-389' into develop 2017-05-05 17:13:13 +05:30
Nazeer Hussain Shaik 7add0a8982 Merge branch 'Fineract-297' into develop 2017-05-05 16:15:48 +05:30
Nazeer Hussain Shaik 29777ddfbd Merge branch 'FINERACT-249' into develop 2017-05-05 16:08:08 +05:30
nazeer1100126 6c60d84a85 issue 205 for jlg change of disbursement date at time of disbursement 2017-05-03 16:26:59 +05:30
nazeer1100126 7e3b04ccd1 bulk jlg loan bug fixes 2017-05-03 14:33:42 +05:30
ThisuraThejith c72d2e02cd Fixing Fixed CWE582,CWE607 issues in account and infrastructure modules 2017-04-30 00:26:49 +05:30
nazeer1100126 716f09eaf0 #359 daily repayment schedule fix 2017-04-24 16:27:23 +05:30
nazeer1100126 3c44d92991 417 flat interest free period 2017-04-21 18:16:53 +05:30
nazeer1100126 94a4bf570a #261 validation added on disabling gl account 2017-04-21 15:26:19 +05:30
nazeer1100126 b059bb6206 #317 flat installment amount for fixed installment amount 2017-04-21 13:03:25 +05:30
nazeer1100126 755d4d2f92 teller cashier issues #334 #432 #433 #434 #435 2017-04-20 19:26:49 +05:30
unknown 187faf5153 FIX FINERACT-423: Compilation fails due to missing licence header in some files 2017-04-19 11:26:56 +02:00
Sanyam96 9b2912f676 refactored 404.html file and created 404.css file 2017-04-15 21:07:14 +05:30
ThisuraThejith 1b43802142 ordere by gl_code added to sql query in retrieveAllGLAccounts 2017-04-11 00:02:02 +05:30
nazeer1100126 bc1d3b41f3 FINERACT-249 : PortfolioProductType.SAVING and PortfolioProductType.CLIENT have the same value 2017-03-31 15:14:28 +05:30
ThisuraThejith 1df40f7b44 Fixed issues in removin all mapping fees,penalties to income acounts 2017-03-29 07:39:31 +05:30
nazeer1100126 8baf9f4cd0 FINERACT-78 : Specified due date percentage charge calculation uses loan principal amount instead of installment principal amount 2017-03-28 13:52:20 +05:30
nazeer1100126 254d259705 FINERACT-360 : Individual Collection Sheet is not considering Installment Fee during payment 2017-03-27 15:36:42 +05:30
nazeer1100126 f59dacbfc8 FINERACT-303 - % Loan Amount + Interest or %Amount if collected as disbursement fees it is not working as expected 2017-03-24 17:20:40 +05:30
nazeer1100126 935d6146c0 FINERACT-270 : Unable to waive all Loan charges 2017-03-23 18:45:00 +05:30
Nazeer Hussain Shaik 14a1216d0c Merge branch 'FINERACT-418' into develop 2017-03-22 11:57:33 +05:30
Nazeer Hussain Shaik 1873db6451 Merge branch 'FINERACT-321' into develop 2017-03-22 11:46:26 +05:30
Nazeer Hussain Shaik e444aca44e Merge branch 'FINERACT-330' into develop 2017-03-22 11:43:25 +05:30
Nazeer Hussain Shaik 7f9591ce96 Merge branch 'FINERACT-243' into develop 2017-03-22 11:40:13 +05:30
Lionel Raymundi - Poincenot a7b27d6d36 FINERACT-418 penalties should be applied until the day before running job 2017-03-19 23:11:29 -03:00
nazeer1100126 5f74453606 FINERACT-321 - Manual Journal entries should not allowed to reverse after accounting closure is done for that branch 2017-03-17 17:49:05 +05:30
nazeer1100126 d6e7013410 FINERACT-330 : No error message is getting displayed in productive collection sheet if meeting is not attached to center/group 2017-03-17 15:53:39 +05:30
nazeer1100126 770b33cf69 FINERACT-243 : Constitution Type Required Field 2017-03-15 16:29:06 +05:30
nazeer1100126 e47f4dde8b FINERACT-345 : Should not allow to add guarantor, If savings account transaction date is greter that loan application submitted date 2017-03-14 19:25:20 +05:30
Nazeer Hussain Shaik 8cc560cd84 Merge branch 'FINERACT-326' into develop 2017-03-13 17:36:21 +05:30
Nazeer Hussain Shaik fdcd2d4476 Merge branch 'FINERACT-344' into develop 2017-03-13 17:35:01 +05:30
Nazeer Hussain Shaik 2f4ff30c91 Merge branch 'FINERACT-331' into develop 2017-03-13 17:33:39 +05:30
Nazeer Hussain Shaik a8f386811e Merge branch 'FINERACT-378' into develop 2017-03-13 17:31:12 +05:30
Nazeer Hussain Shaik b5c130736c Merge branch 'FINERACT-117' into develop 2017-03-13 17:29:04 +05:30
Nazeer Hussain Shaik 121df4eb08 Merge branch 'FINERACT-115' into develop 2017-03-13 17:27:36 +05:30
Nazeer Hussain Shaik f159e59c15 Merge branch 'FINERACT-89' into develop 2017-03-13 17:25:44 +05:30
nazeer1100126 fb1a890940 FINERACT-344 : Should not allow to add guarantor ,If savings account activation date is gretar than loan application submitted date 2017-03-13 13:33:13 +05:30
nazeer1100126 f04b3719c3 FINERACT-326 : Edit datatable page not able to save if the single character is entered in New Name field 2017-03-10 18:28:08 +05:30
nazeer1100126 f6b0e280e0 FINERACT-331 : In edit client if the Legal Form is modified from entity to person not getting updated as person after submission 2017-03-10 17:41:32 +05:30
nazeer1100126 0296fd4351 FINERACT-378 and 379 : Can not link a Saving account to during Group Loan Application and Bluck JLG Loan application 2017-03-10 13:45:54 +05:30
nazeer1100126 d32aeabe66 FINERACT-117 : Tranche disbursement charge % disbursed amount is displaying as -ve amount if the 2nd tranche disbursed is with lesser amount and charge was waived before 2nd disbursement 2017-03-09 15:25:58 +05:30
nazeer1100126 df93ce64db FINERACT-115 : In Loan tranche details page if any tranche is added, Tranche disbursement charge is getting added twice 2017-03-08 18:23:01 +05:30
nazeer1100126 069c8ada56 FINERACT-89 : 1st tranche will appear twice in repayment schedule when disbursement date and first repayment date is on same date 2017-03-07 19:45:29 +05:30
Nazeer Hussain Shaik f1f3d65161 Merge branch 'FINERACT-228' into develop 2017-03-07 13:52:25 +05:30
Nazeer Hussain Shaik 34b988195c Merge branch 'FINERACT-412' into develop 2017-03-07 13:48:44 +05:30
Nazeer Hussain Shaik 8c080fc75d Merge branch 'FINERACT-406' into develop 2017-03-07 13:03:05 +05:30
Nazeer Hussain Shaik cdbcf75010 Merge branch 'FINERACT-365' into develop 2017-03-07 12:18:50 +05:30
Nazeer Hussain Shaik c49956c151 Fixing FixedDeposit integration test failure 2017-03-07 12:14:37 +05:30
Ippez Robert 5a258bde90 FINERACT-228 2017-03-04 10:45:17 +03:00
Ippez Robert 9b8d253217 FINERACT-412 - Add Share account in Global Search 2017-03-03 13:13:31 +03:00
Lionel Raymundi - Poincenot c197614af6 FINERACT-406 allow disbursal of topup loan on same date of transaction of previous loan 2017-02-24 18:49:02 -03:00
satish-conflux 652059c246 FINERACT-365 : The 'Transactions' tab showing wrong balance in RD account 2017-02-24 15:51:56 +05:30
Nazeer Hussain Shaik c1af6d6685 FINERACT-399-Barebones and Sampledata sql files are broken 2017-02-24 14:24:57 +05:30
Nazeer Hussain Shaik 8c5cf0667f FINERACT-402-Integrate PMD and Findbugs with Fineract 2017-02-23 15:09:25 +05:30
Nazeer Hussain Shaik 3125946c2e FINERACT-374-Add Gradle wrapper download location in readme file 2017-02-23 11:25:43 +05:30
myrle-krantz 90a49c37f0 Merge branch 'nazeer1100126-FINERACT-371' into develop 2017-02-22 13:53:00 +01:00
myrle-krantz fe0f20b732 gradlew executable on linux 2017-02-22 13:51:46 +01:00
myrle-krantz 9db39391ab Merge branch 'FINERACT-371' of https://github.com/nazeer1100126/incubator-fineract into nazeer1100126-FINERACT-371 2017-02-22 13:47:43 +01:00
Nazeer Hussain Shaik b36ba8e0f1 Merge branch 'FINERACT-366' into develop 2017-02-21 14:35:33 +05:30
satish-conflux 8e9674b4aa FINERACT-366 : Issue With Creating RD account with 'Charge Time Type' Savings Activation 2017-02-20 13:25:55 +05:30
Nazeer Hussain Shaik 9387b3efd5 Merge branch 'FINERACT-377' into develop 2017-02-17 17:25:31 +05:30
satish-conflux 5d1a32e6f8 FINERACT-377 : Reinvesting Recurring Deposit is taking present date in stead of maturity date 2017-02-17 17:22:56 +05:30
Nazeer Hussain Shaik c7905e945b Merge branch 'FINERACT-312' into develop 2017-02-17 16:36:49 +05:30
Nazeer Hussain Shaik ffa7bd71df Merge branch 'FINERACT-234' into develop 2017-02-17 15:17:34 +05:30
Nazeer Hussain Shaik 1dabd44b45 FINERACT-371 - Make gradle callable from the top level directory. 2017-02-16 19:38:08 +05:30
satish-conflux 7ceb68fec9 FINERACT-312 : For Loan with interest recalculation periodic accrual with respect to current date is not getting modified after repayment in Transaction page 2017-02-15 18:22:09 +05:30
Nazeer Hussain Shaik dc3bf98c44 FINERACT-234 - Can't process bulk JLG loan application [MIFOSX-2137] 2017-02-08 19:19:02 +05:30
Nazeer Hussain Shaik c6da909d61 FINERACT-311 - Issue With 'Payment Due On Non Working Days 2017-02-07 15:09:49 +05:30
Nazeer Hussain Shaik b6f4230777 Merge branch 'FINERACT-221' into develop 2017-01-31 16:16:59 +05:30
Nazeer Hussain Shaik e92b6b1712 FINERACT-221-After submitting the modify application the currency is not getting updated as per the new product 2017-01-23 18:48:28 +05:30
Nazeer Hussain Shaik e1a0e3f1ea FINERACT-126 - Not able to Submit the loan application if multi tranche is added and the Expected disbursement on field is left blank displays internal server error 2017-01-23 16:30:09 +05:30
Nazeer Hussain Shaik d8a0a07429 Merge branch 'FINERACT-364' into develop 2017-01-20 13:51:18 +05:30
Nazeer Hussain Shaik 3c2128ffb4 Merge branch 'FINERACT-380' into develop 2017-01-20 13:46:57 +05:30
Nazeer Hussain Shaik e397b807e0 Merge branch 'FINERACT-16' into develop 2017-01-20 13:40:57 +05:30
Nazeer Hussain Shaik 77f9d5cb95 FINERACT-5 Interest re-calculation setup for loan product but repayment doesn't occur 2017-01-19 16:57:37 +05:30
Nazeer Hussain Shaik b4156ed1ef FINERACT-380 S3 permission issue -- add system property 2017-01-19 16:00:34 +05:30
Nazeer Hussain Shaik 633cfc7c24 FINERACT-16-Cannot close Savings Account when linked to a loan even when loan status is closed 2017-01-18 14:15:41 +05:30
Nazeer Hussain Shaik 0173c8d05f FINERACT-364 2017-01-17 17:38:01 +05:30
Nazeer Hussain Shaik 80fada22aa Merge branch 'FINERACT-352' into develop 2017-01-13 14:20:39 +05:30
Nazeer Hussain Shaik 749266d408 Merge branch 'Fineract-265' into develop 2017-01-13 14:18:01 +05:30
lionel 392dff0cd1 FINERACT-352 fix showing penalties after last loan's installment 2017-01-12 11:11:50 -03:00
Nazeer Hussain Shaik 4fb7794a45 Renaming LICENSE.md to APACHE_LICENSETEXT.md 2017-01-06 22:45:41 +05:30
Nazeer Hussain Shaik ba33af36af Making License & Notice with 80Col and updating build.gradle to copy disclaimer 2017-01-06 21:19:23 +05:30
Nazeer Hussain Shaik c577680757 Sperating source and binary licenses 2017-01-06 19:42:19 +05:30
Nazeer Hussain Shaik 71b6ca8856 Merge branch 'PR267' into develop 2017-01-03 20:13:05 +05:30
Nazeer Hussain Shaik 7a734ebd59 Fixing integration tests for staff creation with joiningDate as mandatory 2017-01-03 20:10:07 +05:30
nikpawar89 b8d8c452cc addressModuleFix 2017-01-02 17:54:47 -05:00
Nazeer Hussain Shaik 7b0fcc5674 Merge branch 'Fineract-361' into develop 2017-01-02 17:57:52 +05:30
Adi Narayana Raju 5fe0e529e7 [Fineract-361] Partial periods not to be considered for PMT calculations 2017-01-02 16:10:30 +05:30
Adi Narayana Raju f55a16755f [Fineract-309] query result list assigned as a modifiable list 2017-01-02 12:43:10 +05:30
Nazeer Hussain Shaik 9a6b5d1c12 Adding instructions to run RAT check 2016-12-30 17:09:52 +05:30
Nazeer Hussain Shaik e139238a04 Adding License text for jQuery v1.7,v1.7.1 2016-12-30 14:23:27 +05:30
Ilya Andreev 1e437b9cc1 Remove unnecessary checking for missing joined date. 2016-12-29 20:46:08 +02:00
Nazeer Hussain Shaik 7f2b2f676e SMS Campaign Integration tests depends upon message-gateway. So adding @ignore not to run 2016-12-29 12:54:02 +05:30
Nazeer Hussain Shaik c4fcc7e424 Merge branch 'PR266' into develop 2016-12-29 10:46:22 +05:30
Tan Gemicioglu ac7195a488 Relocated charge recalculation in loan approval. 2016-12-26 16:27:14 +03:00
Emmanuel Nnaa d8f14a662a commit for FINERACT-52 (Null value not handled in 'ClientWritePlatformServiceJpaRepositoryImpl.CloseClient' date comparison) 2016-07-18 12:52:16 +02:00
venkatconflux 67317b18b7 FINERACT-186 2016-06-21 20:25:22 +05:30
1205 changed files with 90263 additions and 5165 deletions
+19
View File
@@ -0,0 +1,19 @@
# 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.
#
build/*
.gradle/*
+19
View File
@@ -0,0 +1,19 @@
## Description
Describe the changes made and why they were made. Ignore if these details are present on the associated Jira ticket
## Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
- [ ] Commit message starts with the issue number from https://issues.apache.org/jira/projects/FINERACT/. Ex: FINERACT-646 Pockets API.
- [ ] Coding conventions at https://cwiki.apache.org/confluence/display/FINERACT/Coding+Conventions have been followed.
- [ ] API documentation at https://github.com/apache/fineract/blob/develop/api-docs/apiLive.htm has been updated with details of any API changes.
- [ ] Integration tests have been created/updated for verifying the changes made.
- [ ] All Integrations tests are passing with the new commits.
- [ ] Submission is not a "code dump". (Large changes can be made "in repository" via a branch. Ask on the list.)
Our guidelines for code reviews is at https://cwiki.apache.org/confluence/display/FINERACT/Code+Review+Guide
+8
View File
@@ -2,3 +2,11 @@
*.jar
*.war
*.ear
.gradle
build
*.iml
*.ipr
*.iws
*.DS_Store
.idea
gradle
+57
View File
@@ -0,0 +1,57 @@
# 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.
#
# https://issues.apache.org/jira/browse/FINERACT-763
dist: trusty
language: java
jdk:
- openjdk8
services:
- mysql
# Hardcoding system time as a temporary fix for running buggy test cases
before_install:
- echo "USE mysql;\nUPDATE user SET password=PASSWORD('mysql') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root
- mysql -u root -pmysql -e 'CREATE DATABASE IF NOT EXISTS `mifosplatform-tenants`;'
- mysql -u root -pmysql -e 'CREATE DATABASE IF NOT EXISTS `mifostenant-default`;'
- export TZ=Asia/Kolkata
- sudo service ntp stop
- sudo date --set="23 February 2019 01:02:03"
# https://docs.travis-ci.com/user/languages/java/#caching
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.m2
# NOTE: We used to run with --info, which is quite a bit more verbose, but is VERY useful to understand failures on Travis,
# where you do not have access to any files like build/reports/tests/index.html, only the Console.
# @see http://mrhaki.blogspot.ch/2013/05/gradle-goodness-show-more-information.html
# @see http://forums.gradle.org/gradle/topics/whats_new_in_gradle_1_1_test_logging for alternative
# https://jira.apache.org/jira/browse/FINERACT-732 removed that again, because it made Travis CI fail.
script:
- date
- ./gradlew --console=plain licenseMain licenseTest licenseIntegrationTest test
- ./gradlew --console=plain clean integrationTest
-1
View File
@@ -1 +0,0 @@
Apache Fineract is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.
+39
View File
@@ -0,0 +1,39 @@
# 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.
#
FROM bitnami/tomcat:7.0.94 as fineract
USER root
RUN apt-get update -qq && apt-get install -y git openjdk-8-jdk wget
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
RUN mkdir fineract
COPY . fineract
WORKDIR fineract
RUN sed -i 's/localhost/fineractmysql/' ./fineract-provider/build.gradle
RUN sed -i 's/localhost/fineractmysql/' ./fineract-provider/src/main/resources/sql/migrations/list_db/V1__mifos-platform-shared-tenants.sql
RUN ./gradlew clean war
RUN mv build/libs/fineract-provider.war /opt/bitnami/tomcat/webapps
RUN keytool -genkey -keyalg RSA -alias tomcat -keystore /opt/bitnami/tomcat/tomcat.keystore -keypass xyz123 -storepass xyz123 -noprompt -dname "CN=Fineract, OU=Fineract, O=Fineract, L=Unknown, ST=Unknown, C=Unknown"
COPY ./docker/server.xml /opt/bitnami/tomcat/conf
RUN chmod 664 /opt/bitnami/tomcat/conf/server.xml
WORKDIR /opt/bitnami/tomcat/lib
RUN wget http://central.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/1.4/drizzle-jdbc-1.4.jar
+46 -79
View File
@@ -208,73 +208,16 @@
======================================
All the source code for the Apache Fineract project is released under the
license above. Additionally, the Apache Fineract source and binary distribution includes a number of third-party files that are required in
license above. Additionally, the Apache Fineract source and binary
distribution includes a number of third-party files that are required in
order to the software to function. Unless noted below, these jars
and resource files are also released under the ASF license above.
==================================================
*The exceptions for source release are as follows:
==================================================
For API & System Architecture Documentation Apache Fineract includes following css and js packages.
This product bundles normalize v1.1.1 and v2.1.0, copyright Nicolas Gallagher and Jonathan Neal, which is available under a MIT license.
For details, see licenses/source/normalize.MIT
This product bundles Modernizr v2.6.2, which is available under a MIT license.
For details, see licenses/source/modernizr.MIT
This product bundles filesaver, copyright Eli Grey, which is available under a MIT license.
For details, see licenses/source/filesaver.MIT
This product bundles Glyphicons Halflings Regular, copyright Jan Kovarik,
which is available under a MIT license.
For details, see licenses/source/glyphicons.MIT
This product bundles jszip, copyright Stuart Knightley,
David Duponchel, Franz Buchinger and António Afonso, which is available under a MIT license.
For details, see licenses/source/jszip.MIT
This product bundles jQuery v1.7, v1.7.1, v1.9.1, v1.10.2, copyright jQuery Foundation, Inc. which is available under a MIT license.
For details, see licenses/source/jQuery.MIT
This product bundles Respond v1.1.0, copyright Scott Jehl,
which is available under a MIT license.
For details, see licenses/source/respond.MIT
This product bundles matchMedia polyfill, copyright Scott Jehl,
which is available under a MIT license.
For details, see licenses/polyfill.MIT
This product bundles HTML5Shiv v3.6.2pre, copyright Alexander Farkas,
which is available under a MIT license.
For details, see licenses/source/html5shiv.MIT
This product bundles UglifyJS copyright Mihai Bazon,
which available under a BSD license.
For details, see licenses/source/uglify.BSD
This product bundles sizzle copyright jQuery Foundation and other contributors, which is available under a MIT license.
For details, see licenses/source/sizzle.MIT
This product bundles some parts of es5-shim, copyright Kristopher Michael Kowal and contributors, which is available under a MIT license.
For details, see licenses/source/es5shim.MIT
This product bundles toc v0.1.2, copyright Greg Allen,
which is available under a MIT license.
For details, see licenses/source/toc.MIT
This product bundles livejs Version 4, copyright Martin Kool and Q42,
which is available under a MIT license.
For details, see licenses/source/livejs.MIT
This product bundles HTML5 Boilerplate, which is under a MIT license.
For details, see licenses/source/h5bp.MIT.
==================================================
*The exceptions for binary release are as follows:
==================================================
This product bundles AOP Alliance v1.0, which is available under a Public Domain license. For details, see licenses/binary/Aopa.PL
This product bundles AOP Alliance v1.0, which is available under a
Public Domain license. For details, see licenses/binary/Aopa.PL
This product bundles ASM Core v3.1, which is available under a BSD license.
For details, see licenses/binary/Asm.BSD
@@ -283,58 +226,82 @@ This product bundles JavaMail API(compat) v1.5.0-b01,
which is available under a CDDL v1.0 license.
For details, see licenses/binary/Javamail.CDDL
This product bundles AspectJ Runtime v1.8.2, Copyright (c) 1999-2001 Xerox Corporation, 2002 Palo Alto Research Center, Incorporated (PARC), which is available under a EPL v1.0 license.
This product bundles AspectJ Runtime v1.8.2, Copyright (c) 1999-2001
Xerox Corporation, 2002 Palo Alto Research Center, Incorporated (PARC),
which is available under a EPL v1.0 license.
For details, see licenses/binary/Aspectrt.EPL
This product bundles AspectJ Weaver v1.8.2, Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC), which is available under a EPL v1.0 license. For details, see licenses/binary/Aspectweaver.EPL
This product bundles AspectJ Weaver v1.8.2, Copyright (c) 2002 Palo Alto
Research Center, Incorporated (PARC), which is available under a EPL v1.0
license. For details, see licenses/binary/Aspectweaver.EPL
This product bundles IText(A Free Java PDF Library) v2.1.7, Copyright 2007 Bruno Lowagie, which is available under a MPL v1.1 license.
This product bundles IText(A Free Java PDF Library) v2.1.7, Copyright 2007
Bruno Lowagie, which is available under a MPL v1.1 license.
For details, see licenses/binary/IText.MPL
This product bundles DOM4J, Copyright 2001-2005 (C) MetaStuff, Ltd., which is available under a BSD license.
This product bundles DOM4J, Copyright 2001-2005 (C) MetaStuff, Ltd.,
which is available under a BSD license.
For details, see licenses/binary/Dom4J.BSD
This product bundles JDBC driver for MySQL and Drizzle v1.3, Copyright (c) 2009-2013, Marcus Eriksson which is available under a BSD license.
This product bundles JDBC driver for MySQL and Drizzle v1.3, Copyright (c)
2009-2013, Marcus Eriksson which is available under a BSD license.
For details, see licenses/binary/Drizzle.BSD
This product bundles Ical4J v1.0.4, Copyright (c) 2012, Ben Fortuna,
which is available under a BSD license.
For details, see licenses/binary/Ical4J.BSD
This product bundles Jersey Core v1.17, Copyright (c) 2010-2012 Oracle and/or its affiliates, which is available under a CDDL 1.1 license.
This product bundles Jersey Core v1.17, Copyright (c) 2010-2012 Oracle
and/or its affiliates, which is available under a CDDL 1.1 license.
For details, see licenses/binary/Jersey.CDDL
This product bundles Jersey Json v1.17, Copyright (c) 2010-2012 Oracle and/or its affiliates, which is available under a CDDL 1.1 license.
This product bundles Jersey Json v1.17, Copyright (c) 2010-2012 Oracle
and/or its affiliates, which is available under a CDDL 1.1 license.
For details, see licenses/binary/Jersey.CDDL
This product bundles Jersey Multipart v1.17, Copyright (c) 2010-2011 Oracle and/or its affiliates, which is available under a CDDL 1.1 license.
This product bundles Jersey Multipart v1.17, Copyright (c) 2010-2011 Oracle
and/or its affiliates, which is available under a CDDL 1.1 license.
For details, see licenses/binary/Jersey.CDDL
This product bundles Jersey Server v1.17, Copyright (c) 2010-2011 Oracle and/or its affiliates, which is available under a CDDL 1.1 license.
This product bundles Jersey Server v1.17, Copyright (c) 2010-2011 Oracle
and/or its affiliates, which is available under a CDDL 1.1 license.
For details, see licenses/binary/Jersey.CDDL
This product bundles Jersey Servlet v1.17, Copyright (c) 2010-2011 Oracle and/or its affiliates, which is available under a CDDL 1.1 license.
This product bundles Jersey Servlet v1.17, Copyright (c) 2010-2011 Oracle
and/or its affiliates, which is available under a CDDL 1.1 license.
For details, see licenses/binary/Jersey.CDDL
This product bundles Jersey Spring v1.17, Copyright (c) 2010-2011 Oracle and/or its affiliates, which is available under a CDDL 1.1 license.
This product bundles Jersey Spring v1.17, Copyright (c) 2010-2011 Oracle
and/or its affiliates, which is available under a CDDL 1.1 license.
For details, see licenses/binary/Jersey.CDDL
This product bundles Logback Classic Module v1.1.2, Copyright (C) 1999-2012, QOS.ch. All rights reserved, which is available under a EPL v1.0 license.
This product bundles Logback Classic Module v1.1.2, Copyright (C) 1999-2012,
QOS.ch. All rights reserved, which is available under a EPL v1.0 license.
For details, see licenses/binary/Logback.EPL
This product bundles Logback Core Module v1.1.2, Copyright (C) 1999-2012, QOS.ch. All rights reserved, which is available under a EPL v1.0 license.
This product bundles Logback Core Module v1.1.2, Copyright (C) 1999-2012,
QOS.ch. All rights reserved, which is available under a EPL v1.0 license.
For details, see licenses/binary/Logback.EPL
This product bundles MIME Streaming Extension v1.6, Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved., which is available under a CDDL v1.1 license.
This product bundles MIME Streaming Extension v1.6, Copyright (c) 1997-2010
Oracle and/or its affiliates. All rights reserved., which is available under
a CDDL v1.1 license.
For details, see licenses/binary/Mimepull.CDDL
This product bundles JUnit v3.8.1 created by Erich Gamma and Kent Beck which is available under a CPL v1.0 license.
This product bundles JUnit v3.8.1 created by Erich Gamma and Kent Beck which
is available under a CPL v1.0 license.
For details, see licenses/binary/Junit.CPL
This product bundles SLF4J API Module v1.7.7 opyright (c) 2004-2013 QOS.ch All rights reserved., which is available under a MIT license.
This product bundles SLF4J API Module v1.7.7 opyright (c) 2004-2013 QOS.ch
All rights reserved., which is available under a MIT license.
For details, see licenses/binary/Slf4j.MIT
This product bundles Backport Util Concurrent v3.1 written by Dawid Kurzyniec,
which is avilable under Public Domain license. For details see licenses/binary/Backport.PL
which is avilable under Public Domain license.
For details see licenses/binary/Backport.PL
******************************************
This product bundles JarAnalyzer v1.2 written by Kirk Knoernschild,
which is available under BSD license.
For details see licences/binary/JarAnalyzer.BSD
******************************************
+286
View File
@@ -0,0 +1,286 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.
******************************************
======================================
LICENSES FOR INCLUDED DEPENDENCIES
======================================
All the source code for the Apache Fineract project is released under the
license above. Additionally, the Apache Fineract source and binary
distribution includes a number of third-party files that are required in
order to the software to function. Unless noted below, these jars
and resource files are also released under the ASF license above.
==================================================
*The exceptions for source release are as follows:
==================================================
For API & System Architecture Documentation Apache Fineract includes
following css and js packages.
This product bundles normalize v1.1.1 and v2.1.0, copyright Nicolas
Gallagher and Jonathan Neal, which is available under a MIT license.
For details, see licenses/source/normalize.MIT
This product bundles Modernizr v2.6.2, which is available under a MIT license.
For details, see licenses/source/modernizr.MIT
This product bundles filesaver, copyright Eli Grey, which is available under
a MIT license.
For details, see licenses/source/filesaver.MIT
This product bundles Glyphicons Halflings Regular, copyright Jan Kovarik,
which is available under a MIT license.
For details, see licenses/source/glyphicons.MIT
This product bundles jszip, copyright Stuart Knightley,
David Duponchel, Franz Buchinger and António Afonso, which is available
under a MIT license.
For details, see licenses/source/jszip.MIT
This product bundles jQuery v1.7, v1.7.1, Copyright (c) 2011 John Resig,
which is available under a MIT license.
For details, see licenses/source/jQuery1.MIT
This product bundles jQuery v1.9.1, v1.10.2, copyright jQuery Foundation,
Inc. which is available under a MIT license.
For details, see licenses/source/jQuery.MIT
This product bundles Respond v1.1.0, copyright Scott Jehl,
which is available under a MIT license.
For details, see licenses/source/respond.MIT
This product bundles matchMedia polyfill, copyright Scott Jehl,
which is available under a MIT license.
For details, see licenses/polyfill.MIT
This product bundles HTML5Shiv v3.6.2, copyright Alexander Farkas,
which is available under a MIT license.
For details, see licenses/source/html5shiv.MIT
This product bundles UglifyJS copyright Mihai Bazon,
which available under a BSD license.
For details, see licenses/source/uglify.BSD
This product bundles sizzle copyright jQuery Foundation and other
contributors, which is available under a MIT license.
For details, see licenses/source/sizzle.MIT
This product bundles some parts of es5-shim, copyright Kristopher Michael
Kowal and contributors, which is available under a MIT license.
For details, see licenses/source/es5shim.MIT
This product bundles toc v0.1.2, copyright Greg Allen,
which is available under a MIT license.
For details, see licenses/source/toc.MIT
This product bundles livejs Version 4, copyright Martin Kool and Q42,
which is available under a MIT license.
For details, see licenses/source/livejs.MIT
This product bundles HTML5 Boilerplate, which is under a MIT license.
For details, see licenses/source/h5bp.MIT.
******************************************
+29 -12
View File
@@ -12,35 +12,52 @@ Fineract elects to include this software in this distribution under the
CDDL license. You can obtain a copy of the License at:
https://glassfish.java.net/public/CDDL+GPL.html
Apache Fineract includes all Jersey libraries (Jersey Core v1.17, Jersey Json v1.17, Jersey Multipart v1.17, Jersey Server v1.17,Jersey Servlet v1.17,
Jersey Spring v1.17). Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved. Fineract elects to include this software in this distribution under the CDDL license. You can obtain a copy of the License at:
Apache Fineract includes all Jersey libraries (Jersey Core v1.17,
Jersey Json v1.17, Jersey Multipart v1.17, Jersey Server v1.17,
Jersey Servlet v1.17, Jersey Spring v1.17).
Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
Fineract elects to include this software in this distribution under the
CDDL license. You can obtain a copy of the License at:
https://glassfish.java.net/public/CDDL+GPL.html
Apache Fineract includes Logback Classic Module v1.1.2 and Logback Core Module v1.1.2, Copyright (C) 1999-2012, QOS.ch. All rights reserved. Fineract elects to include this software in this distribution under the
EPL license. You can obtain a copy of the License at:
Apache Fineract includes Logback Classic Module v1.1.2 and Logback Core
Module v1.1.2, Copyright (C) 1999-2012, QOS.ch.
All rights reserved. Fineract elects to include this software in this
distribution under the EPL license. You can obtain a copy of the License at:
http://www.eclipse.org/legal/epl-v10.html
Apache Fineract includes MIME Streaming Extension v1.6, CCopyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
Fineract elects to include this software in this distribution under the
CDDL license. You can obtain a copy of the License at:
Apache Fineract includes MIME Streaming Extension v1.6,
Copyright (c) 1997-2010 Oracle and/or its affiliates.
All rights reserved. Fineract elects to include this software in this
distribution under the CDDL license. You can obtain a copy of the License at:
https://glassfish.java.net/public/CDDL+GPL_1_1.html
Apache Fineract includes JUnit v3.8.1 created by Erich Gamma and Kent Beck.
Apache Fineract includes JUnit v3.8.1 created by Erich Gamma and Kent Beck.
Fineract elects to include this software in this distribution under the
CPL license. You can obtain a copy of the License at:
https://opensource.org/licenses/cpl1.0.txt
Apache Fineract includes Log4j Implemented Over SLF4J. Fineract elects to include this software in this distribution under the Apache license. You can obtain a copy of the License at:
Apache Fineract includes Log4j Implemented Over SLF4J. Fineract elects to
include this software in this distribution under the Apache license.
You can obtain a copy of the License at:
http://apache.org/licenses/LICENSE-2.0
Apache Fineract includes Jackson Core v2.3.4, Jackson Annotations v2.3.0,
Jackson Databind v2.3.4, JAX RS Provider For JSON Content Type v1.9.2, Xml Compatibility Extensions For Jackson v1.9.2 libraries. Fineract elects to include this software in this distribution under the Apache license. You can obtain a copy of the License at:
Jackson Databind v2.3.4, JAX RS Provider For JSON Content Type v1.9.2,
Xml Compatibility Extensions For Jackson v1.9.2 libraries.
Fineract elects to include this software in this distribution under the
Apache license. You can obtain a copy of the License at:
http://apache.org/licenses/LICENSE-2.0
Apache Fineract includes AspectJ Runtime v1.8.2, Copyright (c) 1999-2001 Xerox Corporation, 2002 Palo Alto Research Center, Incorporated (PARC) and AspectJ Weaver v1.8.2 Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC)., libraries. The library information is available at
Apache Fineract includes AspectJ Runtime v1.8.2, Copyright (c) 1999-2001
Xerox Corporation, 2002 Palo Alto Research Center, Incorporated (PARC) and
AspectJ Weaver v1.8.2 Copyright (c) 2002 Palo Alto Research Center,
Incorporated (PARC)., libraries. The library information is available at
(https://eclipse.org/aspectj/)
Apache Fineract includes IText(A Free Java PDF Library) v2.1.7 library, Copyright 2007 Bruno Lowagie. The library information is available at (http://developers.itextpdf.com/itext-java)
Apache Fineract includes IText(A Free Java PDF Library) v2.1.7 library,
Copyright 2007 Bruno Lowagie. The library information is available at
(http://developers.itextpdf.com/itext-java)
=====================
Apache OpenJPA NOTICE
+5
View File
@@ -0,0 +1,5 @@
Apache Fineract
Copyright 2008-2016 The Apache Software Foundation
This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).
+86 -21
View File
@@ -1,59 +1,115 @@
Apache Fineract: A Platform for Microfinance
Apache Fineract: A Platform for Microfinance [![Build Status](https://travis-ci.org/apache/fineract.svg?branch=develop)](https://travis-ci.org/apache/fineract)
============
The next evolution of Apache Fineract focuses on being faster, lighter and cheaper to change (than the existing Mifos) so that it is more responsive to the needs of Microfinance Institutions and Integrators.
Fineract is a mature platform with open APIs that provides a reliable, robust, and affordable core banking solution for financial institutions offering services to the world’s 2 billion underbanked and unbanked.
Requirements
============
* Java >= 1.8 (Oracle JVMS have been tested)
* gradle-wrapper.jar version 2.10
* Java >= 1.8 (Oracle JVMs have been tested)
* MySQL 5.5
Instructions to build war file
============
You can run the required version of the database server in a container, instead of having to install it, like this:
docker run --name mysql-5.5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysql -d mysql:5.5
and stop and destroy it like this:
docker rm -f mysql-5.5
Beware that this database container database keeps its state inside the container and not on the host filesystem. It is lost when you destroy (rm) this container. This is typically fine for development. See [Caveats: Where to Store Data on the database container documentation](https://hub.docker.com/_/mysql) re. how to make it persistant instead of ephemeral.
Instructions to download gradle wrapper
============
The file fineract-provider/gradle/wrapper/gradle-wrapper.jar binary is checked into this projects's Git source repository,
but won't exist in your copy of the Fineract codebase if you downloaded a released source archive from apache.org.
In that case, you need to downloaded it using the commands below:
wget --no-check-certificate -P fineract-provider/gradle/wrapper https://github.com/apache/fineract/raw/develop/fineract-provider/gradle/wrapper/gradle-wrapper.jar
(or)
curl --insecure -L https://github.com/apache/fineract/raw/develop/fineract-provider/gradle/wrapper/gradle-wrapper.jar > fineract-provider/gradle/wrapper/gradle-wrapper.jar
Instructions to run Apache RAT (Release Audit Tool)
============
1. Extract the archive file to your local directory.
2. Download gradle-wrapper.jar version 2.10 and place it in the fineract-provider/gradle/wrapper folder.
3. Change the current working directory to fineract-provider.
4. Run `./gradlew clean war` or `./gradlew build` to build deployable war file which will be created at fineract-provider/build/libs directory.
2. Run `./gradlew rat`. A report will be generated under build/reports/rat/rat-report.txt
Instructions to build a war file
============
1. Extract the archive file to your local directory.
2. Run `./gradlew clean war` or `./gradlew build` to build deployable war file which will be created at build/libs directory.
Instructions to execute Integration tests
============
1. Login to mysql DB using `mysql -u root -pmysql`
2. Create the mifosplatform-tenants database using `CREATE DATABASE mifosplatform-tenants`.
3. Create the default tenant database using `CREATE DATABASE mifostenant-default`.
4. With fineract-provider as current working directory run the following commands:
1. `./gradlew migrateTenantListDB -PdbName=mifosplatform-tenants`
2. `./gradlew migrateTenantDB -PdbName=mifostenant-default`
5. Run `./gradlew clean integrationTest`
> Note that if this is the first time to access MySQL DB, then you may need to reset your password.
Run the following commands, very similarly to how [.travis.yml](.travis.yml) does:
1. `./gradlew createDB -PdbName=mifosplatform-tenants`
1. `./gradlew createDB -PdbName=mifostenant-default`
1. `./gradlew clean integrationTest`
Instructions to run using Docker and docker-compose
===================================================
It is possible to do a 'one-touch' installation of Fineract using docker-compose
Prerequisites:
* docker and docker-compose installed on your machine
Installing a new Fineract instance:
* Clone the Fineract Github repository
* Run the following commands:
* docker-compose build
* docker-compose up -d
* Fineract will run at https://localhost:8443/fineract-provider
Version
============
The latest stable release can be viewed on the develop branch: [Latest Release on Develop](https://github.com/apache/incubator-fineract/tree/develop "Latest Release"), [View change log](https://github.com/apache/incubator-fineract/blob/develop/CHANGELOG.md "Latest release change log")
The latest stable release can be viewed on the develop branch: [Latest Release on Develop](https://github.com/apache/fineract/tree/develop "Latest Release").
The progress of this project can be viewed here: [View change log](https://github.com/apache/fineract/blob/develop/CHANGELOG.md "Latest release change log")
License
============
This project is licensed under Apache License Version 2.0. See <https://github.com/apache/incubator-fineract/blob/develop/LICENSE.md>.
This project is licensed under Apache License Version 2.0. See <https://github.com/apache/incubator-fineract/blob/develop/LICENSE.md> for referece.
The Connector/J JDBC Driver client library from MariaDB.org, which is licensed under the LGPL,
is used in development when running integration tests that use the Flyway library. That JDBC
driver is however not included in and distributed with the Fineract product, and is not
required to use the product.
If you are developer and object to using the LGPL licensed Connector/J JDBC driver,
simply do not run the integration tests that use the Flyway library.
As discussed in [LEGAL-462](https://issues.apache.org/jira/browse/LEGAL-462), this project therefore
complies with the [Apache Software Foundation third-party license policy](https://www.apache.org/legal/resolved.html).
Apache Fineract Platform API
============
The API for the Fineract-platform (project named 'Apache Fineract') is documented in the API-docs under <b>Full API Matrix</b> and can be viewed [here](https://demo.openmf.org/api-docs/apiLive.htm "API Documentation").
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.openmf.org/api-docs/apiLive.htm "API Documentation").
Online Demos
============
* [Community App](https://demo.openmf.org "Reference Client App")
> For this demo, a demo account is also provided for users to experience the functionality of this Community App. Users can use "mifos" for USERNAME and "password" for PASSWORD(without quotation marks).
Developers
============
Please see <https://cwiki.apache.org/confluence/display/FINERACT/Contributor%27s+Zone> for the developers wiki page.
Please refer to <https://cwiki.apache.org/confluence/display/FINERACT/Fineract+101> for first time contribution for this project.
Please see <https://cwiki.apache.org/confluence/display/FINERACT/How-to+articles> for technical details to get started.
Roadmap
============
@@ -64,6 +120,15 @@ Video Demonstration
Apache Fineract / Mifos X Demo (November 2016) - <https://www.youtube.com/watch?v=h61g9TptMBo>
Governance and Policies
=======================
[Becoming a Committer](https://cwiki.apache.org/confluence/display/FINERACT/Becoming+a+Committer)
documents the process through which you can become a committer in this project.
[Pull Request Size Limit](https://cwiki.apache.org/confluence/display/FINERACT/Pull+Request+Size+Limit)
documents that we cannot accept huge "code dump" Pull Requests, with some related suggestions.
More Information
============
More details of the project can be found at <https://cwiki.apache.org/confluence/display/FINERACT>.
More details of the project can be found at <https://cwiki.apache.org/confluence/display/FINERACT>.
+4063 -71
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -745,4 +745,8 @@ ul.field li {
tt {
font-size: 9.5pt;
}
ol.normalli li {
list-style-type: decimal;
}
-38
View File
@@ -1,38 +0,0 @@
#!/bin/bash
#
# 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.
#
# Exit the script if any command returns a non-true return value (http://www.davidpashley.com/articles/writing-robust-shell-scripts/)
set -e
git --version
# TODO UNCOMMENT THIS once https://github.com/openMF/mifosx/pull/1291 is merged!
# git pull
# This does NOT get the most recent revision from the submodule repository.
# Instead, it only gets the revision of the submodule that is recorded in the revision of the main repository.
## NOT git submodule update --remote
# The following is very important, because even if the main (API) repo is latest,
# the sub-module initially will be a fixed old rev. and only this grabs real latest:
git submodule foreach 'git checkout develop && git pull --ff-only origin develop'
cd apps/community-app
./build.sh
cd ../../fineract-provider/
./gradlew -Penv=dev clean dist
+37
View File
@@ -0,0 +1,37 @@
# 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.
#
version: '3.7'
services:
fineractmysql:
image: mysql:5.7
volumes:
- ./fineract-db/docker:/docker-entrypoint-initdb.d
restart: always
environment:
MYSQL_ROOT_PASSWORD: mysql
ports:
- "3306:3306"
fineract-server:
build:
context: .
target: fineract
ports:
- 8443:8443
depends_on:
- fineractmysql
+191
View File
@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource type="javax.sql.DataSource"
name="jdbc/mifosplatform-tenants"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="org.drizzle.jdbc.DrizzleDriver"
url="jdbc:mysql:thin://fineractmysql:3306/mifosplatform-tenants"
username="root"
password="mysql"
initialSize="3"
maxActive="10"
maxIdle="6"
minIdle="3"
validationQuery="SELECT 1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
logAbandoned="true"
suspectTimeout="60"
/>
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
This connector uses the NIO implementation. The default
SSLImplementation will depend on the presence of the APR/native
library and the useOpenSSL attribute of the
AprLifecycleListener.
Either JSSE or OpenSSL style configuration may be used regardless of
the SSLImplementation selected. JSSE style configuration is used below.
-->
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200" scheme="https"
secure="true" SSLEnabled="true"
keystoreFile="/opt/bitnami/tomcat/tomcat.keystore"
keystorePass="xyz123"
clientAuth="false" sslProtocol="TLS"
URIEncoding="UTF-8"
compression="force"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css"/>
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
This connector uses the APR/native implementation which always uses
OpenSSL for TLS.
Either JSSE or OpenSSL style configuration may be used. OpenSSL style
configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" >
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>
</Server>
@@ -0,0 +1,7 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions
//Response Body:
{
"bulkTransactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d" // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
}
@@ -0,0 +1,28 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions
//GET paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions/11436b17-c690-4a30-8505-42a2c4eafb9d
//Response URI:
//PUT <FSPIOP-Callback>/interoperation/bulkTransactions/11436b17-c690-4a30-8505-42a2c4eafb9d
//Header:
//X-Tenant-Identifier: T111
//Response Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
"bulkTransferState": "COMPLETED", // mandatory, Enum of String(1..32): RECEIVED, PENDING, ACCEPTED, PROCESSING, COMPLETED, REJECTED
"individualTransferResults": [ // mandatory, (1..1000)
{
"transferId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
"transferState": "COMMITTED"// mandatory, Enum of String(1..32): RECEIVED, RESERVED, COMMITTED, ABORTED
},
{
"transferId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
"transferState": "COMMITTED"// mandatory, Enum of String(1..32): RECEIVED, RESERVED, COMMITTED, ABORTED
}
]
}
@@ -0,0 +1,60 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions
// HTTP/1.1
//Request Header:
//Accept: application/vnd.interoperability.quotes+json;version=1
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
//Content-Length: 975
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
//Origin: http://www.example.com
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
}
},
"amountType": "RECEIVE", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"individualTransfers": [ // mandatory, (1..1000)
{
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345671", // mandatory, String(1..128)
"partySubIdOrType": "nothing" // optional, String(1..128)
}
},
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
}
},
{
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345672", // mandatory, String(1..128)
"partySubIdOrType": "nothing" // optional, String(1..128)
}
},
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
}
}
],
"transactionType": { // mandatory
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,46 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
// HTTP/1.1
//Request Header:
//Accept: application/vnd.interoperability.quotes+json;version=1
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
//Content-Length: 975
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
//Origin: http://www.example.com
//FSPIOP-Callback: http://www.client-server.com/demo
//FSPIOP-Notification: http://www.client-server.com/demo
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
},
"merchantClassificationCode": "" // optional, String(1..4 digits)
},
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN4550000000058398257466", // mandatory, String(1..128)
"partySubIdOrType": "nothing", // optional, String(1..128)
"fspId": "BankNrOne" // optional, String(1..32)
}
},
"amountType": "RECEIVE", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transactionType": { // mandatory
"scenario": "PAYMENT", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,42 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
// HTTP/1.1
//Request Header:
//Accept: application/vnd.interoperability.quotes+json;version=1
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
//Content-Length: 975
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
//Origin: http://www.example.com
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
}
},
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
"partySubIdOrType": "nothing" // optional, String(1..128)
}
},
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transactionType": { // mandatory
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYEE", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,42 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
// HTTP/1.1
//Request Header:
//Accept: application/vnd.interoperability.quotes+json;version=1
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
//Content-Length: 975
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
//Origin: http://www.example.com
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
"partySubIdOrType": "nothing" // optional, String(1..128)
}
},
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
}
},
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transactionType": { // mandatory
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,53 @@
//Request URI:
//POST <FSPIOP-Notification>/channel/quotes/notification
//HTTP/1.1
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"requestId": "18e43330-187e-11e9-ab14-d663bd873d93", // optional, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"quoteId": "61058cea-187e-11e9-ab14-d663bd873d93", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "12345678901", // mandatory, String(1..128)
"partySubIdOrType": "nothing", // optional, String(1..128)
"fspId": "BankNrOne" // optional, String(1..32)
}
},
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
},
"name": "" // optional, String(1..128) ^(?!\s*$)[\w .,'-]{1,128}$
},
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"amount": {
"amount": "100",
"currency": "USD"
},
"transferAmount": {
"amount": "99",
"currency": "USD"
},
"fspFee": { // optional
"amount": "1", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"fspCommission": { // optional
"amount": "0", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transactionRole": "PAYEE",
"transactionType": { // mandatory
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,57 @@
//Request URI:
//POST <FSPIOP-Notification>/channel/quotes/notification
// HTTP/1.1
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"requestId": "18e43330-187e-11e9-ab14-d663bd873d93", // optional, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"quoteId": "61058cea-187e-11e9-ab14-d663bd873d93", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
"partySubIdOrType": "nothing", // optional, String(1..128)
"fspId": "BankNrOne" // optional, String(1..32)
},
"name": "" // optional, String(1..128) ^(?!\s*$)[\w .,'-]{1,128}$
},
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
}
},
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transferAmount": {
"amount": "99",
"currency": "USD"
},
"payeeReceiveAmount": {
"amount": "100",
"currency": "USD"
},
"fspFee": { // optional
"amount": "1", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"fspCommission": { // optional
"amount": "0", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transactionRole": "PAYER",
"transactionType": { // mandatory
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYEE", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,39 @@
//Request URI:
//POST <FSPIOP-Notification>/channel/transactions/{transactionId}/notification
// HTTP/1.1
//X-Tenant-Identifier: T111
//Request Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"requestId": "18e43330-187e-11e9-ab14-d663bd873d93", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
"payee": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
"partySubIdOrType": "nothing", // optional, String(1..128)
"fspId": "BankNrOne" // optional, String(1..32)
},
"name": "" // optional, String(1..128) ^(?!\s*$)[\w .,'-]{1,128}$
},
"payer": { // mandatory
"partyIdInfo": { // mandatory
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
"partySubIdOrType": "something" // optional, String(1..128)
}
},
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
"amount": { // mandatory
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
},
"transactionType": { // mandatory
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
"initiator": "PAYEE", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
},
"note": "From Mats", // optional, String(1..128)
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
}
@@ -0,0 +1,7 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
//Response Body:
{
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d" // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
}
@@ -0,0 +1,16 @@
//Request URI:
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
//GET paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions/11436b17-c690-4a30-8505-42a2c4eafb9d
//Response URI:
//PUT <FSPIOP-Callback>/interoperation/transactions/11436b17-c690-4a30-8505-42a2c4eafb9d
//Header:
//X-Tenant-Identifier: T111
//Response Body:
{
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
"transferState": "COMMITTED" // mandatory, Enum of String(1..32): RECEIVED, RESERVED, COMMITTED, ABORTED
}
+154
View File
@@ -0,0 +1,154 @@
/**
* 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.
*/
<style>
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
html {
padding: 30px 10px;
font-size: 20px;
line-height: 1.4;
color: #737373;
background: #f0f0f0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
input {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
body {
max-width: 500px;
_width: 500px;
padding: 30px 20px 50px;
border: 1px solid #b3b3b3;
border-radius: 4px;
margin: 0 auto;
box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;
background: #fcfcfc;
}
h1 {
margin: 0 10px;
font-size: 50px;
text-align: center;
}
h1 span {
color: #bbb;
}
h3 {
margin: 1.5em 0 0.5em;
}
p {
margin: 1em 0;
}
ul {
padding: 0 0 0 40px;
margin: 1em 0;
}
.container {
max-width: 380px;
_width: 380px;
margin: 0 auto;
}
/* google search */
#goog-fixurl ul {
list-style: none;
padding: 0;
margin: 0;
}
#goog-fixurl form {
margin: 0;
}
#goog-wm-qt,
#goog-wm-sb {
border: 1px solid #bbb;
font-size: 16px;
line-height: normal;
vertical-align: top;
color: #444;
border-radius: 2px;
}
#goog-wm-qt {
width: 220px;
height: 20px;
padding: 5px;
margin: 5px 10px 0 0;
box-shadow: inset 0 1px 1px #ccc;
}
#goog-wm-sb {
display: inline-block;
height: 32px;
padding: 0 10px;
margin: 5px 0 0;
white-space: nowrap;
cursor: pointer;
background-color: #f5f5f5;
background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
*overflow: visible;
*display: inline;
*zoom: 1;
}
#goog-wm-sb:hover,
#goog-wm-sb:focus {
border-color: #aaa;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
background-color: #f8f8f8;
}
#goog-wm-qt:hover,
#goog-wm-qt:focus {
border-color: #105cb6;
outline: 0;
color: #222;
}
input::-moz-focus-inner {
padding: 0;
border: 0;
}
</style>
+11 -135
View File
@@ -1,145 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Page Not Found :(</title>
<style>
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
html {
padding: 30px 10px;
font-size: 20px;
line-height: 1.4;
color: #737373;
background: #f0f0f0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
input {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
body {
max-width: 500px;
_width: 500px;
padding: 30px 20px 50px;
border: 1px solid #b3b3b3;
border-radius: 4px;
margin: 0 auto;
box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;
background: #fcfcfc;
}
h1 {
margin: 0 10px;
font-size: 50px;
text-align: center;
}
h1 span {
color: #bbb;
}
h3 {
margin: 1.5em 0 0.5em;
}
p {
margin: 1em 0;
}
ul {
padding: 0 0 0 40px;
margin: 1em 0;
}
.container {
max-width: 380px;
_width: 380px;
margin: 0 auto;
}
/* google search */
#goog-fixurl ul {
list-style: none;
padding: 0;
margin: 0;
}
#goog-fixurl form {
margin: 0;
}
#goog-wm-qt,
#goog-wm-sb {
border: 1px solid #bbb;
font-size: 16px;
line-height: normal;
vertical-align: top;
color: #444;
border-radius: 2px;
}
#goog-wm-qt {
width: 220px;
height: 20px;
padding: 5px;
margin: 5px 10px 0 0;
box-shadow: inset 0 1px 1px #ccc;
}
#goog-wm-sb {
display: inline-block;
height: 32px;
padding: 0 10px;
margin: 5px 0 0;
white-space: nowrap;
cursor: pointer;
background-color: #f5f5f5;
background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
*overflow: visible;
*display: inline;
*zoom: 1;
}
#goog-wm-sb:hover,
#goog-wm-sb:focus {
border-color: #aaa;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
background-color: #f8f8f8;
}
#goog-wm-qt:hover,
#goog-wm-qt:focus {
border-color: #105cb6;
outline: 0;
color: #222;
}
input::-moz-focus-inner {
padding: 0;
border: 0;
}
</style>
<link rel="stylesheet" href="404.css">
</head>
<body>
<div class="container">
<h1>Not found <span>:(</span></h1>
<p>Sorry, but the page you were trying to view does not exist.</p>
@@ -148,10 +19,15 @@
<li>a mistyped address</li>
<li>an out-of-date link</li>
</ul>
<script>
var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),GOOG_FIXURL_SITE = location.host;
</script>
<script src="//linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
</div>
</body>
</html>
+25
View File
@@ -0,0 +1,25 @@
--
-- 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.
--
# create databases
CREATE DATABASE IF NOT EXISTS `mifosplatform-tenants`;
CREATE DATABASE IF NOT EXISTS `mifostenant-default`;
# create root user and grant rights
GRANT ALL ON *.* TO 'root'@'%';
+1
View File
@@ -7,5 +7,6 @@ repos
.settings
.gradle
*.log
.idea
!gradle/wrapper/gradle-wrapper.jar
/gradle
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:
+122 -63
View File
@@ -20,7 +20,17 @@ description = '''\
Run as:
gradle clean tomcatrunwar
'''
project.ext.springBootVersion = '1.2.8.RELEASE'
project.ext.springVersion = '4.1.9.RELEASE'
project.ext.springOauthVersion = '2.0.4.RELEASE'
project.ext.jerseyVersion = '1.17'
project.ext.springDataJpaVersion = '1.7.0.RELEASE' // also change spring-boot-gradle-plugin version below
buildscript {
ext {
openJPAVersion = '2.4.1'
}
repositories {
jcenter()
mavenCentral()
@@ -31,8 +41,8 @@ buildscript {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:1.0',
'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0',
'org.zeroturnaround:gradle-jrebel-plugin:1.1.2',
'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE' // also change springDataJpaVersion below
classpath 'org.apache.openjpa:openjpa-all:2.4.1'
'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE' // also change springDataJpaVersion above
classpath "org.apache.openjpa:openjpa-all:$openJPAVersion"
classpath 'at.schmutterer.oss.gradle:gradle-openjpa:0.2.0'
classpath 'gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.2.2'
}
@@ -49,24 +59,19 @@ apply plugin: 'tomcat'
apply plugin: 'project-report'
apply plugin: 'java'
apply plugin: 'openjpa'
apply plugin: 'pmd'
apply plugin: 'findbugs'
/* define the valid syntax level for source files */
sourceCompatibility = JavaVersion.VERSION_1_8
/* define binary compatibility version */
targetCompatibility = JavaVersion.VERSION_1_8
project.ext.springBootVersion = '1.1.6.RELEASE'
project.ext.springVersion = '4.0.7.RELEASE'
project.ext.springOauthVersion = '2.0.4.RELEASE'
project.ext.jerseyVersion = '1.17'
project.ext.springDataJpaVersion = '1.7.0.RELEASE' // also change spring-boot-gradle-plugin version above
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)
@@ -75,7 +80,7 @@ openjpa {
files = fileTree(sourceSets.main.output.classesDir).matching {
include '**/AbstractPersistableCustom.class'
include '**/domain/*.class'
}
enforcePropertyRestrictions = true
}
@@ -84,11 +89,14 @@ rat {
xmlOutput = false
htmlOutput = false
plainOutput = true
verbose = true
inputDir = './..'
verbose = false
// inputDir = './..'
reportDir = new File(buildDir,'reports/rat')
excludes = [
'**/licenses/**',
'**/*.md',
'**/*.github/*',
'**/MANIFEST.MF',
'**/*.txt',
'**/*.log',
'**/fineractdev-eclipse-preferences.epf',
@@ -97,13 +105,19 @@ rat {
'**/.classpath',
'**/.project',
'**/.idea/**',
'**/*.ipr',
'**/*.iws',
'**/.settings/**',
'**/bin/**',
'**/.git/**',
'**/.gitignore',
'**/.gitkeep',
'**/*.iml',
//Notice files
'**/NOTICE_RELEASE',
'**/NOTICE_SOURCE',
// Swagger License
'**/src/main/resources/swagger-ui/**',
// gradle
'**/.gradle/**',
'**/gradlew',
@@ -114,8 +128,8 @@ rat {
'**/native/**',
'**/wrapper/**',
'**/build/**',
//Api Docs
//Api Docs
'**/api-docs/*.*',
'**/docs/system-architecture/.htaccess',
'**/docs/system-architecture/404.html',
@@ -123,14 +137,15 @@ rat {
'**/docs/system-architecture/**/*.xml',
'**/bootstrap-3.0.0/assets/application.js',
'**/system-architecture/js/plugins.js',
'**/docs/interoperation/specification/json/*.json',
//Apache License
'**/bootstrap-3.0.0/assets/less.js',
'**/css/bootstrap-3.0.0/**/*.*',
//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',
@@ -145,9 +160,11 @@ rat {
'**/system-architecture/js/vendor/toc-0.1.2/jquery.toc.min.js',
'**/assets/respond.min.js',
'**/assets/html5shiv.js',
//BSD License
'**/assets/uglify.js'
'**/assets/uglify.js',
//Ignore out folder
'**/out/**'
]
}
@@ -187,17 +204,33 @@ if (project.hasProperty('env') && project.getProperty('env') == 'dev') {
/* Enable Oauth2 authentication based on environment, default to HTTP basic auth */
if (project.hasProperty('security') && project.getProperty('security') == 'oauth') {
copy {
from './properties/oauth/'
into 'src/main/resources/'
include '*.properties'
}
if(project.hasProperty('twofactor') && project.getProperty('twofactor') == 'enabled') {
copy {
from './properties/oauth/twofactor/'
into 'src/main/resources/'
include '*.properties'
}
} else {
copy {
from './properties/oauth/'
into 'src/main/resources/'
include '*.properties'
}
}
} else {
copy {
from './properties/basicauth/'
into 'src/main/resources/'
include '*.properties'
}
if(project.hasProperty('twofactor') && project.getProperty('twofactor') == 'enabled') {
copy {
from './properties/basicauth/twofactor/'
into 'src/main/resources/'
include '*.properties'
}
} else {
copy {
from './properties/basicauth/'
into 'src/main/resources/'
include '*.properties'
}
}
}
task dist(type:Zip){
@@ -232,7 +265,7 @@ task dist(type:Zip){
include '**/*'
into('database/migrations')
}
from war.outputs.files
into(baseName + '-' + version)
}
@@ -240,23 +273,37 @@ task dist(type:Zip){
compileJava{
dependsOn rat
}
pmd {
sourceSets = [sourceSets.main]
ignoreFailures = true
}
findbugs {
ignoreFailures = true
sourceSets = [sourceSets.main]
}
war {
from('../licenses') { // notice the parens
into "WEB-INF/licenses/" // no leading slash
from('../licenses/binary/') { // notice the parens
into "WEB-INF/licenses/binary/" // no leading slash
}
from('../LICENSE') { // notice the parens
from('../LICENSE_RELEASE') { // notice the parens
into "WEB-INF/" // no leading slash
}
from('../NOTICE') { // 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
into "WEB-INF/" // no leading slash
}
war.finalizedBy(bootRepackage)
}
license {
header rootProject.file('../LICENSE.md')
excludes(["**/*.html", "**/*.mustache", "**/package-info.java", "**/keystore.jks"])
header rootProject.file('../APACHE_LICENSETEXT.md')
excludes(["**/*.html", "**/*.mustache", "**/package-info.java", "**/keystore.jks", "**/swagger-ui/**"])
strictCheck true
}
@@ -340,7 +387,7 @@ configurations {
driver
}
dependencies {
driver 'org.drizzle.jdbc:drizzle-jdbc:1.3'
driver 'org.drizzle.jdbc:drizzle-jdbc:1.4'
}
test {
@@ -357,17 +404,17 @@ configurations.driver.each {File file ->
task createDB<<{
description= "Creates the Database. Needs database name to be passed (like: -PdbName=someDBname)"
sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
sql.execute( 'create database '+"`$dbName`" )
}
task dropDB<<{
description= "Drops the specified database. The database name has to be passed (like: -PdbName=someDBname)"
sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
sql.execute( 'DROP DATABASE '+"`$dbName`")
}
task setBlankPassword<<{
sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
sql.execute('USE `mifosplatform-tenants`')
sql.execute('UPDATE mifosplatform-tenants.tenants SET schema_server = \'localhost\', schema_server_port = \'3306\', schema_username = \'mifos\', schema_password = \'mysql\' WHERE id=1;')
}
@@ -381,14 +428,26 @@ buildscript {
dependencies {
classpath "org.flywaydb:flyway-gradle-plugin:3.0" // version upgraded during Spring Boot & MariaDB4j work, as prev. used v0.2 didn't work well after *.sql moved from fineract-db to fineract-provider/src/main/resources (new version also has clearer errors, e.g. in case of missing DB)
classpath 'org.drizzle.jdbc:drizzle-jdbc:1.3'
// NOT classpath 'org.drizzle.jdbc:drizzle-jdbc:1.3' as it is not compatible with Flyway 3.1+ (only up to 3.0)
// We require Flyway 3.1+ because =< 3.0 is not compatible with current Gradle versions (only ancient ones we originally used to use).
// Using LGPL ConnectorJ ()org.mariadb.jdbc:mariadb-java-client) instead of the BSD licensed drizzle-jdbc *IS OK* at Apache.org,
// as long as it's only used as a test library by developers at build time, and not end-user distributed, and optional.
// So it's OK here, but would not be as a default runtime dependency and in the dist JAR/WAR.
// see https://issues.apache.org/jira/browse/LEGAL-462
// see https://issues.apache.org/jira/browse/FINERACT-761
// see https://github.com/flyway/flyway/issues/2332
// see https://github.com/krummas/DrizzleJDBC/issues/46
// see https://github.com/apache/fineract/pull/525
// see https://github.com/apache/fineract/pull/550
classpath 'org.mariadb.jdbc:mariadb-java-client:2.4.1'
}
}
flyway {
url = "jdbc:mysql:thin://localhost:3306/mifostenant-default"
driver = "org.drizzle.jdbc.DrizzleDriver"
url = "jdbc:mariadb://localhost:3306/mifostenant-default"
driver = "org.mariadb.jdbc.Driver"
user = mysqlUser
password = mysqlPassword
}
@@ -401,9 +460,9 @@ task migrateTenantDB<<{
if (rootProject.hasProperty("dbName")) {
tenantDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mysql:thin://localhost:3306/$tenantDbName"
flyway.driver = "org.drizzle.jdbc.DrizzleDriver"
flyway.url= "jdbc:mariadb://localhost:3306/$tenantDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
/**We use ${ as the prefix for strecthy reporting, do not want them to be interpreted by Flyway**/
flyway.placeholderPrefix = "\$\${"
@@ -412,15 +471,15 @@ task migrateTenantDB<<{
task showTenantDBInfo<<{
description="Shows the migration info for a Tenant DB. Optionally can pass dbName. Defaults to 'mifostenant-default' (Example: -PdbName=someTenantDBname)"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/core_db'
def tenantDbName = 'mifostenant-default';
if (rootProject.hasProperty("dbName")) {
tenantDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mysql:thin://localhost:3306/$tenantDbName"
flyway.driver = "org.drizzle.jdbc.DrizzleDriver"
flyway.url= "jdbc:mariadb://localhost:3306/$tenantDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayInfo.execute()
}
@@ -434,9 +493,9 @@ task migrateTenantListDB<<{
if (rootProject.hasProperty("dbName")) {
tenantsDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mysql:thin://localhost:3306/$tenantsDbName"
flyway.driver = "org.drizzle.jdbc.DrizzleDriver"
flyway.url= "jdbc:mariadb://localhost:3306/$tenantsDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayMigrate.execute()
@@ -444,30 +503,30 @@ task migrateTenantListDB<<{
task showTenantListDBInfo<<{
description="Shows the migration info for a List DB. Optionally can pass dbName. Defaults to 'mifosplatform-tenants' (Example: -PdbName=someDBname)"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
def tenantsDbName = 'mifosplatform-tenants';
if (rootProject.hasProperty("dbName")) {
tenantsDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mysql:thin://localhost:3306/$tenantsDbName"
flyway.driver = "org.drizzle.jdbc.DrizzleDriver"
flyway.url= "jdbc:mariadb://localhost:3306/$tenantsDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayInfo.execute()
}
task repairTenantDB<<{
description="repair migrate"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
def tenantsDbName = 'mifosplatform-tenants';
if (rootProject.hasProperty("dbName")) {
tenantsDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mysql:thin://localhost:3306/$tenantsDbName"
flyway.driver = "org.drizzle.jdbc.DrizzleDriver"
flyway.url= "jdbc:mariadb://localhost:3306/$tenantsDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayRepair.execute()
}
+15 -8
View File
@@ -25,7 +25,7 @@ dependencies {
}
tomcat "org.apache.tomcat:tomcat-dbcp:${tomcatVersion}"
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat:${springBootVersion}")
providedCompile(
// [group: 'javax.servlet', name: 'servlet-api', version: '2.5'],
@@ -42,8 +42,7 @@ dependencies {
[group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: springOauthVersion],
[group: 'org.apache.openjpa', name:'openjpa-all', version:'2.4.1'],
//[group: 'org.apache.openjpa', name:'openjpa-maven-plugin', version:'2.4.1'],
[group: 'org.apache.openjpa', name:'openjpa-all', version: openJPAVersion],
//[group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'],
[group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion],
[group: 'com.sun.jersey', name: 'jersey-servlet', version: jerseyVersion],
@@ -68,7 +67,7 @@ dependencies {
// no slf4j & logback here (anymore), as spring-boot-starter-logging already brings this now, better assembled (log4j-over-slf4j was originally forgotten here)
//[group: 'mysql', name: 'mysql-connector-java', version: '5.1.27'],
[group: 'org.drizzle.jdbc', name: 'drizzle-jdbc', version: '1.3'],
[group: 'org.drizzle.jdbc', name: 'drizzle-jdbc', version: '1.4'],
// [group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: tomcatVersion],
@@ -81,21 +80,29 @@ dependencies {
[group: 'org.mnode.ical4j', name: 'ical4j', version: '1.0.4'],
[group: 'com.googlecode.flyway', name: 'flyway-core', version: '2.1.1'],
[group: 'org.quartz-scheduler', name: 'quartz', version: '2.1.7'],
[group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.2.1'],
[group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.80'],
[group: 'net.sf.ehcache', name: 'ehcache', version: '2.7.2'],
[group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.8.12'],
[group: 'com.jayway.jsonpath', name: 'json-path', version: '0.9.1'],
[group: 'org.apache.tika', name: 'tika-core', version :'1.9'],
// Although fineract (at the time of writing) doesn't have any compile time dep. on this,
// 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
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5'],
// Once we've switched to Java 8 this dep can be removed.
//[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
)
[group: 'io.swagger', name: 'swagger-jersey-jaxrs', version: '1.5.15'],
[group: 'org.springframework', name:'spring-jms'],
[group: 'org.apache.activemq', name: 'activemq-broker'],
[group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final']
)
testCompile 'junit:junit:4.11',
'junit:junit-dep:4.11',
'org.mockito:mockito-core:1.9.5',
'com.jayway.restassured:rest-assured:2.3.3',
[group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion]
[group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion],
[group: 'com.mockrunner', name: 'mockrunner-jms', version: '1.0.6'],
[group: 'com.mockrunner', name: 'mockrunner-jdbc', version: '1.0.6']
}
+13 -5
View File
@@ -25,7 +25,7 @@ dependencies {
}
tomcat "org.apache.tomcat:tomcat-dbcp:${tomcatVersion}"
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat:${springBootVersion}")
providedCompile(
// [group: 'javax.servlet', name: 'servlet-api', version: '2.5'],
@@ -80,21 +80,29 @@ dependencies {
[group: 'org.mnode.ical4j', name: 'ical4j', version: '1.0.4'],
[group: 'com.googlecode.flyway', name: 'flyway-core', version: '2.1.1'],
[group: 'org.quartz-scheduler', name: 'quartz', version: '2.1.7'],
[group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.2.1'],
[group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.80'],
[group: 'net.sf.ehcache', name: 'ehcache', version: '2.7.2'],
[group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.8.12'],
[group: 'com.jayway.jsonpath', name: 'json-path', version: '0.9.1'],
[group: 'org.apache.tika', name: 'tika-core', version :'1.9'],
// Although fineract (at the time of writing) doesn't have any compile time dep. on this,
// 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
[group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.5'],
// Once we've switched to Java 8 this dep can be removed.
//[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
)
[group: 'io.swagger', name: 'swagger-jersey-jaxrs', version: '1.5.15'],
[group: 'org.springframework', name:'spring-jms'],
[group: 'org.apache.activemq', name: 'activemq-broker'],
[group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final']
)
testCompile 'junit:junit:4.11',
'junit:junit-dep:4.11',
'org.mockito:mockito-core:1.9.5',
'com.jayway.restassured:rest-assured:2.3.3',
[group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion]
[group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion],
[group: 'com.mockrunner', name: 'mockrunner-jms', version: '1.0.6'],
[group: 'com.mockrunner', name: 'mockrunner-jdbc', version: '1.0.6']
}
+1 -1
View File
@@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
releaseVersion=0.3.2-incubating
releaseVersion=1.0.0
buildType=BUILD
@@ -1,4 +1,3 @@
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -18,10 +17,5 @@
# under the License.
#
set -e
# https://developer.cloudbees.com/bin/view/DEV/Node+Builds
curl -s -o use-node https://repository-cloudbees.forge.cloudbees.com/distributions/ci-addons/node/use-node
NODE_VERSION=0.11.12 . ./use-node
./build.sh
spring.profiles.default=basicauth
spring.profiles.active=basicauth,twofactor
@@ -1,4 +1,3 @@
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -18,9 +17,5 @@
# under the License.
#
cd fineract-provider
# NOTE: The --info, while quite a bit more verbose, is VERY useful to understand failures on Travis,
# where you do not have access to any files like build/reports/tests/index.html, only the Console.
# @see http://mrhaki.blogspot.ch/2013/05/gradle-goodness-show-more-information.html
# @see http://forums.gradle.org/gradle/topics/whats_new_in_gradle_1_1_test_logging for alternative
./gradlew --info clean licenseMain licenseTest licenseIntegrationTest test
spring.profiles.default=basicauth
spring.profiles.active=oauth,twofactor
@@ -373,8 +373,9 @@ public class AccountNumberPreferencesTest {
}
}
private void validateAccountNumberLengthAndStartsWithPrefix(final String accountNumber, final String prefix) {
private void validateAccountNumberLengthAndStartsWithPrefix(final String accountNumber, String prefix) {
if (prefix != null) {
prefix = prefix.substring(0, Math.min(prefix.length(), 10));
Assert.assertEquals(accountNumber.length(), prefix.length() + 9);
Assert.assertTrue(accountNumber.startsWith(prefix));
} else {
@@ -19,7 +19,10 @@
package org.apache.fineract.integrationtests;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
@@ -338,6 +341,70 @@ public class BatchApiTest {
Assert.assertEquals("Verify Status Code 200 for Create Loan Charge", 200L, (long) response.get(3).getStatusCode());
}
/**
* 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
*/
@Test
public void shouldReturnOkStatusForBatchRepayment() {
final String loanProductJSON = new LoanProductTestBuilder() //
.withPrincipal("10000000.00") //
.withNumberOfRepayments("24") //
.withRepaymentAfterEvery("1") //
.withRepaymentTypeAsMonth() //
.withinterestRatePerPeriod("2") //
.withInterestRateFrequencyTypeAsMonths() //
.withAmortizationTypeAsEqualPrincipalPayment() //
.withInterestTypeAsDecliningBalance() //
.currencyDetails("0", "100").build(null);
final Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec).getLoanProductId(loanProductJSON);
// Create a createClient Request
final BatchRequest br1 = BatchHelper.createClientRequest(4730L, "");
// Create a activateClient Request
final BatchRequest br2 = BatchHelper.activateClientRequest(4731L, 4730L);
// Create a ApplyLoan Request
final BatchRequest br3 = BatchHelper.applyLoanRequest(4732L, 4731L, productId);
// Create a approveLoan Request
final BatchRequest br4 = BatchHelper.approveLoanRequest(4733L, 4732L);
// Create a disburseLoan Request
final BatchRequest br5 = BatchHelper.disburseLoanRequest(4734L, 4733L);
// Create a loanRepay Request
final BatchRequest br6 = BatchHelper.repayLoanRequest(4735L, 4734L);
// Create a loanRepay Request
final BatchRequest br7 = BatchHelper.repayLoanRequest(4736L, 4734L);
final List<BatchRequest> batchRequests = new ArrayList<>();
batchRequests.add(br1);
batchRequests.add(br2);
batchRequests.add(br3);
batchRequests.add(br4);
batchRequests.add(br5);
batchRequests.add(br6);
batchRequests.add(br7);
final String jsonifiedRequest = BatchHelper.toJsonString(batchRequests);
final List<BatchResponse> response = BatchHelper.postBatchRequestsWithoutEnclosingTransaction(this.requestSpec, this.responseSpec,
jsonifiedRequest);
Assert.assertEquals("Verify Status Code 200 for Repayment", 200L, (long) response.get(5).getStatusCode());
Assert.assertEquals("Verify Status Code 200 for Repayment", 200L, (long) response.get(6).getStatusCode());
}
/**
* Test for the successful activation of a pending client using
* 'ActivateClientCommandStrategy'. A '200' status code is expected on
@@ -422,4 +489,51 @@ public class BatchApiTest {
Assert.assertEquals("Verify Status Code 200 for Approve Loan", 200L, (long) response.get(3).getStatusCode());
Assert.assertEquals("Verify Status Code 200 for Disburse Loan", 200L, (long) response.get(4).getStatusCode());
}
/**
* 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
*/
@Test
public void shouldReturnOkStatusOnSuccessfulLoanApprovalAndDisburseWithTransaction(){
final String loanProductJSON = new LoanProductTestBuilder() //
.withPrincipal("10000000.00") //
.withNumberOfRepayments("24") //
.withRepaymentAfterEvery("1") //
.withRepaymentTypeAsMonth() //
.withinterestRatePerPeriod("2") //
.withInterestRateFrequencyTypeAsMonths() //
.withAmortizationTypeAsEqualPrincipalPayment() //
.withInterestTypeAsDecliningBalance() //
.currencyDetails("0", "100").build(null);
final Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec).getLoanProductId(loanProductJSON);
// Create a createClient Request
final BatchRequest br1 = BatchHelper.createActiveClientRequest(4740L, "");
// Create a ApplyLoan Request
final BatchRequest br2 = BatchHelper.applyLoanRequest(4742L, 4740L, productId);
// Create a approveLoan Request
final BatchRequest br3 = BatchHelper.approveLoanRequest(4743L, 4742L);
// Create a disburseLoan Request
final BatchRequest br4 = BatchHelper.disburseLoanRequest(4744L, 4743L);
final List<BatchRequest> batchRequests = Arrays.asList(br1,br2,br3,br4);
final String jsonifiedRequest = BatchHelper.toJsonString(batchRequests);
final List<BatchResponse> response = BatchHelper.postBatchRequestsWithEnclosingTransaction(this.requestSpec, this.responseSpec,
jsonifiedRequest);
Assert.assertEquals("Verify Status Code 200 for create client", 200L, (long) response.get(0).getStatusCode());
Assert.assertEquals("Verify Status Code 200 for apply Loan", 200L, (long) response.get(1).getStatusCode());
Assert.assertEquals("Verify Status Code 200 for approve Loan", 200L, (long) response.get(2).getStatusCode());
Assert.assertEquals("Verify Status Code 200 for disburse Loan", 200L, (long) response.get(3).getStatusCode());
}
}
@@ -199,61 +199,64 @@ public class CenterIntegrationTest {
@Test
public void testStaffAssignmentDuringCenterCreation() {
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
final Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
System.out.println("--------------creating first staff with id-------------" + staffId);
Assert.assertNotNull(staffId);
int centerWithStaffId = CenterHelper.createCenterWithStaffId(this.requestSpec, this.responseSpec, staffId);
CenterDomain center = CenterHelper.retrieveByID(centerWithStaffId, requestSpec, responseSpec);
final int centerWithStaffId = CenterHelper.createCenterWithStaffId(this.requestSpec, this.responseSpec, staffId);
final CenterDomain center = CenterHelper.retrieveByID(centerWithStaffId, requestSpec, responseSpec);
Assert.assertNotNull(center);
Assert.assertTrue(center.getId() == centerWithStaffId);
Assert.assertTrue(center.getStaffId() == staffId);
Assert.assertTrue(center.getStaffId().intValue() == staffId);
Assert.assertTrue(center.isActive() == true);
}
@Test
public void testAssignStaffToCenter() {
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
final Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
System.out.println("--------------creating first staff with id-------------" + staffId);
Assert.assertNotNull(staffId);
Integer groupID = CenterHelper.createCenter(this.requestSpec, this.responseSpec);
final Integer groupID = CenterHelper.createCenter(this.requestSpec, this.responseSpec);
CenterHelper.verifyCenterCreatedOnServer(this.requestSpec, this.responseSpec, groupID);
HashMap assignStaffToCenterResponseMap = (HashMap) CenterHelper.assignStaff(this.requestSpec, this.responseSpec, groupID.toString(),
final HashMap assignStaffToCenterResponseMap = (HashMap) CenterHelper.assignStaff(this.requestSpec,
this.responseSpec, groupID.toString(),
staffId.longValue());
assertEquals("Verify assigned staff id is the same as id sent", assignStaffToCenterResponseMap.get("staffId"), staffId);
CenterDomain center = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec);
final CenterDomain center = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec);
Assert.assertNotNull(center);
Assert.assertTrue(center.getId() == groupID);
Assert.assertTrue(center.getStaffId() == staffId);
Assert.assertTrue(center.getId().intValue() == groupID);
Assert.assertTrue(center.getStaffId().intValue() == staffId);
}
@Test
public void testUnassignStaffToCenter() {
Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
final Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
System.out.println("--------------creating first staff with id-------------" + staffId);
Assert.assertNotNull(staffId);
Integer groupID = CenterHelper.createCenter(this.requestSpec, this.responseSpec);
final Integer groupID = CenterHelper.createCenter(this.requestSpec, this.responseSpec);
CenterHelper.verifyCenterCreatedOnServer(this.requestSpec, this.responseSpec, groupID);
HashMap assignStaffToCenterResponseMap = (HashMap) CenterHelper.assignStaff(this.requestSpec, this.responseSpec, groupID.toString(),
final HashMap assignStaffToCenterResponseMap = (HashMap) CenterHelper.assignStaff(this.requestSpec,
this.responseSpec, groupID.toString(),
staffId.longValue());
assertEquals("Verify assigned staff id is the same as id sent", assignStaffToCenterResponseMap.get("staffId"), staffId);
CenterDomain centerWithStaffAssigned = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec);
final CenterDomain centerWithStaffAssigned = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec);
Assert.assertNotNull(centerWithStaffAssigned);
Assert.assertTrue(centerWithStaffAssigned.getId() == groupID);
Assert.assertTrue(centerWithStaffAssigned.getStaffId() == staffId);
Assert.assertTrue(centerWithStaffAssigned.getId().intValue() == groupID);
Assert.assertTrue(centerWithStaffAssigned.getStaffId().intValue() == staffId);
HashMap unassignStaffToCenterResponseMap = (HashMap) CenterHelper.unassignStaff(this.requestSpec, this.responseSpec, groupID.toString(),
final HashMap unassignStaffToCenterResponseMap = (HashMap) CenterHelper.unassignStaff(this.requestSpec,
this.responseSpec, groupID.toString(),
staffId.longValue());
assertEquals("Verify staffId is null after unassigning ", unassignStaffToCenterResponseMap.get("staffId"), null);
CenterDomain centerWithStaffUnssigned = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec);
final CenterDomain centerWithStaffUnssigned = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec);
Assert.assertNotNull(centerWithStaffUnssigned);
Assert.assertTrue(centerWithStaffUnssigned.getId() == groupID);
Assert.assertTrue(centerWithStaffUnssigned.getId().intValue() == groupID);
Assert.assertTrue(centerWithStaffUnssigned.getStaffId() == null);
}
@@ -28,10 +28,12 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
@@ -1632,9 +1634,10 @@ public class ClientSavingsIntegrationTest {
final String INTEREST_POSTING_DATE = dateFormat.format(interestPostingDate.getTime());
final String TODYS_POSTING_DATE = dateFormat.format(todysDate.getTime());
String withdrawBalance = "true";
if (TODYS_POSTING_DATE.equalsIgnoreCase(INTEREST_POSTING_DATE)) {
final SavingsAccountHelper validationErrorHelper = new SavingsAccountHelper(this.requestSpec, errorResponse);
final SavingsAccountHelper validationErrorHelper = new SavingsAccountHelper(this.requestSpec, responseSpec);
validationErrorHelper.closeSavingsAccountPostInterestAndGetBackRequiredField(savingsId, withdrawBalance,
CommonConstants.RESPONSE_ERROR, CLOSEDON_DATE);
} else {
@@ -2115,4 +2118,119 @@ public class ClientSavingsIntegrationTest {
* assertEquals("Verifying Interest Calculation", new Float("238.3399"),
* savingsInterest); }
*/
@SuppressWarnings("unchecked")
@Test
public void testSavingsAccountBlockStatus() {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
SavingsAccountHelper savingsAccountHelperValidationError = new SavingsAccountHelper(this.requestSpec,
new ResponseSpecBuilder().build());
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
final String minBalanceForInterestCalculation = null;
final String minRequiredBalance = null;
final String enforceMinRequiredBalance = "false";
final boolean allowOverdraft = false;
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance, allowOverdraft);
Assert.assertNotNull(savingsProductID);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
Assert.assertNotNull(savingsProductID);
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId);
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.approveSavings(savingsId);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
HashMap summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
Float balance = new Float(MINIMUM_OPENING_BALANCE);
savingsStatusHashMap = this.savingsAccountHelper.blockSavings(savingsId);
SavingsStatusChecker.verifySavingsSubStatusblock(savingsStatusHashMap);
List<HashMap> error = (List) savingsAccountHelperValidationError.withdrawalFromSavingsAccount(savingsId, "100",
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_ERROR);
assertEquals("error.msg.saving.account.blocked.transaction.not.allowed",
error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
error = (List) savingsAccountHelperValidationError.depositToSavingsAccount(savingsId, "100", SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_ERROR);
assertEquals("error.msg.saving.account.blocked.transaction.not.allowed",
error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
savingsStatusHashMap = this.savingsAccountHelper.unblockSavings(savingsId);
SavingsStatusChecker.verifySavingsSubStatusIsNone(savingsStatusHashMap);
Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, DEPOSIT_AMOUNT,
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
HashMap depositTransaction = this.savingsAccountHelper.getSavingsTransaction(savingsId, depositTransactionId);
balance += new Float(DEPOSIT_AMOUNT);
assertEquals("Verifying Deposit Amount", new Float(DEPOSIT_AMOUNT), depositTransaction.get("amount"));
savingsStatusHashMap = this.savingsAccountHelper.blockDebit(savingsId);
SavingsStatusChecker.verifySavingsSubStatusIsDebitBlocked(savingsStatusHashMap);
error = (List) savingsAccountHelperValidationError.withdrawalFromSavingsAccount(savingsId, "100",
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_ERROR);
assertEquals("error.msg.savings.account.debit.transaction.not.allowed",
error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, DEPOSIT_AMOUNT,
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
depositTransaction = this.savingsAccountHelper.getSavingsTransaction(savingsId, depositTransactionId);
balance += new Float(DEPOSIT_AMOUNT);
assertEquals("Verifying Deposit Amount", new Float(DEPOSIT_AMOUNT), depositTransaction.get("amount"));
savingsStatusHashMap = this.savingsAccountHelper.unblockDebit(savingsId);
SavingsStatusChecker.verifySavingsSubStatusIsNone(savingsStatusHashMap);
Integer withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, WITHDRAW_AMOUNT,
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
HashMap withdrawTransaction = this.savingsAccountHelper.getSavingsTransaction(savingsId, withdrawTransactionId);
balance -= new Float(WITHDRAW_AMOUNT);
assertEquals("Verifying Withdrawal Amount", new Float(WITHDRAW_AMOUNT), withdrawTransaction.get("amount"));
savingsStatusHashMap = this.savingsAccountHelper.blockCredit(savingsId);
SavingsStatusChecker.verifySavingsSubStatusIsCreditBlocked(savingsStatusHashMap);
error = (List) savingsAccountHelperValidationError.depositToSavingsAccount(savingsId, "100", SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_ERROR);
assertEquals("error.msg.savings.account.credit.transaction.not.allowed",
error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, WITHDRAW_AMOUNT,
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
withdrawTransaction = this.savingsAccountHelper.getSavingsTransaction(savingsId, withdrawTransactionId);
balance -= new Float(WITHDRAW_AMOUNT);
assertEquals("Verifying Withdrawal Amount", new Float(WITHDRAW_AMOUNT), withdrawTransaction.get("amount"));
savingsStatusHashMap = this.savingsAccountHelper.unblockCredit(savingsId);
SavingsStatusChecker.verifySavingsSubStatusIsNone(savingsStatusHashMap);
depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, DEPOSIT_AMOUNT,
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
depositTransaction = this.savingsAccountHelper.getSavingsTransaction(savingsId, depositTransactionId);
balance += new Float(DEPOSIT_AMOUNT);
assertEquals("Verifying Deposit Amount", new Float(DEPOSIT_AMOUNT), depositTransaction.get("amount"));
Integer holdTransactionId = (Integer) this.savingsAccountHelper.holdAmountInSavingsAccount(savingsId, String.valueOf(balance - 100),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
error = (List) savingsAccountHelperValidationError.withdrawalFromSavingsAccount(savingsId, "300",
SavingsAccountHelper.TRANSACTION_DATE_PLUS_ONE, CommonConstants.RESPONSE_ERROR);
assertEquals("error.msg.savingsaccount.transaction.insufficient.account.balance",
error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
Integer releaseTransactionId = this.savingsAccountHelper.releaseAmount(savingsId, holdTransactionId);
Date today = DateUtils.getDateOfTenant();
String todayDate = today.toString();
SimpleDateFormat dt1 = new SimpleDateFormat("dd MMM yyyy");
todayDate = dt1.format(today).toString();
withdrawTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "300", todayDate,
CommonConstants.RESPONSE_RESOURCE_ID);
withdrawTransaction = this.savingsAccountHelper.getSavingsTransaction(savingsId, withdrawTransactionId);
balance -= new Float("300");
assertEquals("Verifying Withdrawal Amount", new Float("300"), withdrawTransaction.get("amount"));
}
}
@@ -1855,7 +1855,7 @@ public class FixedDepositTest {
final String VALID_TO = dateFormat.format(todaysDate.getTime());
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.MONTH, -1);
//todaysDate.add(Calendar.MONTH, -1);
Integer currentDate = new Integer(currentDateFormat.format(todaysDate.getTime()));
todaysDate.add(Calendar.DATE, -(currentDate - 1));
final String SUBMITTED_ON_DATE = dateFormat.format(todaysDate.getTime());
@@ -0,0 +1,55 @@
/**
* 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 com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.integrationtests.common.NotificationHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
public class NotificationApiTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
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();
}
@Test
@SuppressWarnings("unchecked")
public void testNotificationRetrieval() {
HashMap<String, Object> response = (HashMap<String, Object>) NotificationHelper.getNotifications(this.requestSpec,
this.responseSpec, "");
System.out.println("Response : " + response.toString());
Assert.assertNotNull(response);
}
}
@@ -108,7 +108,7 @@ public class SchedulerJobsTest {
Thread.sleep(15000);
schedulerJob = this.schedulerJobHelper.getSchedulerJobById(this.requestSpec, this.responseSpec, jobId.toString());
Assert.assertNotNull(schedulerJob);
System.out.println("Job is Still Running");
System.out.println("Job " +jobId.toString() +" is Still Running");
}
ArrayList<HashMap> jobHistoryData = this.schedulerJobHelper.getSchedulerJobHistory(this.requestSpec, this.responseSpec,
jobId.toString());
@@ -24,6 +24,8 @@ import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -136,7 +138,6 @@ public class SchedulerJobsTestResults {
savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
HashMap summaryBefore = this.savingsAccountHelper.getSavingsSummary(savingsId);
String JobName = "Apply Annual Fee For Savings";
this.schedulerJobHelper.executeJob(JobName);
@@ -144,9 +145,14 @@ public class SchedulerJobsTestResults {
Float chargeAmount = (Float) chargeData.get("amount");
final HashMap summaryAfter = this.savingsAccountHelper.getSavingsSummary(savingsId);
Assert.assertEquals("Verifying Annual Fee after Running Scheduler Job for Apply Anual Fee", chargeAmount,
(Float) summaryAfter.get("totalAnnualFees"));
final HashMap savingsDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
final HashMap annualFeeDetails = (HashMap) savingsDetails.get("annualFee");
ArrayList<Integer> annualFeeDueDateAsArrayList = (ArrayList<Integer>) annualFeeDetails.get("dueDate");
LocalDate nextDueDateForAnnualFee = LocalDate.of(annualFeeDueDateAsArrayList.get(0), annualFeeDueDateAsArrayList.get(1), annualFeeDueDateAsArrayList.get(2));
LocalDate todaysDate = LocalDate.now(ZoneId.of("Asia/Kolkata"));
Assert.assertTrue("Verifying that all due Annual Fees have been paid ",
nextDueDateForAnnualFee.isAfter(todaysDate));
}
@@ -0,0 +1,144 @@
/**
* 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.bulkimport.importhandler.client;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.ClientEntityConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.fineract.integrationtests.common.system.CodeHelper;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ClientEntityImportHandlerTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
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();
}
@Test
@Ignore
public void testClientImport() throws InterruptedException, IOException, ParseException {
//in order to populate helper sheets
StaffHelper staffHelper=new StaffHelper();
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
Integer outcome_staff_creation =staffHelper.createStaff(requestSpec,responseSpec);
Assert.assertNotNull("Could not create staff",outcome_staff_creation);
//in order to populate helper sheets
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Integer outcome_office_creation=officeHelper.createOffice("02 May 2000");
Assert.assertNotNull("Could not create office" ,outcome_office_creation);
//in order to populate helper columns in client entity sheet
CodeHelper codeHelper=new CodeHelper();
//create constitution
codeHelper.retrieveOrCreateCodeValue(24,requestSpec,responseSpec);
//create client classification
codeHelper.retrieveOrCreateCodeValue(17,requestSpec,responseSpec);
//create client types
codeHelper.retrieveOrCreateCodeValue(16,requestSpec,responseSpec);
//create Address types
codeHelper.retrieveOrCreateCodeValue(29,requestSpec,responseSpec);
//create State
codeHelper.retrieveOrCreateCodeValue(27,requestSpec,responseSpec);
//create Country
codeHelper.retrieveOrCreateCodeValue(28,requestSpec,responseSpec);
//create Main business line
codeHelper.retrieveOrCreateCodeValue(25,requestSpec,responseSpec);
ClientHelper clientHelper=new ClientHelper(requestSpec,responseSpec);
Workbook workbook=clientHelper.getClientEntityWorkbook(GlobalEntityType.CLIENTS_ENTTTY,"dd MMMM yyyy");
//insert dummy data into client entity sheet
Sheet clientEntitySheet = workbook.getSheet(TemplatePopulateImportConstants.CLIENT_ENTITY_SHEET_NAME);
Row firstClientRow=clientEntitySheet.getRow(1);
firstClientRow.createCell(ClientEntityConstants.NAME_COL).setCellValue(Utils.randomNameGenerator("C_E_",6));
Sheet staffSheet=workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
firstClientRow.createCell(ClientEntityConstants.OFFICE_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(0).getStringCellValue());
firstClientRow.createCell(ClientEntityConstants.STAFF_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(1).getStringCellValue());
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd MMMM yyyy");
Date incoporationDate=simpleDateFormat.parse("14 May 2001");
firstClientRow.createCell(ClientEntityConstants.INCOPORATION_DATE_COL).setCellValue(incoporationDate);
Date validTill=simpleDateFormat.parse("14 May 2019");
firstClientRow.createCell(ClientEntityConstants.INCOPORATION_VALID_TILL_COL).setCellValue(validTill);
firstClientRow.createCell(ClientEntityConstants.MOBILE_NO_COL).setCellValue(Utils.randomNumberGenerator(7));
firstClientRow.createCell(ClientEntityConstants.CLIENT_TYPE_COL).setCellValue(clientEntitySheet.getRow(1).getCell(ClientEntityConstants.LOOKUP_CLIENT_TYPES).getStringCellValue());
firstClientRow.createCell(ClientEntityConstants.CLIENT_CLASSIFICATION_COL).setCellValue(clientEntitySheet.getRow(1).getCell(ClientEntityConstants.LOOKUP_CLIENT_CLASSIFICATION).getStringCellValue());
firstClientRow.createCell(ClientEntityConstants.INCOPORATION_NUMBER_COL).setCellValue(Utils.randomNumberGenerator(6));
firstClientRow.createCell(ClientEntityConstants.MAIN_BUSINESS_LINE).setCellValue(clientEntitySheet.getRow(1).getCell(ClientEntityConstants.LOOKUP_MAIN_BUSINESS_LINE).getStringCellValue());
firstClientRow.createCell(ClientEntityConstants.CONSTITUTION_COL).setCellValue(clientEntitySheet.getRow(1).getCell(ClientEntityConstants.LOOKUP_CONSTITUTION_COL).getStringCellValue());
firstClientRow.createCell(ClientEntityConstants.ACTIVE_COL).setCellValue("False");
Date submittedDate=simpleDateFormat.parse("28 September 2017");
firstClientRow.createCell(ClientEntityConstants.SUBMITTED_ON_COL).setCellValue(submittedDate);
firstClientRow.createCell(ClientEntityConstants.ADDRESS_ENABLED).setCellValue("False");
File directory=new File(System.getProperty("user.home")+File.separator+"Fineract"+File.separator+"bulkimport"+File.separator+"integration_tests"+File.separator+"importhandler"+File.separator+"client") ;
if (!directory.exists())
directory.mkdirs();
File file= new File(directory+File.separator+"ClientEntity.xls");
OutputStream outputStream=new FileOutputStream(file);
workbook.write(outputStream);
outputStream.close();
String importDocumentId=clientHelper.importClientEntityTemplate(file);
file.delete();
Assert.assertNotNull(importDocumentId);
//Wait for the creation of output excel
Thread.sleep(3000);
//check status column of output excel
String location=clientHelper.getOutputTemplateLocation(importDocumentId);
FileInputStream fileInputStream = new FileInputStream(location);
Workbook outputWorkbook=new HSSFWorkbook(fileInputStream);
Sheet outputClientEntitySheet = outputWorkbook.getSheet(TemplatePopulateImportConstants.CLIENT_ENTITY_SHEET_NAME);
Row row= outputClientEntitySheet.getRow(1);
Assert.assertEquals("Imported",row.getCell(ClientEntityConstants.STATUS_COL).getStringCellValue());
}
}
@@ -0,0 +1,176 @@
/**
* 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.bulkimport.importhandler.loan;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.LoanConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.integrationtests.common.*;
import org.apache.fineract.integrationtests.common.funds.FundsResourceHandler;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LoanImportHandlerTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
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();
}
@Test
@Ignore
public void testLoanImport() throws InterruptedException, IOException, ParseException {
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
//in order to populate helper sheets
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Integer outcome_office_creation=officeHelper.createOffice("02 May 2000");
Assert.assertNotNull("Could not create office" ,outcome_office_creation);
//in order to populate helper sheets
ClientHelper clientHelper=new ClientHelper(requestSpec,responseSpec);
Integer outcome_client_creation=clientHelper.createClient(requestSpec,responseSpec);
Assert.assertNotNull("Could not create client" ,outcome_client_creation);
//in order to populate helper sheets
GroupHelper groupHelper=new GroupHelper(requestSpec,responseSpec);
Integer outcome_group_creation=groupHelper.createGroup(requestSpec,responseSpec,true);
Assert.assertNotNull("Could not create group" ,outcome_group_creation);
//in order to populate helper sheets
StaffHelper staffHelper=new StaffHelper();
Integer outcome_staff_creation =staffHelper.createStaff(requestSpec,responseSpec);
Assert.assertNotNull("Could not create staff",outcome_staff_creation);
// LoanTransactionHelper ltHelper=new LoanTransactionHelper(requestSpec,responseSpec);
// LoanProductTestBuilder loanProductTestBuilder=new LoanProductTestBuilder();
// String jsonLoanProduct=loanProductTestBuilder.build(null);
// Integer outcome_lp_creaion=ltHelper.getLoanProductId(jsonLoanProduct);
// Assert.assertNotNull("Could not create Loan Product" ,outcome_lp_creaion);
// FundsResourceHandler fundsResourceHandler=new FundsResourceHandler();
// String jsonFund="{\n" +
// "\t\"name\": \""+Utils.randomNameGenerator("Fund_Name",9)+"\"\n" +
// "}";
// Integer outcome_fund_creation=fundsResourceHandler.createFund(jsonFund,requestSpec,responseSpec);
// Assert.assertNotNull("Could not create Fund" ,outcome_fund_creation);
// PaymentTypeHelper paymentTypeHelper=new PaymentTypeHelper();
// String name = PaymentTypeHelper.randomNameGenerator("P_T", 5);
// String description = PaymentTypeHelper.randomNameGenerator("PT_Desc", 15);
// Boolean isCashPayment = true;
// Integer position = 1;
// Integer outcome_payment_creation= paymentTypeHelper.createPaymentType(requestSpec, responseSpec,name,description,isCashPayment,position);
// Assert.assertNotNull("Could not create payment type" ,outcome_payment_creation);
LoanTransactionHelper loanTransactionHelper=new LoanTransactionHelper(requestSpec,responseSpec);
Workbook workbook=loanTransactionHelper.getLoanWorkbook("dd MMMM yyyy");
//insert dummy data into loan Sheet
Sheet loanSheet = workbook.getSheet(TemplatePopulateImportConstants.LOANS_SHEET_NAME);
Row firstLoanRow=loanSheet.getRow(1);
Sheet officeSheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
firstLoanRow.createCell(LoanConstants.OFFICE_NAME_COL).setCellValue(officeSheet.getRow(1).getCell(1).getStringCellValue());
firstLoanRow.createCell(LoanConstants.LOAN_TYPE_COL).setCellValue("Individual");
firstLoanRow.createCell(LoanConstants.CLIENT_NAME_COL).setCellValue(loanSheet.getRow(1).getCell(LoanConstants.LOOKUP_CLIENT_NAME_COL).getStringCellValue());
firstLoanRow.createCell(LoanConstants.CLIENT_EXTERNAL_ID).setCellValue(loanSheet.getRow(1).getCell(LoanConstants.LOOKUP_CLIENT_EXTERNAL_ID).getStringCellValue());
Sheet loanProductSheet=workbook.getSheet(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME);
firstLoanRow.createCell(LoanConstants.PRODUCT_COL).setCellValue(loanProductSheet.getRow(1).getCell(1).getStringCellValue());
Sheet staffSheet=workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
firstLoanRow.createCell(LoanConstants.LOAN_OFFICER_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(1).getStringCellValue());
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd MMMM yyyy");
Date date=simpleDateFormat.parse("13 May 2017");
firstLoanRow.createCell(LoanConstants.SUBMITTED_ON_DATE_COL).setCellValue(date);
firstLoanRow.createCell(LoanConstants.APPROVED_DATE_COL).setCellValue(date);
firstLoanRow.createCell(LoanConstants.DISBURSED_DATE_COL).setCellValue(date);
Sheet extrasSheet=workbook.getSheet(TemplatePopulateImportConstants.EXTRAS_SHEET_NAME);
firstLoanRow.createCell(LoanConstants.DISBURSED_PAYMENT_TYPE_COL).setCellValue(extrasSheet.getRow(1).getCell(3).getStringCellValue());
firstLoanRow.createCell(LoanConstants.FUND_NAME_COL).setCellValue(extrasSheet.getRow(1).getCell(1).getStringCellValue());
firstLoanRow.createCell(LoanConstants.PRINCIPAL_COL).setCellValue(loanProductSheet.getRow(1).getCell(3).getNumericCellValue());
firstLoanRow.createCell(LoanConstants.NO_OF_REPAYMENTS_COL).setCellValue(loanProductSheet.getRow(1).getCell(6).getNumericCellValue());
firstLoanRow.createCell(LoanConstants.REPAID_EVERY_COL).setCellValue(loanProductSheet.getRow(1).getCell(9).getNumericCellValue());
firstLoanRow.createCell(LoanConstants.REPAID_EVERY_FREQUENCY_COL).setCellValue(loanProductSheet.getRow(1).getCell(10).getStringCellValue());
firstLoanRow.createCell(LoanConstants.LOAN_TERM_COL).setCellValue(60);
firstLoanRow.createCell(LoanConstants.LOAN_TERM_FREQUENCY_COL).setCellValue(loanProductSheet.getRow(1).getCell(10).getStringCellValue());
firstLoanRow.createCell(LoanConstants.NOMINAL_INTEREST_RATE_COL).setCellValue(loanProductSheet.getRow(1).getCell(11).getNumericCellValue());
firstLoanRow.createCell(LoanConstants.NOMINAL_INTEREST_RATE_FREQUENCY_COL).setCellValue(loanProductSheet.getRow(1).getCell(14).getStringCellValue());
firstLoanRow.createCell(LoanConstants.AMORTIZATION_COL).setCellValue(loanProductSheet.getRow(1).getCell(15).getStringCellValue());
firstLoanRow.createCell(LoanConstants.INTEREST_METHOD_COL).setCellValue(loanProductSheet.getRow(1).getCell(16).getStringCellValue());
firstLoanRow.createCell(LoanConstants.INTEREST_CALCULATION_PERIOD_COL).setCellValue(loanProductSheet.getRow(1).getCell(17).getStringCellValue());
firstLoanRow.createCell(LoanConstants.ARREARS_TOLERANCE_COL).setCellValue(0);
firstLoanRow.createCell(LoanConstants.REPAYMENT_STRATEGY_COL).setCellValue(loanProductSheet.getRow(1).getCell(19).getStringCellValue());
firstLoanRow.createCell(LoanConstants.GRACE_ON_PRINCIPAL_PAYMENT_COL).setCellValue(0);
firstLoanRow.createCell(LoanConstants.GRACE_ON_INTEREST_PAYMENT_COL).setCellValue(0);
firstLoanRow.createCell(LoanConstants.GRACE_ON_INTEREST_CHARGED_COL).setCellValue(0);
firstLoanRow.createCell(LoanConstants.FIRST_REPAYMENT_COL).setCellValue(date);
firstLoanRow.createCell(LoanConstants.TOTAL_AMOUNT_REPAID_COL).setCellValue(6000);
firstLoanRow.createCell(LoanConstants.LAST_REPAYMENT_DATE_COL).setCellValue(date);
firstLoanRow.createCell(LoanConstants.REPAYMENT_TYPE_COL).setCellValue(extrasSheet.getRow(1).getCell(3).getStringCellValue());
String currentdirectory = new File("").getAbsolutePath();
File directory=new File(currentdirectory+File.separator+"src"+File.separator+"integrationTest"+File.separator+
"resources"+File.separator+"bulkimport"+File.separator+"importhandler"+File.separator+"loan") ;
if (!directory.exists())
directory.mkdirs();
File file= new File(directory+File.separator+"Loan.xls");
OutputStream outputStream=new FileOutputStream(file);
workbook.write(outputStream);
outputStream.close();
String importDocumentId=loanTransactionHelper.importLoanTemplate(file);
file.delete();
Assert.assertNotNull(importDocumentId);
//Wait for the creation of output excel
Thread.sleep(10000);
//check status column of output excel
String location=loanTransactionHelper.getOutputTemplateLocation(importDocumentId);
FileInputStream fileInputStream = new FileInputStream(location);
Workbook Outputworkbook=new HSSFWorkbook(fileInputStream);
Sheet outputLoanSheet = Outputworkbook.getSheet(TemplatePopulateImportConstants.LOANS_SHEET_NAME);
Row row= outputLoanSheet.getRow(1);
Assert.assertEquals("Imported",row.getCell(LoanConstants.STATUS_COL).getStringCellValue());
}
}
@@ -0,0 +1,104 @@
/**
* 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.bulkimport.importhandler.office;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.OfficeConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.infrastructure.bulkimport.populator.AbstractWorkbookPopulator;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.organisation.office.domain.Office;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.io.*;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class OfficeImportHandlerTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
public void setup(){
Utils.initializeRESTAssured();
this.requestSpec=new RequestSpecBuilder().build();
this.requestSpec
.header("Authorization",
"Basic "
+ Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200)
.build();
}
@Test
@Ignore
public void testOfficeImport() throws IOException, InterruptedException, NoSuchFieldException, ParseException {
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Workbook workbook=officeHelper.getOfficeWorkBook("dd MMMM yyyy");
//insert dummy data into excel
Sheet sheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
Row firstOfficeRow= sheet.getRow(1);
firstOfficeRow.createCell(OfficeConstants.OFFICE_NAME_COL).setCellValue(Utils.randomNameGenerator("Test_Off_",6));
firstOfficeRow.createCell(OfficeConstants.PARENT_OFFICE_NAME_COL).setCellValue(firstOfficeRow.getCell(OfficeConstants.LOOKUP_OFFICE_COL).getStringCellValue());
firstOfficeRow.createCell(OfficeConstants.PARENT_OFFICE_ID_COL).setCellValue(firstOfficeRow.getCell(OfficeConstants.LOOKUP_OFFICE_ID_COL).getNumericCellValue());
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd MMMM yyyy");
Date date=simpleDateFormat.parse("14 May 2001");
firstOfficeRow.createCell(OfficeConstants.OPENED_ON_COL).setCellValue(date);
String currentdirectory = new File("").getAbsolutePath();
File directory=new File(currentdirectory+File.separator+"src"+File.separator+"integrationTest"+File.separator+
"resources"+File.separator+"bulkimport"+File.separator+"importhandler"+File.separator+"office");
if (!directory.exists())
directory.mkdirs();
File file= new File(directory+File.separator+"Office.xls");
OutputStream outputStream=new FileOutputStream(file);
workbook.write(outputStream);
outputStream.close();
String importDocumentId=officeHelper.importOfficeTemplate(file);
file.delete();
Assert.assertNotNull(importDocumentId);
// Wait for the creation of output excel
Thread.sleep(3000);
//check status column of output excel
String location=officeHelper.getOutputTemplateLocation(importDocumentId);
FileInputStream fileInputStream = new FileInputStream(location);
Workbook outputWorkbook=new HSSFWorkbook(fileInputStream);
Sheet officeSheet = outputWorkbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
Row row= officeSheet.getRow(1);
Assert.assertEquals("Imported",row.getCell(OfficeConstants.STATUS_COL).getStringCellValue());
}
}
@@ -0,0 +1,155 @@
/**
* 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.bulkimport.importhandler.savings;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.LoanConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.SavingsConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GroupHelper;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.template.domain.Template;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SavingsImportHandlerTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
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();
}
@Test
@Ignore
public void testSavingsImport() throws InterruptedException, IOException, ParseException {
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
//in order to populate helper sheets
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Integer outcome_office_creation=officeHelper.createOffice("02 May 2000");
Assert.assertNotNull("Could not create office" ,outcome_office_creation);
//in order to populate helper sheets
ClientHelper clientHelper=new ClientHelper(requestSpec,responseSpec);
Integer outcome_client_creation=clientHelper.createClient(requestSpec,responseSpec);
Assert.assertNotNull("Could not create client" ,outcome_client_creation);
//in order to populate helper sheets
GroupHelper groupHelper=new GroupHelper(requestSpec,responseSpec);
Integer outcome_group_creation=groupHelper.createGroup(requestSpec,responseSpec,true);
Assert.assertNotNull("Could not create group" ,outcome_group_creation);
//in order to populate helper sheets
StaffHelper staffHelper=new StaffHelper();
Integer outcome_staff_creation =staffHelper.createStaff(requestSpec,responseSpec);
Assert.assertNotNull("Could not create staff",outcome_staff_creation);
SavingsProductHelper savingsProductHelper=new SavingsProductHelper();
String jsonSavingsProduct=savingsProductHelper.build();
Integer outcome_sp_creaction=savingsProductHelper.createSavingsProduct(jsonSavingsProduct,requestSpec,responseSpec);
Assert.assertNotNull("Could not create Savings product",outcome_sp_creaction);
SavingsAccountHelper savingsAccountHelper=new SavingsAccountHelper(requestSpec,responseSpec);
Workbook workbook=savingsAccountHelper.getSavingsWorkbook("dd MMMM yyyy");
//insert dummy data into Savings sheet
Sheet savingsSheet = workbook.getSheet(TemplatePopulateImportConstants.SAVINGS_ACCOUNTS_SHEET_NAME);
Row firstSavingsRow=savingsSheet.getRow(1);
Sheet officeSheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
firstSavingsRow.createCell(SavingsConstants.OFFICE_NAME_COL).setCellValue(officeSheet.getRow(1).getCell(1).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.SAVINGS_TYPE_COL).setCellValue("Individual");
firstSavingsRow.createCell(SavingsConstants.CLIENT_NAME_COL).setCellValue(savingsSheet.getRow(1).getCell(SavingsConstants.LOOKUP_CLIENT_NAME_COL).getStringCellValue());
Sheet savingsProductSheet=workbook.getSheet(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME);
firstSavingsRow.createCell(SavingsConstants.PRODUCT_COL).setCellValue(savingsProductSheet.getRow(1).getCell(1).getStringCellValue());
Sheet staffSheet=workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
firstSavingsRow.createCell(SavingsConstants.FIELD_OFFICER_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(1).getStringCellValue());
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd MMMM yyyy");
Date date=simpleDateFormat.parse("13 May 2017");
firstSavingsRow.createCell(SavingsConstants.SUBMITTED_ON_DATE_COL).setCellValue(date);
firstSavingsRow.createCell(SavingsConstants.APPROVED_DATE_COL).setCellValue(date);
firstSavingsRow.createCell(SavingsConstants.ACTIVATION_DATE_COL).setCellValue(date);
firstSavingsRow.createCell(SavingsConstants.CURRENCY_COL).setCellValue(savingsProductSheet.getRow(1).getCell(10).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.DECIMAL_PLACES_COL).setCellValue(savingsProductSheet.getRow(1).getCell(11).getNumericCellValue());
firstSavingsRow.createCell(SavingsConstants.IN_MULTIPLES_OF_COL).setCellValue(savingsProductSheet.getRow(1).getCell(12).getNumericCellValue());
firstSavingsRow.createCell(SavingsConstants.NOMINAL_ANNUAL_INTEREST_RATE_COL).setCellValue(savingsProductSheet.getRow(1).getCell(2).getNumericCellValue());
firstSavingsRow.createCell(SavingsConstants.INTEREST_COMPOUNDING_PERIOD_COL).setCellValue(savingsProductSheet.getRow(1).getCell(3).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.INTEREST_POSTING_PERIOD_COL).setCellValue(savingsProductSheet.getRow(1).getCell(4).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.INTEREST_CALCULATION_COL).setCellValue(savingsProductSheet.getRow(1).getCell(5).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.INTEREST_CALCULATION_DAYS_IN_YEAR_COL).setCellValue(savingsProductSheet.getRow(1).getCell(6).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.MIN_OPENING_BALANCE_COL).setCellValue(1000.0);
firstSavingsRow.createCell(SavingsConstants.LOCKIN_PERIOD_COL).setCellValue(1);
firstSavingsRow.createCell(SavingsConstants.LOCKIN_PERIOD_FREQUENCY_COL).setCellValue("Weeks");
firstSavingsRow.createCell(SavingsConstants.APPLY_WITHDRAWAL_FEE_FOR_TRANSFERS).setCellValue("False");
firstSavingsRow.createCell(SavingsConstants.ALLOW_OVER_DRAFT_COL).setCellValue("False");
firstSavingsRow.createCell(SavingsConstants.OVER_DRAFT_LIMIT_COL).setCellValue(savingsProductSheet.getRow(1).getCell(15).getNumericCellValue());
String currentdirectory = new File("").getAbsolutePath();
File directory=new File(currentdirectory+File.separator+"src"+File.separator+"integrationTest"+File.separator+
"resources"+File.separator+"bulkimport"+File.separator+"importhandler"+File.separator+"savings") ;
if (!directory.exists())
directory.mkdirs();
File file= new File(directory+File.separator+"Savings.xls");
OutputStream outputStream=new FileOutputStream(file);
workbook.write(outputStream);
outputStream.close();
String importDocumentId=savingsAccountHelper.importSavingsTemplate(file);
file.delete();
Assert.assertNotNull(importDocumentId);
//Wait for the creation of output excel
Thread.sleep(10000);
//check status column of output excel
String location=savingsAccountHelper.getOutputTemplateLocation(importDocumentId);
FileInputStream fileInputStream = new FileInputStream(location);
Workbook Outputworkbook=new HSSFWorkbook(fileInputStream);
Sheet OutputSavingsSheet = Outputworkbook.getSheet(TemplatePopulateImportConstants.SAVINGS_ACCOUNTS_SHEET_NAME);
Row row= OutputSavingsSheet.getRow(1);
Assert.assertEquals("Imported",row.getCell(SavingsConstants.STATUS_COL).getStringCellValue());
}
}
@@ -0,0 +1,83 @@
/**
* 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.bulkimport.populator.client;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
public class ClientEntityWorkbookPopulatorTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
public void setup(){
Utils.initializeRESTAssured();
this.requestSpec=new RequestSpecBuilder().build();
this.requestSpec
.header("Authorization",
"Basic "
+ Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200)
.build();
}
@Test
public void testClientEntityWorkbookPopulate() throws IOException {
//in order to populate helper sheets
StaffHelper staffHelper=new StaffHelper();
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
Integer outcome_staff_creation =staffHelper.createStaff(requestSpec,responseSpec);
Assert.assertNotNull("Could not create staff",outcome_staff_creation);
//in order to populate helper sheets
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Integer outcome_office_creation=officeHelper.createOffice("02 May 2000");
Assert.assertNotNull("Could not create office" ,outcome_office_creation);
ClientHelper clientHelper=new ClientHelper(requestSpec,responseSpec);
Workbook workbook=clientHelper.getClientEntityWorkbook(GlobalEntityType.CLIENTS_ENTTTY,"dd MMMM yyyy");
Sheet officeSheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
Row firstOfficeRow=officeSheet.getRow(1);
Assert.assertNotNull("No offices found for given OfficeId ",firstOfficeRow.getCell(1));
Sheet staffSheet=workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
Row firstStaffRow=staffSheet.getRow(1);
Assert.assertNotNull("No staff found for given staffId",firstStaffRow.getCell(1));
}
}
@@ -0,0 +1,126 @@
/**
* 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.bulkimport.populator.loan;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.integrationtests.common.*;
import org.apache.fineract.integrationtests.common.funds.FundsResourceHandler;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
public class LoanWorkbookPopulatorTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
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();
}
@Test
public void testLoanWorkbookPopulate() throws IOException {
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
//in order to populate helper sheets
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Integer outcome_office_creation=officeHelper.createOffice("02 May 2000");
Assert.assertNotNull("Could not create office" ,outcome_office_creation);
//in order to populate helper sheets
ClientHelper clientHelper=new ClientHelper(requestSpec,responseSpec);
Integer outcome_client_creation=clientHelper.createClient(requestSpec,responseSpec);
Assert.assertNotNull("Could not create client" ,outcome_client_creation);
//in order to populate helper sheets
GroupHelper groupHelper=new GroupHelper(requestSpec,responseSpec);
Integer outcome_group_creation=groupHelper.createGroup(requestSpec,responseSpec,true);
Assert.assertNotNull("Could not create group" ,outcome_group_creation);
//in order to populate helper sheets
StaffHelper staffHelper=new StaffHelper();
Integer outcome_staff_creation =staffHelper.createStaff(requestSpec,responseSpec);
Assert.assertNotNull("Could not create staff",outcome_staff_creation);
LoanTransactionHelper loanTransactionHelper=new LoanTransactionHelper(requestSpec,responseSpec);
LoanProductTestBuilder loanProductTestBuilder=new LoanProductTestBuilder();
String jsonLoanProduct=loanProductTestBuilder.build(null);
Integer outcome_lp_creaion=loanTransactionHelper.getLoanProductId(jsonLoanProduct);
Assert.assertNotNull("Could not create Loan Product" ,outcome_lp_creaion);
FundsResourceHandler fundsResourceHandler=new FundsResourceHandler();
String jsonFund="{\n" +
"\t\"name\": \""+Utils.randomNameGenerator("Fund_Name",9)+"\"\n" +
"}";
Integer outcome_fund_creation=fundsResourceHandler.createFund(jsonFund,requestSpec,responseSpec);
Assert.assertNotNull("Could not create Fund" ,outcome_fund_creation);
PaymentTypeHelper paymentTypeHelper=new PaymentTypeHelper();
String name = PaymentTypeHelper.randomNameGenerator("P_T", 5);
String description = PaymentTypeHelper.randomNameGenerator("PT_Desc", 15);
Boolean isCashPayment = true;
Integer position = 1;
Integer outcome_payment_creation= paymentTypeHelper.createPaymentType(requestSpec, responseSpec,name,description,isCashPayment,position);
Assert.assertNotNull("Could not create payment type" ,outcome_payment_creation);
Workbook workbook=loanTransactionHelper.getLoanWorkbook("dd MMMM yyyy");
Sheet officeSheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
Row firstOfficeRow=officeSheet.getRow(1);
Assert.assertNotNull("No offices found ",firstOfficeRow.getCell(1));
Sheet clientSheet=workbook.getSheet(TemplatePopulateImportConstants.CLIENT_SHEET_NAME);
Row firstClientRow=clientSheet.getRow(1);
Assert.assertNotNull("No clients found ",firstClientRow.getCell(1));
Sheet groupSheet=workbook.getSheet(TemplatePopulateImportConstants.GROUP_SHEET_NAME);
Row firstGroupRow=groupSheet.getRow(1);
Assert.assertNotNull("No groups found ",firstGroupRow.getCell(1));
Sheet staffSheet=workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
Row firstStaffRow=staffSheet.getRow(1);
Assert.assertNotNull("No staff found ",firstStaffRow.getCell(1));
Sheet productSheet=workbook.getSheet(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME);
Row firstProductRow=productSheet.getRow(1);
Assert.assertNotNull("No products found ",firstProductRow.getCell(1));
Sheet extrasSheet=workbook.getSheet(TemplatePopulateImportConstants.EXTRAS_SHEET_NAME);
Row firstExtrasRow=extrasSheet.getRow(1);
Assert.assertNotNull("No Extras found ",firstExtrasRow.getCell(1));
}
}
@@ -0,0 +1,64 @@
/**
* 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.bulkimport.populator.office;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.OfficeConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class OfficeWorkBookPopulatorTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
public void setup(){
Utils.initializeRESTAssured();
this.requestSpec=new RequestSpecBuilder().build();
this.requestSpec
.header("Authorization",
"Basic "
+ Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200)
.build();
}
@Test
public void testOfficeWorkbookPopulate() throws IOException {
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Workbook workbook=officeHelper.getOfficeWorkBook("dd MMMM yyyy");
Sheet sheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
Row firstRow= sheet.getRow(1);
Assert.assertNotNull("No parent offices found",firstRow.getCell(OfficeConstants.LOOKUP_OFFICE_COL).getStringCellValue());
Assert.assertEquals(1,firstRow.getCell(OfficeConstants.LOOKUP_OFFICE_ID_COL).getNumericCellValue(),0.0);
}
}
@@ -0,0 +1,109 @@
/**
* 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.bulkimport.populator.savings;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GroupHelper;
import org.apache.fineract.integrationtests.common.OfficeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
public class SavingsWorkbookPopulateTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@Before
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();
}
@Test
public void testSavingsWorkbookPopulate() throws IOException {
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
//in order to populate helper sheets
OfficeHelper officeHelper=new OfficeHelper(requestSpec,responseSpec);
Integer outcome_office_creation=officeHelper.createOffice("02 May 2000");
Assert.assertNotNull("Could not create office" ,outcome_office_creation);
//in order to populate helper sheets
ClientHelper clientHelper=new ClientHelper(requestSpec,responseSpec);
Integer outcome_client_creation=clientHelper.createClient(requestSpec,responseSpec);
Assert.assertNotNull("Could not create client" ,outcome_client_creation);
//in order to populate helper sheets
GroupHelper groupHelper=new GroupHelper(requestSpec,responseSpec);
Integer outcome_group_creation=groupHelper.createGroup(requestSpec,responseSpec,true);
Assert.assertNotNull("Could not create group" ,outcome_group_creation);
//in order to populate helper sheets
StaffHelper staffHelper=new StaffHelper();
Integer outcome_staff_creation =staffHelper.createStaff(requestSpec,responseSpec);
Assert.assertNotNull("Could not create staff",outcome_staff_creation);
SavingsProductHelper savingsProductHelper=new SavingsProductHelper();
String jsonSavingsProduct=savingsProductHelper.build();
Integer outcome_sp_creaction=savingsProductHelper.createSavingsProduct(jsonSavingsProduct,requestSpec,responseSpec);
Assert.assertNotNull("Could not create Savings product",outcome_sp_creaction);
SavingsAccountHelper savingsAccountHelper=new SavingsAccountHelper(requestSpec,responseSpec);
Workbook workbook=savingsAccountHelper.getSavingsWorkbook("dd MMMM yyyy");
Sheet officeSheet=workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME);
Row firstOfficeRow=officeSheet.getRow(1);
Assert.assertNotNull("No offices found ",firstOfficeRow.getCell(1));
Sheet clientSheet=workbook.getSheet(TemplatePopulateImportConstants.CLIENT_SHEET_NAME);
Row firstClientRow=clientSheet.getRow(1);
Assert.assertNotNull("No clients found ",firstClientRow.getCell(1));
Sheet groupSheet=workbook.getSheet(TemplatePopulateImportConstants.GROUP_SHEET_NAME);
Row firstGroupRow=groupSheet.getRow(1);
Assert.assertNotNull("No groups found ",firstGroupRow.getCell(1));
Sheet staffSheet=workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
Row firstStaffRow=staffSheet.getRow(1);
Assert.assertNotNull("No staff found ",firstStaffRow.getCell(1));
Sheet productSheet=workbook.getSheet(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME);
Row firstProductRow=productSheet.getRow(1);
Assert.assertNotNull("No products found ",firstProductRow.getCell(1));
}
}
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.common;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
@@ -58,6 +59,16 @@ public class BatchHelper {
return new Gson().toJson(batchRequests);
}
/**
* Returns a Map from Json String
*
* @param jsonBody
* @return Map
*/
public static Map generateMapFromJsonString(final String jsonString) {
return new Gson().fromJson(jsonString, Map.class);
}
/**
* Returns the converted string response into JSON.
*
@@ -155,6 +166,38 @@ public class BatchHelper {
return br;
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.CreateClientCommandStrategy}
* Request as one of the request in Batch.
*
* @param reqId
* @param externalId
* @return BatchRequest
*/
public static BatchRequest createActiveClientRequest(final Long requestId, final String externalId) {
final BatchRequest br = new BatchRequest();
br.setRequestId(requestId);
br.setRelativeUrl("clients");
br.setMethod("POST");
final String extId;
if (externalId.equals("")) {
extId = "ext" + String.valueOf((10000 * Math.random())) + String.valueOf((10000 * Math.random()));
} else {
extId = externalId;
}
final String body = "{ \"officeId\": 1, \"firstname\": \"Petra\", \"lastname\": \"Yton\"," + "\"externalId\": \"" + externalId
+ "\", \"dateFormat\": \"dd MMMM yyyy\", \"locale\": \"en\"," + "\"active\": true, \"activationDate\": \"04 March 2010\", \"submittedOnDate\": \"04 March 2010\"}";
br.setBody(body);
return br;
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.UpdateClientCommandStrategy}
@@ -197,7 +240,7 @@ public class BatchHelper {
br.setReference(reference);
final String body = "{\"dateFormat\": \"dd MMMM yyyy\", \"locale\": \"en_GB\", \"clientId\": \"$.clientId\"," + "\"productId\": "
+ productId + ", \"principal\": \"10,000.00\", \"loanTermFrequency\": 12,"
+ productId + ", \"principal\": \"10,000.00\", \"loanTermFrequency\": 10,"
+ "\"loanTermFrequencyType\": 2, \"loanType\": \"individual\", \"numberOfRepayments\": 10,"
+ "\"repaymentEvery\": 1, \"repaymentFrequencyType\": 2, \"interestRatePerPeriod\": 10,"
+ "\"amortizationType\": 1, \"interestType\": 0, \"interestCalculationPeriodType\": 1,"
@@ -347,6 +390,29 @@ public class BatchHelper {
return br;
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy}
* Request with given requestId.
*
*
* @param requestId
* @param reference
* @return BatchRequest
*/
public static BatchRequest repayLoanRequest(final Long requestId, final Long reference) {
final BatchRequest br = new BatchRequest();
br.setRequestId(requestId);
br.setReference(reference);
br.setRelativeUrl("loans/$.loanId/transactions?command=repayment");
br.setMethod("POST");
br.setBody("{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", " +
"\"transactionDate\": \"15 September 2013\", \"transactionAmount\": 500}");
return br;
}
/**
* Checks that the client with given externalId is not created on the
@@ -20,15 +20,25 @@ package org.apache.fineract.integrationtests.common;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.integrationtests.common.system.CodeHelper;
import com.google.gson.Gson;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
public class ClientHelper {
@@ -591,4 +601,27 @@ public class ClientHelper {
return Utils.performServerGet(requestSpec, responseSpec, CHARGES_URL, "reversed");
}
public Workbook getClientEntityWorkbook(GlobalEntityType clientsEntity, String dateFormat) throws IOException {
requestSpec.header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel");
byte [] byteArray=Utils.performGetBinaryResponse(requestSpec,responseSpec,CLIENT_URL+"/downloadtemplate"+"?"+
Utils.TENANT_IDENTIFIER+"&legalFormType="+clientsEntity+"&dateFormat="+dateFormat);
InputStream inputStream= new ByteArrayInputStream(byteArray);
Workbook workbook=new HSSFWorkbook(inputStream);
return workbook;
}
public String getOutputTemplateLocation(final String importDocumentId){
requestSpec.header(HttpHeaders.CONTENT_TYPE,MediaType.TEXT_PLAIN);
return Utils.performServerOutputTemplateLocationGet(requestSpec,responseSpec,"/fineract-provider/api/v1/imports/getOutputTemplateLocation"+"?"
+Utils.TENANT_IDENTIFIER,importDocumentId);
}
public String importClientEntityTemplate(File file){
String locale="en";
String dateFormat="dd MMMM yyyy";
String legalFormType=GlobalEntityType.CLIENTS_ENTTTY.toString();
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA);
return Utils.performServerTemplatePost(requestSpec,responseSpec,CLIENT_URL+"/uploadtemplate"+"?"+Utils.TENANT_IDENTIFIER,
legalFormType,file,locale,dateFormat);
}
}
@@ -59,7 +59,7 @@ public class HolidayHelper {
map.put("fromDate", "01 April 2013");
map.put("toDate", "01 April 2013");
map.put("repaymentsRescheduledTo", "08 April 2013");
map.put("reschedulingType", 2);
String HolidayCreateJson = new Gson().toJson(map);
System.out.println(HolidayCreateJson);
return HolidayCreateJson;
@@ -0,0 +1,42 @@
/**
* 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 com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
public class NotificationHelper {
private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec;
private static final String NOTIFICATION_API_URL = "/fineract-provider/api/v1/notifications?" + Utils.TENANT_IDENTIFIER;
public NotificationHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
this.responseSpec = responseSpec;
}
public static Object getNotifications(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String jsonReturn) {
final String GET_NOTIFICATIONS_URL = NOTIFICATION_API_URL;
System.out.println("-----------------------------GET NOTIFICATIONS-----------------------------------");
return Utils.performServerGet(requestSpec, responseSpec, GET_NOTIFICATIONS_URL, "");
}
}
@@ -18,6 +18,10 @@
*/
package org.apache.fineract.integrationtests.common;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import com.google.common.reflect.TypeToken;
@@ -25,6 +29,12 @@ import com.google.gson.Gson;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
public class OfficeHelper {
private static final String OFFICE_URL = "/fineract-provider/api/v1/offices";
@@ -77,4 +87,27 @@ public class OfficeHelper {
System.out.println("map : " + map);
return new Gson().toJson(map);
}
public String importOfficeTemplate(File file){
String locale="en";
String dateFormat="dd MMMM yyyy";
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA);
return Utils.performServerTemplatePost(requestSpec,responseSpec,OFFICE_URL+"/uploadtemplate"+"?"+Utils.TENANT_IDENTIFIER,
null,file,locale,dateFormat);
}
public String getOutputTemplateLocation(final String importDocumentId){
requestSpec.header(HttpHeaders.CONTENT_TYPE,MediaType.TEXT_PLAIN);
return Utils.performServerOutputTemplateLocationGet(requestSpec,responseSpec,"/fineract-provider/api/v1/imports/getOutputTemplateLocation"+"?"
+Utils.TENANT_IDENTIFIER,importDocumentId);
}
public Workbook getOfficeWorkBook(final String dateFormat) throws IOException {
requestSpec.header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel");
byte[] byteArray=Utils.performGetBinaryResponse(requestSpec,responseSpec,OFFICE_URL+"/downloadtemplate"+"?"+
Utils.TENANT_IDENTIFIER+"&dateFormat="+dateFormat);
InputStream inputStream= new ByteArrayInputStream(byteArray);
Workbook workbook=new HSSFWorkbook(inputStream);
return workbook;
}
}
@@ -24,13 +24,11 @@ import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.File;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Random;
import java.util.TimeZone;
import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.http.conn.HttpHostConnectException;
@@ -41,7 +39,6 @@ import com.jayway.restassured.RestAssured;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
/**
* Util for RestAssured tests. This class here in src/integrationTest is
* copy/pasted to src/test; please keep them in sync.
@@ -49,7 +46,9 @@ import com.jayway.restassured.specification.ResponseSpecification;
@SuppressWarnings("unchecked")
public class Utils {
public static final String TENANT_IDENTIFIER = "tenantIdentifier=default";
public static final String TENANT_PARAM_NAME = "tenantIdentifier";
public static final String DEFAULT_TENANT = "default";
public static final String TENANT_IDENTIFIER = TENANT_PARAM_NAME + '=' + DEFAULT_TENANT;
public static final String TENANT_TIME_ZONE = "Asia/Kolkata";
@@ -116,6 +115,13 @@ public class Utils {
return (T) from(json).get(jsonAttributeToGetBack);
}
public static <T> T performServerDelete(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String deleteURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when()
.delete(deleteURL).andReturn().asString();
return (T) (jsonAttributeToGetBack == null ? json : from(json).get(jsonAttributeToGetBack));
}
public static String convertDateToURLFormat(final String dateToBeConvert) {
final SimpleDateFormat oldFormat = new SimpleDateFormat("dd MMMMMM yyyy", Locale.US);
final SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd");
@@ -145,6 +151,16 @@ public class Utils {
public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) {
return randomStringGenerator(prefix, lenOfRandomSuffix);
}
public static Long randomNumberGenerator(final int expectedLength){
final String source="1234567890";
final int lengthofSource=source.length();
final Random random=new Random();
StringBuilder stringBuilder=new StringBuilder(expectedLength);
for (int i = 0; i < expectedLength; i++) {
stringBuilder.append(source.charAt(random.nextInt(lengthofSource)));
}
return Long.parseLong(stringBuilder.toString());
}
public static String convertDateToURLFormat(final Calendar dateToBeConvert) {
DateFormat dateFormat = new SimpleDateFormat("dd MMMMMM yyyy");
@@ -165,4 +181,27 @@ public class Utils {
return TimeZone.getTimeZone(TENANT_TIME_ZONE);
}
public static String performServerTemplatePost(final RequestSpecification requestSpec,final ResponseSpecification responseSpec,
final String postURL,final String legalFormType,final File file,final String locale,final String dateFormat) {
final String importDocumentId=given().spec(requestSpec)
.queryParam("legalFormType",legalFormType)
.multiPart("file",file)
.formParam("locale",locale)
.formParam("dateFormat",dateFormat)
.expect().spec(responseSpec).
log().ifError().when().post(postURL)
.andReturn().asString();
return importDocumentId;
}
public static String performServerOutputTemplateLocationGet(final RequestSpecification requestSpec,final ResponseSpecification responseSpec,
final String getURL,final String importDocumentId){
final String templateLocation=given().spec(requestSpec).
queryParam("importDocumentId",importDocumentId)
.expect().spec(responseSpec)
.log().ifError().when().get(getURL)
.andReturn().asString();
return templateLocation.substring(1,templateLocation.length()-1);
}
}
@@ -27,6 +27,7 @@ import org.apache.fineract.integrationtests.common.Utils;
import com.google.gson.Gson;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ChargesHelper {
@@ -87,24 +88,20 @@ public class ChargesHelper {
}
public static String getSavingsActivationFeeJSON() {
final HashMap<String, Object> map = populateDefaultsForSavings();
map.put("chargeTimeType", CHARGE_SAVINGS_ACTIVATION_FEE);
String chargesCreateJson = new Gson().toJson(map);
System.out.println(chargesCreateJson);
return chargesCreateJson;
return getSavingsJSON(amount, currencyCode, ChargeTimeType.SAVINGS_ACTIVATION);
}
public static String getSavingsNoActivityFeeJSON() {
final HashMap<String, Object> map = populateDefaultsForSavings();
map.put("chargeTimeType", CHARGE_SAVINGS_NO_ACTIVITY_FEE);
String chargesCreateJson = new Gson().toJson(map);
System.out.println(chargesCreateJson);
return chargesCreateJson;
return getSavingsJSON(amount, currencyCode, ChargeTimeType.SAVINGS_NOACTIVITY_FEE);
}
public static String getSavingsWithdrawalFeeJSON() {
final HashMap<String, Object> map = populateDefaultsForSavings();
map.put("chargeTimeType", CHARGE_WITHDRAWAL_FEE);
return getSavingsJSON(amount, currencyCode, ChargeTimeType.WITHDRAWAL_FEE);
}
public static String getSavingsJSON(String amount, String currencyCode, ChargeTimeType timeType) {
final HashMap<String, Object> map = populateDefaultsForSavings(amount.toString(), currencyCode);
map.put("chargeTimeType", timeType.getValue());
String chargesCreateJson = new Gson().toJson(map);
System.out.println(chargesCreateJson);
return chargesCreateJson;
@@ -147,12 +144,16 @@ public class ChargesHelper {
}
public static HashMap<String, Object> populateDefaultsForSavings() {
return populateDefaultsForSavings(amount, currencyCode);
}
public static HashMap<String, Object> populateDefaultsForSavings(String amount, String currencyCode) {
final HashMap<String, Object> map = new HashMap<>();
map.put("active", ChargesHelper.active);
map.put("amount", ChargesHelper.amount);
map.put("amount", amount);
map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SAVINGS);
map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT);
map.put("currencyCode", ChargesHelper.currencyCode);
map.put("currencyCode", currencyCode);
map.put("locale", CommonConstants.locale);
map.put("monthDayFormat", ChargesHelper.monthDayFormat);
map.put("name", Utils.randomNameGenerator("Charge_Savings_", 6));
@@ -21,18 +21,28 @@ package org.apache.fineract.integrationtests.common.loans;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.joda.time.LocalDate;
import com.google.gson.Gson;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class LoanTransactionHelper {
@@ -41,6 +51,7 @@ public class LoanTransactionHelper {
private static final String CREATE_LOAN_PRODUCT_URL = "/fineract-provider/api/v1/loanproducts?" + Utils.TENANT_IDENTIFIER;
private static final String APPLY_LOAN_URL = "/fineract-provider/api/v1/loans?" + Utils.TENANT_IDENTIFIER;
private static final String LOAN_ACCOUNT_URL="/fineract-provider/api/v1/loans";
private static final String APPROVE_LOAN_COMMAND = "approve";
private static final String UNDO_APPROVAL_LOAN_COMMAND = "undoApproval";
private static final String DISBURSE_LOAN_COMMAND = "disburse";
@@ -694,4 +705,29 @@ public class LoanTransactionHelper {
datatablesListMap.add(datatableMap);
return datatablesListMap;
}
public Workbook getLoanWorkbook(String dateFormat) throws IOException {
requestSpec.header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel");
byte[] byteArray=Utils.performGetBinaryResponse(requestSpec,responseSpec,LOAN_ACCOUNT_URL+"/downloadtemplate"+"?"+
Utils.TENANT_IDENTIFIER+"&dateFormat="+dateFormat);
InputStream inputStream= new ByteArrayInputStream(byteArray);
Workbook workbook=new HSSFWorkbook(inputStream);
return workbook;
}
public String importLoanTemplate(File file) {
String locale="en";
String dateFormat="dd MMMM yyyy";
String legalFormType= null;
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA);
return Utils.performServerTemplatePost(requestSpec,responseSpec,LOAN_ACCOUNT_URL+"/uploadtemplate"+"?"+Utils.TENANT_IDENTIFIER,
legalFormType,file,locale,dateFormat);
}
public String getOutputTemplateLocation(final String importDocumentId){
requestSpec.header(HttpHeaders.CONTENT_TYPE,MediaType.TEXT_PLAIN);
return Utils.performServerOutputTemplateLocationGet(requestSpec,responseSpec,"/fineract-provider/api/v1/imports/getOutputTemplateLocation"+"?"
+Utils.TENANT_IDENTIFIER,importDocumentId);
}
}
@@ -26,6 +26,7 @@ import java.util.HashMap;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.jayway.restassured.builder.RequestSpecBuilder;
@@ -34,6 +35,7 @@ import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
@Ignore
public class CampaignsTest {
private RequestSpecification requestSpec;
@@ -97,6 +97,9 @@ public class StaffHelper {
map.put("firstname", Utils.randomNameGenerator("michael_", 5));
map.put("lastname", Utils.randomNameGenerator("Doe_", 4));
map.put("isLoanOfficer", true);
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
map.put("joiningDate", "20 September 2011") ;
System.out.println("map : " + map);
return new Gson().toJson(map);
}
@@ -18,6 +18,11 @@
*/
package org.apache.fineract.integrationtests.common.savings;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@@ -27,12 +32,17 @@ import java.util.Locale;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert;
import com.google.gson.Gson;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
@SuppressWarnings({ "rawtypes" })
public class SavingsAccountHelper {
@@ -55,15 +65,26 @@ public class SavingsAccountHelper {
private static final String WITHDRAW_SAVINGS_COMMAND = "withdrawal";
private static final String MODIFY_TRASACTION_COMMAND = "modify";
private static final String UNDO_TRASACTION_COMMAND = "undo";
private static final String BLOCK_SAVINGS_COMMAND = "block";
private static final String UNBLOCK_SAVINGS_COMMAND = "unblock";
private static final String BLOCK_DEBITS_SAVINGS_COMMAND = "blockDebit";
private static final String UNBLOCK_DEBITS_SAVINGS_COMMAND = "unblockDebit";
private static final String BLOCK_CREDITS_SAVINGS_COMMAND = "blockCredit";
private static final String UNBLOCK_CREDITS_SAVINGS_COMMAND = "unblockCredit";
private static final String HOLD_AMOUNT_SAVINGS_COMMAND = "holdAmount";
private static final String RELEASE_AMOUNT_SAVINGS_COMMAND = "releaseAmount";
public static final String CREATED_DATE = "08 January 2013";
public static final String CREATED_DATE_PLUS_ONE = "09 January 2013";
public static final String CREATED_DATE_MINUS_ONE = "07 January 2013";
public static final String TRANSACTION_DATE = "01 March 2013";
public static final String TRANSACTION_DATE_PLUS_ONE = "02 March 2013";
public static final String LAST_TRANSACTION_DATE = "01 March 2013";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final String DATE_TIME_FORMAT = "dd MMMM yyyy HH:mm";
private static final Boolean isBlock = false;
public SavingsAccountHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
@@ -82,9 +103,21 @@ public class SavingsAccountHelper {
}
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
final String submittedOnDate) {
final String submittedOnDate) {
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, null, false, submittedOnDate);
}
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);
}
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
String externalId, boolean withdrawalFeeForTransfers, final String submittedOnDate) {
System.out.println("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withExternalId(externalId) //
.withWithdrawalFeeForTransfers(withdrawalFeeForTransfers) //
.withSubmittedOnDate(submittedOnDate) //
.build(ID.toString(), savingsProductID.toString(), accountType);
return Utils.performServerPost(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER,
@@ -138,20 +171,20 @@ public class SavingsAccountHelper {
System.out.println("--------------------------------- APPROVING SAVINGS APPLICATION ------------------------------------");
final String savingsOperationURL = createSavingsOperationURL(APPROVE_SAVINGS_COMMAND, savingsID);
if (approvalDate == null || approvalDate == "")
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON());
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJsonOnDate(approvalDate));
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON(), isBlock);
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJsonOnDate(approvalDate), isBlock);
}
public HashMap undoApproval(final Integer savingsID) {
System.out.println("--------------------------------- UNDO APPROVING SAVINGS APPLICATION -------------------------------");
final String undoBodyJson = "{'note':'UNDO APPROVAL'}";
return performSavingApplicationActions(createSavingsOperationURL(UNDO_APPROVAL_SAVINGS_COMMAND, savingsID), undoBodyJson);
return performSavingApplicationActions(createSavingsOperationURL(UNDO_APPROVAL_SAVINGS_COMMAND, savingsID), undoBodyJson, isBlock);
}
public HashMap rejectApplication(final Integer savingsID) {
System.out.println("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(REJECT_SAVINGS_COMMAND, savingsID),
getRejectedSavingsAsJSON(CREATED_DATE_PLUS_ONE));
getRejectedSavingsAsJSON(CREATED_DATE_PLUS_ONE), isBlock);
}
public List rejectApplicationWithErrorCode(final Integer savingsId, final String date) {
@@ -163,18 +196,18 @@ public class SavingsAccountHelper {
public HashMap withdrawApplication(final Integer savingsID) {
System.out.println("--------------------------------- Withdraw SAVINGS APPLICATION -------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(WITHDRAWN_BY_CLIENT_SAVINGS_COMMAND, savingsID),
getWithdrawnSavingsAsJSON());
getWithdrawnSavingsAsJSON(), isBlock);
}
public HashMap activateSavings(final Integer savingsID) {
System.out.println("---------------------------------- ACTIVATING SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(ACTIVATE_SAVINGS_COMMAND, savingsID), getActivatedSavingsAsJSON());
return performSavingApplicationActions(createSavingsOperationURL(ACTIVATE_SAVINGS_COMMAND, savingsID), getActivatedSavingsAsJSON(), isBlock);
}
public HashMap closeSavingsAccount(final Integer savingsID, String withdrawBalance) {
System.out.println("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE));
getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE), isBlock);
}
public Object deleteSavingsApplication(final Integer savingsId, final String jsonAttributeToGetBack) {
@@ -227,9 +260,13 @@ public class SavingsAccountHelper {
}
public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate) {
return addChargesForSavings(savingsId, chargeId, addDueDate, BigDecimal.valueOf(100));
}
public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate, BigDecimal amount) {
System.out.println("--------------------------------- ADD CHARGES FOR SAVINGS --------------------------------");
return (Integer) performSavingActions(SAVINGS_ACCOUNT_URL + "/" + savingsId + "/charges?" + Utils.TENANT_IDENTIFIER,
getPeriodChargeRequestJSON(chargeId, addDueDate), CommonConstants.RESPONSE_RESOURCE_ID);
getPeriodChargeRequestJSON(chargeId, addDueDate, amount), CommonConstants.RESPONSE_RESOURCE_ID);
}
public Integer payCharge(final Integer chargeId, final Integer savingsId, String amount, String dueDate) {
@@ -251,6 +288,60 @@ public class SavingsAccountHelper {
return Utils.performServerDelete(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "/" + savingsId + "/charges/"
+ chargeId + "?" + Utils.TENANT_IDENTIFIER, CommonConstants.RESPONSE_RESOURCE_ID);
}
public HashMap blockSavings(final Integer savingsID) {
System.out.println("---------------------------------- BLOCKING SAVINGS ACCOUNT ----------------------------------");
Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(BLOCK_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock);
}
public HashMap unblockSavings(final Integer savingsID) {
System.out.println("---------------------------------- UNBLOCKING SAVINGS ACCOUNT ----------------------------------");
Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock);
}
public HashMap blockDebit(final Integer savingsID) {
System.out.println("---------------------------------- BLOCKING DEBIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(BLOCK_DEBITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock);
}
public HashMap unblockDebit(final Integer savingsID) {
System.out.println("---------------------------------- UNBLOCKING DEBIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_DEBITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock);
}
public HashMap blockCredit(final Integer savingsID) {
System.out.println("---------------------------------- BLOCKING CREDIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(BLOCK_CREDITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock);
}
public HashMap unblockCredit(final Integer savingsID) {
System.out.println("---------------------------------- UNBLOCKING CREDIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_CREDITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock);
}
public Object holdAmountInSavingsAccount(final Integer savingsID, final String amount, String date, String jsonAttributeToGetback) {
System.out.println("--------------------------------- SAVINGS TRANSACTION HOLD AMOUNT--------------------------------");
return performSavingActions(createSavingsTransactionURL(HOLD_AMOUNT_SAVINGS_COMMAND, savingsID),
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
}
public Integer releaseAmount(final Integer savingsId, final Integer transactionId) {
System.out.println("\n--------------------------------- SAVINGS TRANSACTION RELEASE AMOUNT--------------------------------");
return (Integer) performSavingActions(createAdjustTransactionURL(RELEASE_AMOUNT_SAVINGS_COMMAND, savingsId, transactionId),
getSavingsTransactionJSON("1000", LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID);
}
private String getApproveSavingsAsJSON() {
return getApproveSavingsAsJsonOnDate(CREATED_DATE_PLUS_ONE);
@@ -454,12 +545,15 @@ public class SavingsAccountHelper {
return response;
}
private HashMap performSavingApplicationActions(final String postURLForSavingsTransaction, final String jsonToBeSent) {
private HashMap performSavingApplicationActions(final String postURLForSavingsTransaction, final String jsonToBeSent, 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 (isBlock != null && isBlock) {
status = (HashMap) response.get("subStatus");
}
}
return status;
}
@@ -484,10 +578,10 @@ public class SavingsAccountHelper {
getCloseAccountPostInterestJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
}
private String getPeriodChargeRequestJSON(Integer chargeId, boolean addDueDate) {
private String getPeriodChargeRequestJSON(Integer chargeId, boolean addDueDate, BigDecimal amount) {
final HashMap<String, Object> map = new HashMap<>();
map.put("chargeId", chargeId);
map.put("amount", 100);
map.put("amount", amount);
map.put("feeOnMonthDay", "15 January");
map.put("locale", CommonConstants.locale);
map.put("monthDayFormat", "dd MMMM");
@@ -510,7 +604,7 @@ public class SavingsAccountHelper {
public HashMap activateSavingsAccount(Integer savingsID, String activationDate) {
return performSavingApplicationActions(createSavingsOperationURL(ACTIVATE_SAVINGS_COMMAND, savingsID),
getAccountActivationJSON(activationDate));
getAccountActivationJSON(activationDate), isBlock);
}
public Object inactivateCharge(final Integer chargeId, final Integer savingsId, final String jsonAttributeToGetBack) {
@@ -574,4 +668,28 @@ public class SavingsAccountHelper {
datatablesListMap.add(datatableMap);
return datatablesListMap;
}
public Workbook getSavingsWorkbook(String dateFormat) throws IOException {
requestSpec.header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel");
byte[] byteArray=Utils.performGetBinaryResponse(requestSpec,responseSpec,SAVINGS_ACCOUNT_URL+"/downloadtemplate"+"?"+
Utils.TENANT_IDENTIFIER+"&dateFormat="+dateFormat);
InputStream inputStream= new ByteArrayInputStream(byteArray);
Workbook workbook=new HSSFWorkbook(inputStream);
return workbook;
}
public String importSavingsTemplate(File file) {
String locale="en";
String dateFormat="dd MMMM yyyy";
String legalFormType= null;
requestSpec.header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA);
return Utils.performServerTemplatePost(requestSpec,responseSpec,SAVINGS_ACCOUNT_URL+"/uploadtemplate"+"?"+Utils.TENANT_IDENTIFIER,
legalFormType,file,locale,dateFormat);
}
public String getOutputTemplateLocation(final String importDocumentId){
requestSpec.header(HttpHeaders.CONTENT_TYPE,MediaType.TEXT_PLAIN);
return Utils.performServerOutputTemplateLocationGet(requestSpec,responseSpec,"/fineract-provider/api/v1/imports/getOutputTemplateLocation"+"?"
+Utils.TENANT_IDENTIFIER,importDocumentId);
}
}
@@ -29,6 +29,9 @@ public class SavingsApplicationTestBuilder {
private String submittedOnDate = "";
private String externalId;
private boolean withdrawalFeeForTransfers;
private HashMap<String, String> addParams = null;
private List<HashMap<String, Object>> datatables = null;
@@ -45,6 +48,8 @@ public class SavingsApplicationTestBuilder {
map.put("productId", savingsProductId);
map.put("locale", LOCALE);
map.put("submittedOnDate", this.submittedOnDate);
map.put("externalId", this.externalId);
map.put("withdrawalFeeForTransfers", this.withdrawalFeeForTransfers);
if (addParams != null && addParams.size() > 0) {
map.putAll(addParams);
}
@@ -61,6 +66,16 @@ public class SavingsApplicationTestBuilder {
return this;
}
public SavingsApplicationTestBuilder withExternalId(final String externalId) {
this.externalId = externalId;
return this;
}
public SavingsApplicationTestBuilder withWithdrawalFeeForTransfers(boolean withdrawalFeeForTransfers) {
this.withdrawalFeeForTransfers = withdrawalFeeForTransfers;
return this;
}
public SavingsApplicationTestBuilder withParams(HashMap<String, String> params) {
this.addParams = params;
return this;
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.common.savings;
import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
@@ -60,7 +61,7 @@ public class SavingsProductHelper {
private String nameOfSavingsProduct = Utils.randomNameGenerator("SAVINGS_PRODUCT_", 6);
private String shortName = Utils.randomNameGenerator("", 4);
private String description = Utils.randomNameGenerator("", 20);
private String interestCompoundingPeriodType = "2";
private String interestCompoundingPeriodType = "4";
private String interestPostingPeriodType = "4";
private String interestCalculationType = INTEREST_CALCULATION_USING_DAILY_BALANCE;
private String nominalAnnualInterestRate = "10.0";
@@ -78,7 +79,7 @@ public class SavingsProductHelper {
private String lockinPeriodFrequency = "0";
private String withdrawalFeeForTransfers = "true";
private String lockingPeriodFrequencyType = DAYS;
private final String currencyCode = USD;
private String currencyCode = USD;
private final String interestCalculationDaysInYearType = DAYS_365;
private Account[] accountList = null;
private String minBalanceForInterestCalculation = null;
@@ -231,6 +232,16 @@ public class SavingsProductHelper {
return this;
}
public SavingsProductHelper withCurrencyCode(String currency) {
this.currencyCode = currency;
return this;
}
public SavingsProductHelper withNominalAnnualInterestRate(BigDecimal interestRate) {
this.nominalAnnualInterestRate = interestRate.toString();
return this;
}
private Map<String, String> getAccountMappingForCashBased() {
final Map<String, String> map = new HashMap<>();
if (accountList != null) {
@@ -113,5 +113,30 @@ public class SavingsStatusChecker {
assertTrue("UNEXPECTED SAVINGS ACCOUNT SUB STATUS", getStatus(savingsStatusHashMap, "none"));
System.out.println("Savings Application Sub Status:" + savingsStatusHashMap + "\n");
}
public static void verifySavingsSubStatusblock(HashMap savingsStatusHashMap) {
System.out.println(
"\n-------------------------------------- VERIFYING SAVINGS ACCOUNT IS BLOCKED ------------------------------------");
assertTrue("block", getStatus(savingsStatusHashMap, "block"));
System.out.println("Savings Application Sub Status:" + savingsStatusHashMap + "\n");
}
public static void verifySavingsSubStatusIsNone(HashMap savingsStatusHashMap) {
System.out.println("\n------------------------- VERIFYING SAVINGS ACCOUNT IS NOT BLOCKED FOR ANY TYPE OF TRANSACTIONS ---------------------------");
assertTrue("none", getStatus(savingsStatusHashMap, "none"));
System.out.println("Savings Application Sub Status:" + savingsStatusHashMap + "\n");
}
public static void verifySavingsSubStatusIsDebitBlocked(HashMap savingsStatusHashMap) {
System.out.println("\n--------------------- VERIFYING SAVINGS APPLICATION IS BLOCKED FOR DEBIT TRANSACTIONS ---------------------");
assertTrue("status is blockDebit", getStatus(savingsStatusHashMap, "blockDebit"));
System.out.println("Savings Application Sub Status:" + savingsStatusHashMap + "\n");
}
public static void verifySavingsSubStatusIsCreditBlocked(HashMap savingsStatusHashMap) {
System.out.println("\n---------------------- VERIFYING SAVINGS APPLICATION IS BLOCKED FOR CREDIT TRANSACTIONS ---------------");
assertTrue("blockCredit ", getStatus(savingsStatusHashMap, "blockCredit"));
System.out.println("Savings Application Sub Status:" + savingsStatusHashMap + "\n");
}
}
@@ -34,6 +34,7 @@ import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.google.gson.Gson;
@@ -210,6 +211,7 @@ public class ShareAccountIntegrationTests {
Assert.assertEquals("25", String.valueOf(summaryMap.get("totalApprovedShares")));
Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares")));
}
@Test
@SuppressWarnings("unchecked")
public void rejectShareAccount() {
@@ -267,7 +269,7 @@ public class ShareAccountIntegrationTests {
String transactionType = (String) transactionTypeMap.get("code");
if (transactionType.equals("purchasedSharesType.purchased")) {
Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares")));
Assert.assertEquals("52.0", String.valueOf(transaction.get("amount")));
Assert.assertEquals("50.0", String.valueOf(transaction.get("amount")));
Assert.assertEquals("50.0", String.valueOf(transaction.get("amountPaid")));
Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount")));
Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice")));
@@ -0,0 +1,356 @@
/**
* 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.interoperation;
import com.google.gson.Gson;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.interoperation.domain.InteropAmountType;
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
import org.apache.fineract.interoperation.domain.InteropInitiatorType;
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
import org.apache.fineract.interoperation.domain.InteropTransactionScenario;
import org.apache.fineract.interoperation.domain.InteropTransferActionType;
import org.apache.fineract.interoperation.util.InteropUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.UUID;
@SuppressWarnings({ "rawtypes" })
public class InteropHelper {
private final static Logger log = LoggerFactory.getLogger(InteropTest.class);
private static final String BASE_URL = "/fineract-provider/api/v1/interoperation";
private static final String HEALTH_URL = BASE_URL + "/health";
private static final String PARTIES_URL = BASE_URL + "/parties";
private static final String TRANSACTIONS_URL = BASE_URL + "/transactions";
private static final String REQUESTS_URL_PARAM = "requests";
private static final String REQUESTS_URL = BASE_URL + '/' + REQUESTS_URL_PARAM;
private static final String QUOTES_URL_PARAM = "quotes";
private static final String QUOTES_URL = BASE_URL + '/' + QUOTES_URL_PARAM;
private static final String TRANSFERS_URL_PARAM = "transfers";
private static final String TRANSFERS_URL = BASE_URL + '/' + TRANSFERS_URL_PARAM;
private static final String PARAM_TRANSFER_ACTION = "action";
static final String PARAM_ACTION_STATE = "state";
static final String PARAM_ACCOUNT_BALANCE = "accountBalance";
private static final String NOTE = "Integration test";
private final RequestSpecification requestSpec;
private ResponseSpecification responseSpec;
private final String tenantId;
private final String accountExternalId;
private final String transactionCode;
private final String currency;
private final BigDecimal amount;
private final BigDecimal fee;
public InteropHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec, String tenantId,
String accountExternalId, String transactionCode, String currency, BigDecimal amount, BigDecimal fee) {
this.requestSpec = requestSpec;
this.responseSpec = responseSpec;
this.tenantId = tenantId;
this.accountExternalId = accountExternalId;
this.transactionCode = transactionCode;
this.currency = currency;
this.amount = amount;
this.fee = fee;
}
public InteropHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec, String accountExternalId, String transactionCode) {
this(requestSpec, responseSpec, Utils.DEFAULT_TENANT, accountExternalId, transactionCode, "TZS", BigDecimal.TEN, BigDecimal.ONE);
}
public InteropHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec) {
this(requestSpec, responseSpec, UUID.randomUUID().toString(), UUID.randomUUID().toString());
}
public RequestSpecification getRequestSpec() {
return requestSpec;
}
public ResponseSpecification getResponseSpec() {
return responseSpec;
}
void setResponseSpec(ResponseSpecification responseSpec) {
this.responseSpec = responseSpec;
}
public String getTenantId() {
return tenantId;
}
public String getAccountExternalId() {
return accountExternalId;
}
public String getTransactionCode() {
return transactionCode;
}
public String getCurrency() {
return currency;
}
public BigDecimal getAmount() {
return amount;
}
public BigDecimal getFee() {
return fee;
}
BigDecimal getTransferAmount() {
return fee == null ? amount : amount.add(fee);
}
private String buildUrl(String url) {
return url + '?' + Utils.TENANT_PARAM_NAME + '=' + tenantId;
}
/**
* @return response json
*/
public String getHealth() {
String url = buildUrl(HEALTH_URL);
log.debug("Calling Interoperable GET Health: " + url);
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
log.debug("Response Interoperable GET Health: " + response);
return response;
}
/**
* @return response 'accountId' attribute
*/
public String getParty(InteropIdentifierType idType, String idValue) {
String url = buildUrl(PARTIES_URL + '/' + idType + '/' + idValue);
log.debug("Calling Interoperable GET Party: " + url);
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
log.debug("Response Interoperable GET Party: " + response);
return getJsonAttribute(response, InteropUtil.PARAM_ACCOUNT_ID);
}
/**
* @return response 'accountId' attribute
*/
public String postParty(InteropIdentifierType idType, String idValue) {
String url = buildUrl(PARTIES_URL + '/' + idType + '/' + idValue);
String request = buildPartiesJson();
log.debug("Calling Interoperable POST Party: " + url + ", body: " + request);
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
log.debug("Response Interoperable POST Party: " + response);
return getJsonAttribute(response, InteropUtil.PARAM_ACCOUNT_ID);
}
/**
* @return response 'accountId' attribute
*/
public String deleteParty(InteropIdentifierType idType, String idValue) {
String url = buildUrl(PARTIES_URL + '/' + idType + '/' + idValue);
String request = buildPartiesJson();
log.debug("Calling Interoperable DELETE Party: " + url + ", body: " + request);
String response = Utils.performServerDelete(requestSpec, responseSpec, url, request, null);
log.debug("Response Interoperable DELETE Party: " + response);
return getJsonAttribute(response, InteropUtil.PARAM_ACCOUNT_ID);
}
private String buildPartiesJson() {
HashMap<String, Object> map = new HashMap<>();
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
return new Gson().toJson(map);
}
/**
* @return response 'requestCode' attribute
*/
public String getTransactionRequest(String requestCode) {
String url = buildUrl(TRANSACTIONS_URL + '/' + transactionCode + '/' + REQUESTS_URL_PARAM + '/' + requestCode);
log.debug("Calling Interoperable GET Request: " + url);
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
log.debug("Response Interoperable GET Request: " + response);
return getJsonAttribute(response, InteropUtil.PARAM_REQUEST_CODE);
}
/**
* @param role PAYEE role is not valid for transaction request
* @return response json
*/
public String postTransactionRequest(String requestCode, InteropTransactionRole role) {
String url = buildUrl(REQUESTS_URL);
String request = buildTransactionRequestJson(requestCode, role);
log.debug("Calling Interoperable POST Request: " + url + ", body: " + request);
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
log.debug("Response Interoperable POST Request: " + response);
return response;
}
private String buildTransactionRequestJson(String requestCode, InteropTransactionRole role) {
HashMap<String, Object> map = new HashMap<>();
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);
map.put(InteropUtil.PARAM_REQUEST_CODE, requestCode);
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
HashMap<String, Object> amountMap = new HashMap<>();
amountMap.put(InteropUtil.PARAM_AMOUNT, amount.toString());
amountMap.put(InteropUtil.PARAM_CURRENCY, currency);
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
HashMap<String, Object> typeMap = new HashMap<>();
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYEE);
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
return new Gson().toJson(map);
}
/**
* @return response 'quoteCode' attribute
*/
public String getQuote(String quoteCode) {
String url = buildUrl(TRANSACTIONS_URL + '/' + transactionCode + '/' + QUOTES_URL_PARAM + '/' + quoteCode);
log.debug("Calling Interoperable GET Quote: " + url);
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
log.debug("Response Interoperable GET Quote: " + response);
return getJsonAttribute(response, InteropUtil.PARAM_QUOTE_CODE);
}
/**
* @return response json
*/
public String postQuote(String quoteCode, InteropTransactionRole role) {
String url = buildUrl(QUOTES_URL);
String request = buildQuoteJson(quoteCode, role);
log.debug("Calling Interoperable POST Quote: " + url + ", body: " + request);
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
log.debug("Response Interoperable POST Quote: " + response);
return response;
}
private String buildQuoteJson(String quoteCode, InteropTransactionRole role) {
HashMap<String, Object> map = new HashMap<>();
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);
map.put(InteropUtil.PARAM_QUOTE_CODE, quoteCode);
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
map.put(InteropUtil.PARAM_AMOUNT_TYPE, InteropAmountType.RECEIVE);
map.put(InteropUtil.PARAM_NOTE, NOTE);
HashMap<String, Object> amountMap = new HashMap<>();
amountMap.put(InteropUtil.PARAM_AMOUNT, amount.toString());
amountMap.put(InteropUtil.PARAM_CURRENCY, currency);
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
HashMap<String, Object> typeMap = new HashMap<>();
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYER);
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
return new Gson().toJson(map);
}
/**
* @return response 'transferCode' attribute
*/
public String getTransfer(String transferCode) {
String url = buildUrl(TRANSACTIONS_URL + '/' + transactionCode + '/' + TRANSFERS_URL_PARAM + '/' + transferCode);
log.debug("Calling Interoperable GET Transfer: " + url);
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
log.debug("Response Interoperable GET Transfer: " + response);
return getJsonAttribute(response, InteropUtil.PARAM_TRANSFER_CODE);
}
/**
* @return response json
*/
public String prepareTransfer(String transferCode) {
return postTransfer(transferCode, InteropTransferActionType.PREPARE, InteropTransactionRole.PAYER);
}
/**
* @return response json
*/
public String createTransfer(String transferCode, InteropTransactionRole role) {
return postTransfer(transferCode, InteropTransferActionType.CREATE, role);
}
/**
* @return response json
*/
public String postTransfer(String transferCode, InteropTransferActionType action, InteropTransactionRole role) {
String url = buildUrl(TRANSFERS_URL) + '&' + PARAM_TRANSFER_ACTION + '=' + action;
String request = buildTransferJson(transferCode, role);
log.debug("Calling Interoperable POST Transfer: " + url + ", body: " + request);
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
log.debug("Response Interoperable POST Transfer: " + response);
return response;
}
private String buildTransferJson(String transferCode, InteropTransactionRole role) {
HashMap<String, Object> map = new HashMap<>();
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);
map.put(InteropUtil.PARAM_TRANSFER_CODE, transferCode);
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
map.put(InteropUtil.PARAM_NOTE, NOTE);
HashMap<String, Object> amountMap = new HashMap<>();
amountMap.put(InteropUtil.PARAM_AMOUNT, amount.toString());
amountMap.put(InteropUtil.PARAM_CURRENCY, currency);
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
if (role.isWithdraw()) {
HashMap<String, Object> feeMap = new HashMap<>();
feeMap.put(InteropUtil.PARAM_AMOUNT, fee.toString());
feeMap.put(InteropUtil.PARAM_CURRENCY, currency);
map.put(InteropUtil.PARAM_FSP_FEE, feeMap);
}
HashMap<String, Object> typeMap = new HashMap<>();
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYER);
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
return new Gson().toJson(map);
}
public static String getJsonAttribute(String json, String attrName) {
return JsonPath.from(json).get(attrName);
}
}
@@ -0,0 +1,289 @@
/**
* 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.interoperation;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.internal.path.ObjectConverter;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
import org.apache.fineract.interoperation.domain.InteropActionState;
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
import org.apache.fineract.interoperation.util.InteropUtil;
import org.apache.fineract.interoperation.util.MathUtil;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper.ACCOUNT_TYPE_INDIVIDUAL;
import static org.apache.fineract.integrationtests.interoperation.InteropHelper.PARAM_ACCOUNT_BALANCE;
public class InteropTest {
private final static Logger log = LoggerFactory.getLogger(InteropTest.class);
private final static String MIN_INTEREST_CALCULATON_BALANCE = null;
private final static String MIN_REQUIRED_BALANCE = null;
private final static String MIN_OPENING_BALANCE = "100000.0";
private final static boolean ENFORCE_MIN_REQUIRED_BALANCE = false;
private final static MathContext MATHCONTEXT = new MathContext(12, RoundingMode.HALF_EVEN);
private RequestSpecification requestSpec;
private ResponseSpecification responseSpec;
private ResponseSpecification responseClientErrorSpec;
private ResponseSpecification responseErrorSpec;
private AccountHelper accountHelper;
private SavingsAccountHelper savingsAccountHelper;
private InteropHelper interopHelper;
private Integer clientId;
private Integer savingsProductId;
private Integer savingsId;
private Integer chargeId;
private String requestCode;
private String quoteCode;
private String transferCode;
@Before
public void setup() {
Utils.initializeRESTAssured();
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
responseClientErrorSpec = new ResponseSpecBuilder().expectStatusCode(400).build();
responseErrorSpec = new ResponseSpecBuilder().expectStatusCode(500).build();
String savingsExternalId = UUID.randomUUID().toString();
String transactionCode = UUID.randomUUID().toString();
accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
interopHelper = new InteropHelper(requestSpec, responseSpec, savingsExternalId, transactionCode);
}
@Test
public void testInteroperation() {
createClient();
createSavingsProduct();
createCharge();
openSavingsAccount();
testParties();
testRequests();
testQuotes();
testTransfers();
}
private void createClient() {
clientId = ClientHelper.createClient(requestSpec, responseSpec);
Assert.assertNotNull(clientId);
}
private void createSavingsProduct() {
log.debug("------------------------------ Create Interoperable Saving Product ---------------------------------------");
Account[] accounts = {accountHelper.createAssetAccount(), accountHelper.createIncomeAccount(), accountHelper.createExpenseAccount(),
accountHelper.createLiabilityAccount()};
SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
final String savingsProductJSON = savingsProductHelper
.withCurrencyCode(interopHelper.getCurrency())
.withNominalAnnualInterestRate(BigDecimal.ZERO)
.withInterestCompoundingPeriodTypeAsDaily()
.withInterestPostingPeriodTypeAsMonthly()
.withInterestCalculationPeriodTypeAsDailyBalance()
.withMinBalanceForInterestCalculation(MIN_INTEREST_CALCULATON_BALANCE)
.withMinRequiredBalance(MIN_REQUIRED_BALANCE)
.withEnforceMinRequiredBalance(Boolean.toString(ENFORCE_MIN_REQUIRED_BALANCE))
.withMinimumOpenningBalance(MIN_OPENING_BALANCE)
.withAccountingRuleAsCashBased(accounts)
.build();
savingsProductId = SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
Assert.assertNotNull(savingsProductId);
log.debug("Sucessfully created Interoperable Saving Product (id: " + savingsProductId + ")");
}
private void createCharge() {
chargeId = ChargesHelper.createCharges(requestSpec, responseSpec, ChargesHelper.getSavingsJSON(interopHelper.getFee().toString(),
interopHelper.getCurrency(), ChargeTimeType.WITHDRAWAL_FEE));
Assert.assertNotNull(chargeId);
}
private void openSavingsAccount() {
log.debug("------------------------------ Create Interoperable Saving Account ---------------------------------------");
savingsId = savingsAccountHelper.applyForSavingsApplicationWithExternalId(clientId, savingsProductId, ACCOUNT_TYPE_INDIVIDUAL, interopHelper.getAccountExternalId(), true);
Assert.assertNotNull(savingsId);
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsId);
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
savingsStatusHashMap = savingsAccountHelper.approveSavings(savingsId);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
if (chargeId != null) {
savingsAccountHelper.addChargesForSavings(savingsId, chargeId, false, interopHelper.getFee());
}
log.debug("Sucessfully created Interoperable Saving Account (id: " + savingsId + ")");
}
private void testParties() {
String idValue = UUID.randomUUID().toString();
String accountId = interopHelper.postParty(InteropIdentifierType.MSISDN, idValue);
Assert.assertEquals(interopHelper.getAccountExternalId(), accountId);
interopHelper.setResponseSpec(responseErrorSpec);
accountId = interopHelper.postParty(InteropIdentifierType.MSISDN, idValue);
Assert.assertNull(accountId);
interopHelper.setResponseSpec(responseSpec);
accountId = interopHelper.getParty(InteropIdentifierType.MSISDN, idValue);
Assert.assertEquals(interopHelper.getAccountExternalId(), accountId);
accountId = interopHelper.deleteParty(InteropIdentifierType.MSISDN, idValue);
Assert.assertEquals(interopHelper.getAccountExternalId(), accountId);
interopHelper.setResponseSpec(responseErrorSpec);
accountId = interopHelper.getParty(InteropIdentifierType.MSISDN, idValue);
Assert.assertNull(accountId);
interopHelper.setResponseSpec(responseSpec);
}
private void testRequests() {
requestCode = UUID.randomUUID().toString();
String response = interopHelper.postTransactionRequest(requestCode, InteropTransactionRole.PAYER);
JsonPath json = JsonPath.from(response);
Assert.assertEquals(requestCode, json.getString(InteropUtil.PARAM_REQUEST_CODE));
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
interopHelper.setResponseSpec(responseClientErrorSpec);
interopHelper.postTransactionRequest(requestCode, InteropTransactionRole.PAYEE);
interopHelper.setResponseSpec(responseSpec);
}
private void testQuotes() {
// payer
quoteCode = UUID.randomUUID().toString();
String response = interopHelper.postQuote(quoteCode, InteropTransactionRole.PAYER);
JsonPath json = JsonPath.from(response);
Assert.assertEquals(quoteCode, json.getString(InteropUtil.PARAM_QUOTE_CODE));
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
Map<Object, Object> fee = json.getMap(InteropUtil.PARAM_FSP_FEE);
Assert.assertNotNull(fee);
BigDecimal feeAmount = ObjectConverter.convertObjectTo(fee.get(InteropUtil.PARAM_AMOUNT), BigDecimal.class);
Assert.assertTrue("Quote fee expected: " + interopHelper.getFee() + ", actual: " + feeAmount, MathUtil.isEqualTo(interopHelper.getFee(), feeAmount));
Assert.assertEquals(interopHelper.getCurrency(), fee.get(InteropUtil.PARAM_CURRENCY));
// payee
response = interopHelper.postQuote(quoteCode, InteropTransactionRole.PAYEE);
json = JsonPath.from(response);
Assert.assertEquals(quoteCode, json.getString(InteropUtil.PARAM_QUOTE_CODE));
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
fee = json.getMap(InteropUtil.PARAM_FSP_FEE);
if (fee != null) {
feeAmount = ObjectConverter.convertObjectTo(fee.get(InteropUtil.PARAM_AMOUNT), BigDecimal.class);
Assert.assertTrue("PAYEE Quote fee expected: " + BigDecimal.ZERO + ", actual: " + feeAmount, MathUtil.isZero(feeAmount));
}
}
private void testTransfers() {
String savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
JsonPath savingsJson = JsonPath.from(savings);
BigDecimal onHold = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
BigDecimal balance = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
transferCode = UUID.randomUUID().toString();
String response = interopHelper.prepareTransfer(transferCode);
JsonPath json = JsonPath.from(response);
Assert.assertEquals(transferCode, json.getString(InteropUtil.PARAM_TRANSFER_CODE));
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
// prepare
savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
log.debug("Response Interoperable GET Saving: " + savings);
savingsJson = JsonPath.from(savings);
BigDecimal onHold2 = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
BigDecimal balance2 = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
BigDecimal transferAmount = interopHelper.getTransferAmount();
BigDecimal expectedHold = MathUtil.add(onHold, transferAmount, MATHCONTEXT);
Assert.assertTrue("On hold amount expected: " + expectedHold + ", actual: " + onHold2, MathUtil.isEqualTo(expectedHold, onHold2));
BigDecimal expectedBalance = MathUtil.subtract(balance, transferAmount, MATHCONTEXT);
Assert.assertTrue("Balance amount expected: " + expectedBalance + ", actual: " + balance2, MathUtil.isEqualTo(expectedBalance, balance2));
// payer
response = interopHelper.createTransfer(transferCode, InteropTransactionRole.PAYER);
json = JsonPath.from(response);
Assert.assertEquals(transferCode, json.getString(InteropUtil.PARAM_TRANSFER_CODE));
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
log.debug("Response Interoperable GET Saving: " + savings);
savingsJson = JsonPath.from(savings);
BigDecimal onHold3 = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
BigDecimal balance3 = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
Assert.assertTrue("On hold amount expected: " + onHold + ", actual: " + onHold3, MathUtil.isEqualTo(onHold, onHold3));
Assert.assertTrue("Balance amount expected: " + expectedBalance + ", actual: " + balance3, MathUtil.isEqualTo(expectedBalance, balance3));
// payee
response = interopHelper.createTransfer(transferCode, InteropTransactionRole.PAYEE);
json = JsonPath.from(response);
Assert.assertEquals(transferCode, json.getString(InteropUtil.PARAM_TRANSFER_CODE));
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
log.debug("Response Interoperable GET Saving: " + savings);
savingsJson = JsonPath.from(savings);
BigDecimal onHold4 = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
BigDecimal balance4 = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
expectedBalance = MathUtil.subtract(balance, interopHelper.getFee(), MATHCONTEXT);
Assert.assertTrue("On hold amount expected: " + onHold + ", actual: " + onHold4, MathUtil.isEqualTo(onHold, onHold4));
Assert.assertTrue("Balance amount expected: " + expectedBalance + ", actual: " + balance4, MathUtil.isEqualTo(balance, balance4));
}
}
@@ -24,6 +24,8 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import io.swagger.annotations.*;
// import org.apache.fineract.accounting.accrual.swagger.runaccuralPost;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
@@ -36,6 +38,7 @@ import org.springframework.stereotype.Component;
@Path("/runaccruals")
@Component
@Scope("singleton")
@Api(value = "Periodic Accrual Accounting", description = "Periodic Accrual is to accrue the loan income till the specific date or till batch job scheduled time.\n\n ")
public class AccrualAccountingApiResource {
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@@ -52,7 +55,10 @@ public class AccrualAccountingApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String executePeriodicAccrualAccounting(final String jsonRequestBody) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().excuteAccrualAccounting().withJson(jsonRequestBody).build();
@@ -0,0 +1,46 @@
/**
* 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.accounting.accrual.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* Created by sanyam on 24/7/17.
*/
final class AccrualAccountingApiResourceSwagger {
private AccrualAccountingApiResourceSwagger() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModel(value = "runaccrualsRequest")
public static final class PostRunaccrualsRequest {
private PostRunaccrualsRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "en")
public String locale;
@ApiModelProperty(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)
public String tillDate;
}
}
@@ -30,7 +30,4 @@ public class AccrualAccountingConstants {
public static final String PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME = "periodicaccrual";
public static final String PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE = "execution.failed";
public static final Set<String> LOAN_PERIODIC_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(accrueTillParamName,
localeParamName, dateFormatParamName));
}
@@ -18,16 +18,19 @@
*/
package org.apache.fineract.accounting.accrual.serialization;
import static org.apache.fineract.accounting.accrual.api.AccrualAccountingConstants.LOAN_PERIODIC_REQUEST_DATA_PARAMETERS;
import static org.apache.fineract.accounting.accrual.api.AccrualAccountingConstants.PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME;
import static org.apache.fineract.accounting.accrual.api.AccrualAccountingConstants.accrueTillParamName;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.fineract.accounting.accrual.api.AccrualAccountingConstants;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
@@ -51,6 +54,9 @@ import com.google.gson.reflect.TypeToken;
public final class AccrualAccountingDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private static final Set<String> LOAN_PERIODIC_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(accrueTillParamName, AccrualAccountingConstants.localeParamName,
AccrualAccountingConstants.dateFormatParamName));
@Autowired
public AccrualAccountingDataValidator(final FromJsonHelper fromApiJsonfromApiJsonHelper) {
@@ -36,6 +36,7 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import io.swagger.annotations.*;
import org.apache.fineract.accounting.closure.data.GLClosureData;
import org.apache.fineract.accounting.closure.service.GLClosureReadPlatformService;
import org.apache.fineract.commands.domain.CommandWrapper;
@@ -54,6 +55,7 @@ import org.springframework.stereotype.Component;
@Path("/glclosures")
@Component
@Scope("singleton")
@Api(value = "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<>(Arrays.asList("id", "officeId", "officeName",
@@ -85,7 +87,9 @@ public class GLClosuresApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllClosures(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) {
@ApiOperation(value = "List Accounting closures", notes = "Example Requests:\n" + "\n" + "glclosures")
@ApiResponses({@ApiResponse(code = 200, response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class, message = "", responseContainer = "list")})
public String retrieveAllClosures(@Context final UriInfo uriInfo, @QueryParam("officeId") @ApiParam(value = "officeId") final Long officeId) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
final List<GLClosureData> glClosureDatas = this.glClosureReadPlatformService.retrieveAllGLClosures(officeId);
@@ -98,7 +102,9 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retreiveClosure(@PathParam("glClosureId") final Long glClosureId, @Context final UriInfo uriInfo) {
@ApiOperation(value = "Retrieve an Accounting Closure", notes = "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, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -112,10 +118,14 @@ public class GLClosuresApiResource {
return this.apiJsonSerializerService.serialize(settings, glClosureData, RESPONSE_DATA_PARAMETERS);
}
// NOTE: proposal slight changes @Aleks
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createGLClosure(final String jsonRequestBody) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLClosure().withJson(jsonRequestBody).build();
@@ -128,7 +138,10 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateGLClosure(@PathParam("glClosureId") final Long glClosureId, final String jsonRequestBody) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLClosure(glClosureId).withJson(jsonRequestBody).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
@@ -140,7 +153,9 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteGLClosure(@PathParam("glClosureId") final Long glClosureId) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLClosure(glClosureId).build();
@@ -0,0 +1,133 @@
/**
* 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.accounting.closure.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.joda.time.LocalDate;
import java.lang.reflect.Array;
import java.util.ArrayList;
final class GLClosuresApiResourceSwagger {
private GLClosuresApiResourceSwagger() {
// don't allow to instantiate; use only for live API documentation
}
/**
* TODO: describe where this belongs: {@link GLClosuresApiResource }
* {@Link GLClosuresApiResource}
*/
// Check !!
@ApiModel(value = "GetGLClosureResponse")
public static final class GetGlClosureResponse {
private GetGlClosureResponse() {
// dont allow to initiatiate
}
@ApiModelProperty(example = "7")
public Long id;
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "Head Office")
public String officeName;
@ApiModelProperty(example = "2013,1,2")
public LocalDate closingDate;
@ApiModelProperty(example = "false")
public boolean deleted;
@ApiModelProperty(example = "2013,1,3")
public LocalDate createdDate;
@ApiModelProperty(example = "2013,1,3")
public LocalDate lastUpdatedDate;
@ApiModelProperty(example = "1")
public Long createdByUserId;
@ApiModelProperty(example = "mifos")
public String createdByUsername;
@ApiModelProperty(example = "1")
public Long lastUpdatedByUserId;
@ApiModelProperty(example = "mifos")
public String lastUpdatedByUsername;
@ApiModelProperty(example = "closed")
public String comments;
}
@ApiModel(value = "PostGLCLosuresRequest")
public static final class PostGlClosuresRequest {
private PostGlClosuresRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "06 December 2012")
public LocalDate closingDate;
@ApiModelProperty(example = "The accountants are heading for a carribean vacation")
public String comments;
@ApiModelProperty(example = "en")
public String locale;
@ApiModelProperty(example = "dd MMMM yyyy")
public String dateFormat;
}
@ApiModel(value = "PostGlClosuresResponse")
public static final class PostGlClosuresResponse {
private PostGlClosuresResponse() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
public Long resourceId;
}
@ApiModel(value = "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")
public String comments;
}
@ApiModel(value = "PutGlClosuresResponse")
public static final class PutGlClosuresResponse{
private PutGlClosuresResponse() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
public Long resourceId;
@ApiModelProperty(example = "All transactions verified by Johnny Cash")
public String comments;
}
@ApiModel(value = "DeleteGlClosuresResponse")
public static final class DeleteGlClosuresResponse{
private DeleteGlClosuresResponse(){
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
public Long resourceId;
}
}
@@ -32,7 +32,9 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import io.swagger.annotations.*;
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityAccountData;
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityData;
import org.apache.fineract.accounting.financialactivityaccount.service.FinancialActivityAccountReadPlatformService;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
@@ -49,6 +51,7 @@ import org.springframework.stereotype.Component;
@Path("/financialactivityaccounts")
@Component
@Scope("singleton")
@Api(value = "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" +"\nField 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;
@@ -89,6 +92,8 @@ 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" + "financialactivityaccounts")
@ApiResponses({@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class, responseContainer = "list" )})
public String retrieveAll(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
@@ -103,7 +108,9 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retreive(@PathParam("mappingId") final Long mappingId, @Context final UriInfo uriInfo) {
@ApiOperation(value = "Retrieve a Financial Activity to Account Mapping\n", notes = "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) {
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
@@ -121,7 +128,10 @@ public class FinancialActivityAccountsApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createGLAccount(final String jsonRequestBody) {
@ApiOperation(value = "Create a new Financial Activity to Accounts Mapping", notes = "Mandatory Fields\n" + "financialActivityId, glAccountId")
@ApiImplicitParams({@ApiImplicitParam(value = "Request body", paramType = "body", dataType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class)})
public String createGLAccount(@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createOfficeToGLAccountMapping().withJson(jsonRequestBody)
.build();
@@ -135,7 +145,10 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateGLAccount(@PathParam("mappingId") final Long mappingId, final String jsonRequestBody) {
@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)})
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateOfficeToGLAccountMapping(mappingId)
.withJson(jsonRequestBody).build();
@@ -149,7 +162,9 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteGLAccount(@PathParam("mappingId") final Long mappingId) {
@ApiOperation(value = "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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteOfficeToGLAccountMapping(mappingId).build();
@@ -0,0 +1,103 @@
/**
* 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.accounting.financialactivityaccount.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityData;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import java.util.List;
import java.util.Map;
/**
* Created by sanyam on 24/7/17.
*/
final class FinancialActivityAccountsApiResourceSwagger {
private FinancialActivityAccountsApiResourceSwagger() {
}
@ApiModel(value = "GetFinancialActivityAccountsResponse")
public static final class GetFinancialActivityAccountsResponse{
private GetFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
public Long id;
public FinancialActivityData financialActivityData;
public GLAccountData glAccountData;
}
@ApiModel(value = "PostFinancialActivityAccountsRequest")
public static final class PostFinancialActivityAccountsRequest{
private PostFinancialActivityAccountsRequest() {
}
@ApiModelProperty(example = "200")
public Long financialActivityId;
@ApiModelProperty(example = "2")
public Long glAccountId;
}
@ApiModel(value = "PostFinancialActivityAccountsResponse")
public static final class PostFinancialActivityAccountsResponse{
private PostFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
public Long resourceId;
}
@ApiModel(value = "PutFinancialActivityAccountsRequest")
public static final class PutFinancialActivityAccountsRequest{
private PutFinancialActivityAccountsRequest() {
}
@ApiModelProperty(example = "200")
public Long financialActivityId;
@ApiModelProperty(example = "3")
public Long glAccountId;
}
@ApiModel(value = "PutFinancialActivityAccountsResponse")
public static final class PutFinancialActivityAccountsResponse{
private PutFinancialActivityAccountsResponse() {
}
public final class PutFinancialActivityAccountscommentsSwagger{
private PutFinancialActivityAccountscommentsSwagger(){}
@ApiModelProperty(example = "1")
public Long glAccountId;
}
@ApiModelProperty(example = "1")
public Long resourceId;
public PutFinancialActivityAccountscommentsSwagger comments;
}
@ApiModel(value = "DeleteFinancialActivityAccountsResponse")
public static final class DeleteFinancialActivityAccountsResponse{
private DeleteFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
public Long resourceId;
}
}
@@ -23,9 +23,13 @@ import java.util.HashSet;
import java.util.Set;
public class FinancialActivityAccountsConstants {
public static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "financialActivityData",
"glAccountData", "glAccountOptions", "financialActivityOptions"));
private static final String idParamName = "id";
private static final String factivityDataParamName = "financialActivityData";
private static final String glAccountDataParamName = "glAccountData";
private static final String glAccountOptionsParamName = "glAccountOptions";
private static final String financialActivityOptionsParamName = "financialActivityOptions";
public static final String resourceNameForPermission = "FINANCIALACTIVITYACCOUNT";
protected static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, factivityDataParamName, glAccountDataParamName, glAccountOptionsParamName,
financialActivityOptionsParamName));
}
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.accounting.glaccount.api;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -35,8 +36,13 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import io.swagger.annotations.*;
import io.swagger.models.parameters.HeaderParameter;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import org.apache.fineract.accounting.common.AccountingConstants;
import org.apache.fineract.accounting.common.AccountingDropdownReadPlatformService;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
@@ -46,6 +52,9 @@ import org.apache.fineract.accounting.journalentry.data.JournalEntryAssociationP
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookPopulatorService;
import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookService;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
@@ -61,6 +70,7 @@ import org.springframework.stereotype.Component;
@Path("/glaccounts")
@Component
@Scope("singleton")
@Api(value = "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",
@@ -78,13 +88,19 @@ public class GLAccountsApiResource {
private final PlatformSecurityContext context;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final BulkImportWorkbookService bulkImportWorkbookService;
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
@Autowired
public GLAccountsApiResource(final PlatformSecurityContext context, final GLAccountReadPlatformService glAccountReadPlatformService,
final DefaultToApiJsonSerializer<GLAccountData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final AccountingDropdownReadPlatformService dropdownReadPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService) {
final CodeValueReadPlatformService codeValueReadPlatformService,
final BulkImportWorkbookService bulkImportWorkbookService,
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService) {
this.context = context;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -92,13 +108,17 @@ public class GLAccountsApiResource {
this.glAccountReadPlatformService = glAccountReadPlatformService;
this.dropdownReadPlatformService = dropdownReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
this.bulkImportWorkbookService=bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo, @QueryParam("type") final Integer type) {
@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)})
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo, @QueryParam("type") @ApiParam(value = "type") final Integer type) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -112,10 +132,12 @@ public class GLAccountsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("type") final Integer type,
@QueryParam("searchParam") final String searchParam, @QueryParam("usage") final Integer usage,
@QueryParam("manualEntriesAllowed") final Boolean manualEntriesAllowed, @QueryParam("disabled") final Boolean disabled,
@QueryParam("fetchRunningBalance") final boolean runningBalance) {
@ApiOperation(value = "List General Ledger Accounts", notes = "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) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
@@ -130,8 +152,10 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retreiveAccount(@PathParam("glAccountId") final Long glAccountId, @Context final UriInfo uriInfo,
@QueryParam("fetchRunningBalance") final boolean runningBalance) {
@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, @Context final UriInfo uriInfo,
@QueryParam("fetchRunningBalance") @ApiParam(value = "fetchRunningBalance") final boolean runningBalance) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -148,7 +172,10 @@ public class GLAccountsApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createGLAccount(final String jsonRequestBody) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLAccount().withJson(jsonRequestBody).build();
@@ -161,7 +188,10 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateGLAccount(@PathParam("glAccountId") final Long glAccountId, final String jsonRequestBody) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLAccount(glAccountId).withJson(jsonRequestBody).build();
@@ -174,7 +204,9 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteGLAccount(@PathParam("glAccountId") final Long glAccountId) {
@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) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
@@ -219,4 +251,22 @@ public class GLAccountsApiResource {
}
return returnList;
}
@GET
@Path("downloadtemplate")
@Produces("application/vnd.ms-excel")
public Response getGlAccountsTemplate(@QueryParam("dateFormat") final String dateFormat) {
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.CHART_OF_ACCOUNTS.toString(),null,null,dateFormat);
}
@POST
@Path("uploadtemplate")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postGlAccountsTemplate(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail,
@FormDataParam("locale") final String locale, @FormDataParam("dateFormat") final String dateFormat){
Long importDocumentId= bulkImportWorkbookService.importWorkbook(GlobalEntityType.CHART_OF_ACCOUNTS.toString(), uploadedInputStream,fileDetail,
locale,dateFormat);
return this.apiJsonSerializerService.serialize(importDocumentId);
}
}
@@ -0,0 +1,190 @@
/**
* 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.accounting.glaccount.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import java.util.Collection;
import java.util.List;
/**
* Created by sanyam on 24/7/17.
*/
final class GLAccountsApiResourceSwagger {
private GLAccountsApiResourceSwagger() {
}
@ApiModel(value = "GetGLAccountsResponse")
public static final class GetGLAccountsResponse{
private GetGLAccountsResponse(){
}
@ApiModelProperty(example = "16")
public Long id;
@ApiModelProperty(example = "Cash")
public String name;
@ApiModelProperty(example = "1")
public Long parentId;
@ApiModelProperty(example = "100001")
public String glCode;
@ApiModelProperty(example = "false")
public Boolean disabled;
@ApiModelProperty(example = "true")
public Boolean manualEntriesAllowed;
public EnumOptionData type;
public EnumOptionData usage;
@ApiModelProperty(example = "Desc")
public String description;
@ApiModelProperty(example = "....Cash")
public String nameDecorated;
public CodeValueData tagId;
@ApiModelProperty(example = "118437")
public Long organizationRunningBalance;
}
@ApiModel(value = "GetGLAccountsTemplateResponse")
public static final class GetGLAccountsTemplateResponse{
private GetGLAccountsTemplateResponse(){
}
@ApiModelProperty(example = "false")
public Boolean disabled;
@ApiModelProperty(example = "true")
public Boolean manualEntriesAllowed;
public EnumOptionData type;
public EnumOptionData usage;
public List<EnumOptionData> accountTypeOptions;
public List<EnumOptionData> usageOptions;
public List<GLAccountData> assetHeaderAccountOptions;
public List<GLAccountData> liabilityHeaderAccountOptions;
public List<GLAccountData> equityHeaderAccountOptions;
public List<GLAccountData> expenseHeaderAccountOptions;
public Collection<CodeValueData> allowedAssetsTagOptions;
public Collection<CodeValueData> allowedLiabilitiesTagOptions;
public Collection<CodeValueData> allowedEquityTagOptions;
public Collection<CodeValueData> allowedIncomeTagOptions;
public Collection<CodeValueData> allowedExpensesTagOptions;
}
@ApiModel(value = "PostGLAccountsRequest")
public static final class PostGLAccountsRequest{
private PostGLAccountsRequest(){
}
@ApiModelProperty(example = "Cash at Bangalore")
public String name;
@ApiModelProperty(example = "100001")
public String glCode;
@ApiModelProperty(example = "true")
public Boolean manualEntriesAllowed;
@ApiModelProperty(example = "1")
public String type;
@ApiModelProperty(example = "10")
public String tagId;
@ApiModelProperty(example = "1")
public Long parentId;
@ApiModelProperty(example = "1")
public EnumOptionData usage;
@ApiModelProperty(example = "Desc")
public String description;
}
@ApiModel(value = "PostGLAccountsResponse")
public static final class PostGLAccountsResponse{
private PostGLAccountsResponse() {
}
@ApiModelProperty(example = "22")
public int resourceId;
}
@ApiModel(value = "PutGLAccountsRequest")
public static final class PutGLAccountsRequest{
private PutGLAccountsRequest() {
}
@ApiModelProperty(example = "Cash at Bangalore")
public String name;
}
@ApiModel(value = "PutGLAccountsResponse")
public static final class PutGLAccountsResponse{
private PutGLAccountsResponse() {
}
@ApiModel
public static final class PutGLAccountsResponsechangesSwagger{
private PutGLAccountsResponsechangesSwagger(){}
@ApiModelProperty(example = "Cash at Bangalore")
public String name;
}
@ApiModelProperty(example = "1")
public int resourceId;
public PutGLAccountsResponsechangesSwagger changes;
}
@ApiModel(value = "DeleteGLAccountsRequest")
public static final class DeleteGLAccountsRequest{
private DeleteGLAccountsRequest() {
}
private static final class DeleteGLAccountsRequestchangesSwagger{
private DeleteGLAccountsRequestchangesSwagger(){}
}
@ApiModelProperty(example = "1")
public int resourceId;
private DeleteGLAccountsRequestchangesSwagger changes;
}
}
@@ -62,6 +62,55 @@ public class GLAccountData {
final Collection<CodeValueData> allowedIncomeTagOptions;
final Collection<CodeValueData> allowedExpensesTagOptions;
//import fields
private transient Integer rowIndex;
public static GLAccountData importInstance(String name, Long parentId, String glCode, Boolean manualEntriesAllowed,
EnumOptionData type, EnumOptionData usage, String description, CodeValueData tagId,
Integer rowIndex){
return new GLAccountData(name,parentId,glCode,manualEntriesAllowed,type,
usage,description,tagId,rowIndex);
}
private GLAccountData(String name, Long parentId, String glCode, Boolean manualEntriesAllowed,
EnumOptionData type, EnumOptionData usage, String description, CodeValueData tagId,
Integer rowIndex) {
this.name = name;
this.parentId = parentId;
this.glCode = glCode;
this.manualEntriesAllowed = manualEntriesAllowed;
this.type = type;
this.usage = usage;
this.description = description;
this.tagId = tagId;
this.rowIndex = rowIndex;
this.id = null;
this.disabled = null;
this.nameDecorated = null;
this.organizationRunningBalance = null;
this.accountTypeOptions = null;
this.usageOptions = null;
this.assetHeaderAccountOptions = null;
this.liabilityHeaderAccountOptions = null;
this.equityHeaderAccountOptions = null;
this.incomeHeaderAccountOptions = null;
this.expenseHeaderAccountOptions = null;
this.allowedAssetsTagOptions = null;
this.allowedLiabilitiesTagOptions = null;
this.allowedEquityTagOptions = null;
this.allowedIncomeTagOptions = null;
this.allowedExpensesTagOptions = null;
}
public Integer getRowIndex() {
return rowIndex;
}
public CodeValueData getTagId() {
return tagId;
}
public GLAccountData(final Long id, final String name, final Long parentId, final String glCode, final boolean disabled,
final boolean manualEntriesAllowed, final EnumOptionData type, final EnumOptionData usage, final String description,
final String nameDecorated, final CodeValueData tagId, final Long organizationRunningBalance) {
@@ -195,4 +244,5 @@ public class GLAccountData {
return null;
}
}
@@ -18,6 +18,8 @@
*/
package org.apache.fineract.accounting.glaccount.domain;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import java.util.HashMap;
import java.util.Map;
@@ -60,6 +62,27 @@ public enum GLAccountType {
i = i + 1;
}
}
public static EnumOptionData fromString(String accountType){
Long accountTypeId=null;
if (accountType!=null && accountType.equalsIgnoreCase(ASSET.toString())){
accountTypeId=1L;
return new EnumOptionData(accountTypeId,null,null);
}else if(accountType!=null && accountType.equalsIgnoreCase(LIABILITY.toString())) {
accountTypeId = 2L;
return new EnumOptionData(accountTypeId, null, null);
}else if(accountType!=null && accountType.equalsIgnoreCase(EQUITY.toString())){
accountTypeId=3L;
return new EnumOptionData(accountTypeId,null,null);
}else if(accountType!=null && accountType.equalsIgnoreCase(INCOME.toString())) {
accountTypeId = 4L;
return new EnumOptionData(accountTypeId, null, null);
}else if(accountType!=null && accountType.equalsIgnoreCase(EXPENSE.toString())){
accountTypeId=5L;
return new EnumOptionData(accountTypeId,null,null);
}else {
return null;
}
}
public static GLAccountType fromInt(final int i) {
final GLAccountType type = intToEnumMap.get(Integer.valueOf(i));
@@ -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.accounting.glaccount.domain;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
@Entity
@Table(name = "m_trial_balance")
public class TrialBalance extends AbstractPersistableCustom<Long> {
@Column(name = "office_id", nullable = false)
private Long officeId;
@Column(name = "account_id", nullable = false)
private Long glAccountId;
@Column(name = "amount", nullable = false)
private BigDecimal amount;
@Column(name = "entry_date", nullable = false)
@Temporal(TemporalType.DATE)
private Date entryDate;
@Column(name = "created_date", nullable = true)
@Temporal(TemporalType.DATE)
private Date transactionDate;
@Column(name = "closing_balance", nullable = false)
private BigDecimal closingBalance;
public static TrialBalance getInstance(final Long officeId, final Long glAccountId,
final BigDecimal amount, final Date entryDate, final Date transactionDate) {
return new TrialBalance(officeId, glAccountId, amount, entryDate, transactionDate);
}
private TrialBalance(final Long officeId, final Long glAccountId,
final BigDecimal amount, final Date entryDate, final Date transactionDate) {
this.officeId = officeId;
this.glAccountId = glAccountId;
this.amount = amount;
this.entryDate = entryDate;
this.transactionDate = transactionDate;
}
protected TrialBalance() {
}
public Long getOfficeId() {
return officeId;
}
public Date getTransactionDate() {
return transactionDate;
}
public BigDecimal getAmount() {
return amount;
}
public void setClosingBalance(final BigDecimal closingBalance) {
this.closingBalance = closingBalance;
}
public Date getEntryDate() {
return entryDate;
}
public Long getGlAccountId() {
return glAccountId;
}
@Override
public boolean equals(Object obj) {
if (!obj.getClass().equals(getClass())) return false;
TrialBalance trialBalance = (TrialBalance) obj;
return trialBalance.getOfficeId().equals(this.getOfficeId())
&& trialBalance.getGlAccountId().equals(this.getGlAccountId())
&& trialBalance.getEntryDate().equals(this.getEntryDate())
&& trialBalance.getTransactionDate().equals(this.getTransactionDate());
}
}
@@ -0,0 +1,33 @@
/**
* 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.accounting.glaccount.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface TrialBalanceRepository extends JpaRepository<TrialBalance, Long>, JpaSpecificationExecutor<TrialBalance> {
@Query(value = "select * from m_trial_balance where office_id=:officeId and account_id=:accountId and closing_balance is null order by created_date, entry_date", nativeQuery = true)
List<TrialBalance> findNewByOfficeAndAccount(@Param("officeId") final Long officeId,
@Param("accountId") final Long accountId);
}
@@ -0,0 +1,47 @@
/**
* 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.accounting.glaccount.domain;
import org.apache.fineract.accounting.trialbalance.exception.TrialBalanceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TrialBalanceRepositoryWrapper {
private final TrialBalanceRepository repository;
@Autowired
public TrialBalanceRepositoryWrapper(final TrialBalanceRepository repository){
this.repository=repository;
}
public List<TrialBalance> findNewByOfficeAndAccount(final Long officeId, final Long accountId){
final List<TrialBalance> trialBalanceList=this.repository.findNewByOfficeAndAccount(officeId,accountId);
if (trialBalanceList==null)
throw new TrialBalanceNotFoundException(officeId,accountId);
return trialBalanceList;
}
public void save(final List<TrialBalance> tbRows){
this.repository.save(tbRows);
}
}
@@ -0,0 +1,35 @@
/**
* 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.accounting.glaccount.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
*
* when gl account is attached with any product(loan/saving) then we can not
* disable the gl account
*/
public class GLAccountDisableException extends
AbstractPlatformDomainRuleException {
public GLAccountDisableException() {
super("error.msg.glaccount.attached.to.product",
"General Ledger Account is already attached to product.");
}
}
@@ -123,11 +123,13 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
String sql = "select " + rm.schema();
// append SQL statement for fetching account totals
if (associationParametersData.isRunningBalanceRequired()) {
sql = sql + " and gl_j.id in (select t1.id from (select t2.account_id, max(t2.id) as id from "
+ "(select id, max(entry_date) as entry_date, account_id from acc_gl_journal_entry where is_running_balance_calculated = 1 "
+ "group by account_id desc) t3 inner join acc_gl_journal_entry t2 on t2.account_id = t3.account_id and t2.entry_date = t3.entry_date "
+ "group by t2.account_id desc) t1)";
if (associationParametersData!=null) {
if (associationParametersData.isRunningBalanceRequired()) {
sql = sql + " and gl_j.id in (select t1.id from (select t2.account_id, max(t2.id) as id from "
+ "(select id, max(entry_date) as entry_date, account_id from acc_gl_journal_entry where is_running_balance_calculated = 1 "
+ "group by account_id desc, id) t3 inner join acc_gl_journal_entry t2 on t2.account_id = t3.account_id and t2.entry_date = t3.entry_date "
+ "group by t2.account_id desc) t1)";
}
}
final Object[] paramaterArray = new Object[3];
int arrayPos = 0;
@@ -194,6 +196,8 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
}
}
sql+=" ORDER BY gl_code ASC";
final Object[] finalObjectArray = Arrays.copyOf(paramaterArray, arrayPos);
return this.jdbcTemplate.query(sql, rm, finalObjectArray);
}
@@ -27,6 +27,7 @@ import org.apache.fineract.accounting.glaccount.command.GLAccountCommand;
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
import org.apache.fineract.accounting.glaccount.exception.GLAccountDisableException;
import org.apache.fineract.accounting.glaccount.exception.GLAccountDuplicateException;
import org.apache.fineract.accounting.glaccount.exception.GLAccountInvalidDeleteException;
import org.apache.fineract.accounting.glaccount.exception.GLAccountInvalidParentException;
@@ -44,10 +45,13 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -60,15 +64,17 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
private final JournalEntryRepository glJournalEntryRepository;
private final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
private final JdbcTemplate jdbcTemplate;
@Autowired
public GLAccountWritePlatformServiceJpaRepositoryImpl(final GLAccountRepository glAccountRepository,
final JournalEntryRepository glJournalEntryRepository, final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final CodeValueRepositoryWrapper codeValueRepositoryWrapper) {
final CodeValueRepositoryWrapper codeValueRepositoryWrapper, final RoutingDataSource dataSource) {
this.glAccountRepository = glAccountRepository;
this.glJournalEntryRepository = glJournalEntryRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Transactional
@@ -115,7 +121,13 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
try {
final GLAccountCommand accountCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
accountCommand.validateForUpdate();
if (command.hasParameter(GLAccountJsonInputParams.DISABLED
.getValue())
&& command
.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.DISABLED
.getValue())) {
validateForAttachedProduct(glAccountId);
}
final Long parentId = command.longValueOfParameterNamed(GLAccountJsonInputParams.PARENT_ID.getValue());
if (glAccountId.equals(parentId)) { throw new InvalidParentGLAccountHeadException(glAccountId, parentId); }
// is the glAccount valid
@@ -165,7 +177,18 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
}
}
@Transactional
private void validateForAttachedProduct(Long glAccountId) {
String sql = "select count(*) from acc_product_mapping acc where acc.gl_account_id = ?";
try {
int count = this.jdbcTemplate.queryForObject(sql, Integer.class, glAccountId);
if (count > 0) {
throw new GLAccountDisableException();
}
} catch (EmptyResultDataAccessException e) {
}
}
@Transactional
@Override
public CommandProcessingResult deleteGLAccount(final Long glAccountId) {
final GLAccount glAccount = this.glAccountRepository.findOne(glAccountId);
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.accounting.journalentry.api;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
@@ -32,9 +33,15 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import io.swagger.annotations.*;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import org.apache.commons.lang.StringUtils;
import org.apache.fineract.accounting.journalentry.command.JournalEntryCommand;
import org.apache.fineract.accounting.journalentry.command.SingleDebitOrCreditEntryCommand;
import org.apache.fineract.accounting.journalentry.data.JournalEntryAssociationParametersData;
import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
import org.apache.fineract.accounting.journalentry.data.OfficeOpeningBalancesData;
@@ -43,6 +50,9 @@ import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioPr
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookPopulatorService;
import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookService;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
@@ -58,6 +68,7 @@ import org.springframework.stereotype.Component;
@Path("/journalentries")
@Component
@Scope("singleton")
@Api(value = "Journal Entries", description = "A journal entry refers to the logging of transactions against general ledger accounts. A journal entry may consist of several line items, each of which is either a \"debit\" or a \"credit\". The total amount of the debits must equal the total amount of the credits or the journal entry is said to be \"unbalanced\" \n" + "\n" + "A journal entry directly changes the account balances on the general ledger")
public class JournalEntriesApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "officeId", "officeName",
@@ -72,31 +83,40 @@ public class JournalEntriesApiResource {
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PlatformSecurityContext context;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final BulkImportWorkbookService bulkImportWorkbookService;
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
@Autowired
public JournalEntriesApiResource(final PlatformSecurityContext context,
final JournalEntryReadPlatformService journalEntryReadPlatformService,
final DefaultToApiJsonSerializer<Object> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final BulkImportWorkbookService bulkImportWorkbookService,
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService) {
this.context = context;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiJsonSerializerService = toApiJsonSerializer;
this.journalEntryReadPlatformService = journalEntryReadPlatformService;
this.bulkImportWorkbookService=bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("glAccountId") final Long glAccountId, @QueryParam("manualEntriesOnly") final Boolean onlyManualEntries,
@QueryParam("fromDate") final DateParam fromDateParam, @QueryParam("toDate") final DateParam toDateParam,
@QueryParam("transactionId") final String transactionId, @QueryParam("entityType") final Integer entityType,
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder,
@QueryParam("locale") final String locale, @QueryParam("dateFormat") final String dateFormat,
@QueryParam("loanId") final Long loanId, @QueryParam("savingsId") final Long savingsId,
@QueryParam("runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") final boolean transactionDetails) {
@ApiOperation(value = "List Journal Entries", notes = "The list capability of journal entries can support pagination and sorting.\n\n" + "Example Requests:\n" + "\n" + "journalentries\n" + "\n" + "journalentries?transactionId=PB37X8Y21EQUY4S\n" + "\n" + "journalentries?officeId=1&manualEntriesOnly=true&fromDate=1 July 2013&toDate=15 July 2013&dateFormat=dd MMMM yyyy&locale=en\n" + "\n" + "journalentries?fields=officeName,glAccountName,transactionDate\n" + "\n" + "journalentries?offset=10&limit=50\n" + "\n" + "journalentries?orderBy=transactionId&sortOrder=DESC\n" + "\n" + "journalentries?runningBalance=true\n" + "\n" + "journalentries?transactionDetails=true\n" + "\n" + "journalentries?loanId=12\n" + "\n" + "journalentries?savingsId=24")
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntryData.class, responseContainer = "list")})
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("officeId") @ApiParam(value = "officeId") final Long officeId,
@QueryParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId, @QueryParam("manualEntriesOnly") @ApiParam(value = "manualEntriesOnly") final Boolean onlyManualEntries,
@QueryParam("fromDate") @ApiParam(value = "fromDate") final DateParam fromDateParam, @QueryParam("toDate") @ApiParam(value = "toDate") final DateParam toDateParam,
@QueryParam("transactionId") @ApiParam(value = "transactionId") final String transactionId, @QueryParam("entityType") @ApiParam(value = "entityType") final Integer entityType,
@QueryParam("offset") @ApiParam(value = "offset") final Integer offset, @QueryParam("limit") @ApiParam(value = "limit") final Integer limit,
@QueryParam("orderBy") @ApiParam(value = "orderBy") final String orderBy, @QueryParam("sortOrder") @ApiParam(value = "sortOrder") final String sortOrder,
@QueryParam("locale") @ApiParam(value = "locale") final String locale, @QueryParam("dateFormat") @ApiParam(value = "dateFormat") final String dateFormat,
@QueryParam("loanId") @ApiParam(value = "loanId") final Long loanId, @QueryParam("savingsId") @ApiParam(value = "savingsId") final Long savingsId,
@QueryParam("runningBalance") @ApiParam(value = "runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") @ApiParam(value = "transactionDetails") final boolean transactionDetails) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -124,8 +144,10 @@ public class JournalEntriesApiResource {
@Path("{journalEntryId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retreiveJournalEntryById(@PathParam("journalEntryId") final Long journalEntryId, @Context final UriInfo uriInfo,
@QueryParam("runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") final boolean transactionDetails) {
@ApiOperation(value = "Retrieve a single Entry", notes = "Example Requests:\n" + "\n" + "journalentries/1\n" + "\n" + "\n" + "\n" + "journalentries/1?fields=officeName,glAccountId,entryType,amount\n" + "\n" + "journalentries/1?runningBalance=true\n" + "\n" + "journalentries/1?transactionDetails=true")
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntryData.class)})
public String retreiveJournalEntryById(@PathParam("journalEntryId") @ApiParam(value = "journalEntryId") final Long journalEntryId, @Context final UriInfo uriInfo,
@QueryParam("runningBalance") @ApiParam(value = "runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") @ApiParam(value = "transactionDetails") final boolean transactionDetails) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(transactionDetails,
@@ -140,7 +162,10 @@ public class JournalEntriesApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createGLJournalEntry(final String jsonRequestBody, @QueryParam("command") final String commandParam) {
@ApiOperation(value = "Create \"Balanced\" Journal Entries", notes = "Note: A Balanced (simple) Journal entry would have atleast one \"Debit\" and one \"Credit\" entry whose amounts are equal \n" + "Compound Journal entries may have \"n\" debits and \"m\" credits where both \"m\" and \"n\" are greater than 0 and the net sum or all debits and credits are equal \n\n" + "\n" + "Mandatory Fields\n" + "officeId, transactionDate\n\n" + "\ncredits- glAccountId, amount, comments\n\n " + "\ndebits- glAccountId, amount, comments\n\n " + "\n" + "Optional Fields\n" + "paymentTypeId, accountNumber, checkNumber, routingCode, receiptNumber, bankNumber")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = JournalEntryCommand.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntriesApiResourceSwagger.PostJournalEntriesResponse.class)})
public String createGLJournalEntry(@ApiParam(hidden = true) final String jsonRequestBody, @QueryParam("command") @ApiParam(value = "command") final String commandParam) {
CommandProcessingResult result = null;
if (is(commandParam, "updateRunningBalance")) {
@@ -162,8 +187,11 @@ public class JournalEntriesApiResource {
@Path("{transactionId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createReversalJournalEntry(final String jsonRequestBody, @PathParam("transactionId") final String transactionId,
@QueryParam("command") final String commandParam) {
@ApiOperation(value = "Update Running balances for Journal Entries", notes = "This API calculates the running balances for office. If office ID not provided this API calculates running balances for all offices. \n" + "Mandatory Fields\n" + "officeId")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = JournalEntriesApiResourceSwagger.PostJournalEntriesTransactionIdRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntriesApiResourceSwagger.PostJournalEntriesTransactionIdResponse.class)})
public String createReversalJournalEntry(@ApiParam(hidden = true) final String jsonRequestBody, @PathParam("transactionId") @ApiParam(value = "transactionId") final String transactionId,
@QueryParam("command") @ApiParam(value = "command") final String commandParam) {
CommandProcessingResult result = null;
if (is(commandParam, "reverse")) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().reverseJournalEntry(transactionId).withJson(jsonRequestBody)
@@ -187,14 +215,14 @@ public class JournalEntriesApiResource {
SearchParameters params = SearchParameters.forPagination(offset, limit) ;
Page<JournalEntryData> entries = this.journalEntryReadPlatformService.retrieveAll(params, null, null, null, null, transactionId, PortfolioProductType.PROVISIONING.getValue(), null) ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.apiJsonSerializerService.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
return this.apiJsonSerializerService.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("openingbalance")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Path("openingbalance")
public String retrieveOpeningBalance(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("currencyCode") final String currencyCode) {
@@ -208,4 +236,25 @@ public class JournalEntriesApiResource {
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
@GET
@Path("downloadtemplate")
@Produces("application/vnd.ms-excel")
public Response getJournalEntriesTemplate(@QueryParam("officeId") final Long officeId,
@QueryParam("dateFormat") final String dateFormat) {
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.GL_JOURNAL_ENTRIES.toString(),
officeId,null,dateFormat);
}
@POST
@Path("uploadtemplate")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postJournalEntriesTemplate(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail,
@FormDataParam("locale") final String locale,
@FormDataParam("dateFormat") final String dateFormat){
final Long importDocumentId =this.bulkImportWorkbookService.importWorkbook(GlobalEntityType.GL_JOURNAL_ENTRIES.toString(),
uploadedInputStream,fileDetail, locale,dateFormat);
return this.apiJsonSerializerService.serialize(importDocumentId);
}
}
@@ -0,0 +1,61 @@
/**
* 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.accounting.journalentry.api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.joda.time.LocalDate;
/**
* Created by sanyam on 25/7/17.
*/
final class JournalEntriesApiResourceSwagger {
private JournalEntriesApiResourceSwagger(){}
@ApiModel(value = "PostJournalEntriesResponse")
public static final class PostJournalEntriesResponse {
private PostJournalEntriesResponse(){
}
@ApiModelProperty(value = "1")
public Long officeId;
@ApiModelProperty(value = "RS9MCISID4WK1ZM")
public String transactionId;
}
@ApiModel(value = "PostJournalEntriesTransactionIdRequest")
public static final class PostJournalEntriesTransactionIdRequest {
private PostJournalEntriesTransactionIdRequest() {
}
@ApiModelProperty(value = "1")
public Long officeId;
}
@ApiModel(value = "PostJournalEntriesTransactionIdResponse")
public static final class PostJournalEntriesTransactionIdResponse {
private PostJournalEntriesTransactionIdResponse() {
}
@ApiModelProperty(value = "1")
public Long officeId;
}
}
@@ -0,0 +1,31 @@
/**
* 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.accounting.journalentry.data;
import java.math.BigDecimal;
public class CreditDebit {
private final Long glAccountId;
private final BigDecimal amount;
public CreditDebit(Long glAccountId, BigDecimal amount) {
this.glAccountId = glAccountId;
this.amount = amount;
}
}
@@ -19,8 +19,10 @@
package org.apache.fineract.accounting.journalentry.data;
import java.math.BigDecimal;
import java.util.List;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.joda.time.LocalDate;
@@ -78,6 +80,91 @@ public class JournalEntryData {
@SuppressWarnings("unused")
private final TransactionDetailData transactionDetails;
//import fields
private transient Integer rowIndex;
private String dateFormat;
private String locale;
private List<CreditDebit> credits;
private List<CreditDebit> debits;
private Long paymentTypeId;
private String currencyCode;
private String accountNumber;
private String checkNumber;
private String routingCode;
private String receiptNumber;
private String bankNumber;
public static JournalEntryData importInstance(Long officeId,LocalDate transactionDate,String currencyCode, Long paymentTypeId,
Integer rowIndex,List<CreditDebit> credits, List<CreditDebit>debits,
String accountNumber,String checkNumber,String routingCode,String receiptNumber,String bankNumber,
String comments,String locale,String dateFormat){
return new JournalEntryData(officeId, transactionDate, currencyCode,
paymentTypeId, rowIndex, credits, debits,accountNumber,checkNumber,routingCode,
receiptNumber,bankNumber,comments,locale,dateFormat);
}
private JournalEntryData(Long officeId,LocalDate transactionDate,String currencyCode, Long paymentTypeId,
Integer rowIndex,List<CreditDebit> credits, List<CreditDebit>debits,
String accountNumber,String checkNumber,String routingCode,String receiptNumber,
String bankNumber,String comments,String locale,String dateFormat) {
this.officeId = officeId;
this.dateFormat= dateFormat;
this.locale= locale;
this.transactionDate = transactionDate;
this.currencyCode=currencyCode;
this.rowIndex = rowIndex;
this.credits = credits;
this.debits = debits;
this.paymentTypeId = paymentTypeId;
this.accountNumber=accountNumber;
this.checkNumber=checkNumber;
this.routingCode=routingCode;
this.receiptNumber=receiptNumber;
this.bankNumber=bankNumber;
this.comments=comments;
this.id = null;
this.officeName = null;
this.glAccountName = null;
this.glAccountId = null;
this.glAccountCode = null;
this.glAccountType = null;
this.entryType = null;
this.amount = null;
this.currency = null;
this.transactionId = null;
this.manualEntry = null;
this.entityType = null;
this.entityId = null;
this.createdByUserId = null;
this.createdDate = null;
this.createdByUserName = null;
this.reversed = null;
this.referenceNumber = null;
this.officeRunningBalance = null;
this.organizationRunningBalance = null;
this.runningBalanceComputed = null;
this.transactionDetails = null;
}
public Integer getRowIndex() {
return rowIndex;
}
public LocalDate getTransactionDate() {
return transactionDate;
}
public void addDebits(CreditDebit debit) {
this.debits.add(debit);
}
public void addCredits(CreditDebit credit) {
this.credits.add(credit);
}
public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName,
final Long glAccountId, final String glAccountCode, final EnumOptionData glAccountClassification,
final LocalDate transactionDate, final EnumOptionData entryType, final BigDecimal amount, final String transactionId,
@@ -42,7 +42,7 @@ public class JournalEntryDataValidator {
private final FromJsonHelper fromApiJsonHelper;
public static final Set<String> RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<>(
private final Set<String> RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(JournalEntryJsonInputParams.OFFICE_ID.getValue()));
@Autowired
@@ -0,0 +1,29 @@
/**
* 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.accounting.journalentry.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class JournalEntryRuntimeException extends AbstractPlatformDomainRuleException {
public JournalEntryRuntimeException(String errorCode, String errorMessage) {
super(errorCode, errorMessage);
}
}
@@ -379,18 +379,17 @@ public class AccountingProcessorHelper {
* The target accounts for debits and credits are switched in case of a
* reversal
*
* @param office
* @param accountTypeToBeDebited
* Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited
* Enum of the placeholder of the GLAccount to be credited
* @param loanProductId
* @param paymentTypeId
* @param loanId
* @param transactionId
* @param transactionDate
* @param amount
* @param isReversal
* @param office office
* @param currencyCode currencyCode
* @param accountTypeToBeDebited Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited Enum of the placeholder of the GLAccount to be credited
* @param loanProductId loanProductId
* @param loanId loanId
* @param transactionId transactionId
* @param transactionDate transactionDate
* @param totalAmount totalAmount
* @param isReversal isReversal
* @param chargePaymentDTOs chargePaymentDTOs
*/
public void createAccrualBasedJournalEntriesAndReversalsForLoanCharges(final Office office, final String currencyCode,
final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId, final Long loanId,
@@ -568,17 +567,17 @@ public class AccountingProcessorHelper {
* reversal
*
* @param office
* @param accountTypeToBeDebited
* Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited
* Enum of the placeholder of the GLAccount to be credited
* @param currencyCode
* @param accountTypeToBeDebited Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited Enum of the placeholder of the GLAccount to be credited
* @param savingsProductId
* @param paymentTypeId
* @param loanId
* @param savingsId
* @param transactionId
* @param transactionDate
* @param amount
* @param isReversal
* @param taxDetails
*/
public void createCashBasedJournalEntriesAndReversalsForSavingsTax(final Office office, final String currencyCode,
final CASH_ACCOUNTS_FOR_SAVINGS accountTypeToBeDebited, final CASH_ACCOUNTS_FOR_SAVINGS accountTypeToBeCredited,
@@ -726,18 +725,18 @@ public class AccountingProcessorHelper {
* The target accounts for debits and credits are switched in case of a
* reversal
*
* @param office
* @param accountTypeToBeDebited
* Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited
* Enum of the placeholder of the GLAccount to be credited
* @param savingsProductId
* @param paymentTypeId
* @param loanId
* @param transactionId
* @param transactionDate
* @param amount
* @param isReversal
* @param office office
* @param currencyCode currencyCode
* @param accountTypeToBeDebited Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited Enum of the placeholder of the GLAccount to be credited
* @param savingsProductId savingsProductId
* @param paymentTypeId paymentTypeId
* @param loanId loanId
* @param transactionId transactionId
* @param transactionDate transactionDate
* @param totalAmount totalAmount
* @param isReversal isReversal
* @param chargePaymentDTOs chargePaymentDTOs
*/
public void createCashBasedJournalEntriesAndReversalsForSavingsCharges(final Office office, final String currencyCode,
final CASH_ACCOUNTS_FOR_SAVINGS accountTypeToBeDebited, final CASH_ACCOUNTS_FOR_SAVINGS accountTypeToBeCredited,
@@ -116,15 +116,20 @@ public class CashBasedAccountingProcessorForShares implements AccountingProcesso
CASH_ACCOUNTS_FOR_SHARES.SHARES_EQUITY.getValue(), shareProductId, paymentTypeId, shareAccountId, transactionId,
transactionDate, amountForJE);
} else if (transactionDTO.getTransactionStatus().isRejected()) {
BigDecimal amountForJE = amount;
if (chargeAmount != null && chargeAmount.compareTo(BigDecimal.ZERO) == 1) {
amountForJE = amount.subtract(chargeAmount);
/*this.helper.revertCashBasedJournalEntryForSharesCharges(office, currencyCode, CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES,
shareProductId, shareAccountId, transactionId, transactionDate, chargeAmount, feePayments);*/
this.helper.revertCashBasedJournalEntryForSharesCharges(office, currencyCode, CASH_ACCOUNTS_FOR_SHARES.INCOME_FROM_FEES,
shareProductId, shareAccountId, transactionId, transactionDate, chargeAmount, feePayments);
this.helper.createDebitJournalEntryForShares(office, currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(), shareProductId, paymentTypeId, shareAccountId,
transactionId, transactionDate, amount.subtract(chargeAmount));
this.helper.createCreditJournalEntryForShares(office, currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(), shareProductId, paymentTypeId, shareAccountId,
transactionId, transactionDate, amount);
}else{
this.helper.createJournalEntriesForShares(office, currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(),
CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(), shareProductId, paymentTypeId, shareAccountId, transactionId,
transactionDate, amount);
}
this.helper.createJournalEntriesForShares(office, currencyCode, CASH_ACCOUNTS_FOR_SHARES.SHARES_SUSPENSE.getValue(),
CASH_ACCOUNTS_FOR_SHARES.SHARES_REFERENCE.getValue(), shareProductId, paymentTypeId, shareAccountId, transactionId,
transactionDate, amountForJE);
}
}
@@ -49,6 +49,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.office.data.OfficeData;
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
@@ -74,18 +75,22 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
private final JdbcTemplate jdbcTemplate;
private final GLAccountReadPlatformService glAccountReadPlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
private final ColumnValidator columnValidator;
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper;
private final PaginationHelper<JournalEntryData> paginationHelper = new PaginationHelper<>();
@Autowired
public JournalEntryReadPlatformServiceImpl(final RoutingDataSource dataSource,
final GLAccountReadPlatformService glAccountReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
final GLAccountReadPlatformService glAccountReadPlatformService,
final ColumnValidator columnValidator,
final OfficeReadPlatformService officeReadPlatformService,
final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.glAccountReadPlatformService = glAccountReadPlatformService;
this.officeReadPlatformService = officeReadPlatformService;
this.financialActivityAccountRepositoryWrapper = financialActivityAccountRepositoryWrapper;
this.columnValidator = columnValidator;
}
private static final class GLJournalEntryMapper implements RowMapper<JournalEntryData> {
@@ -356,9 +361,11 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
if (searchParameters.isOrderByRequested()) {
sqlBuilder.append(" order by ").append(searchParameters.getOrderBy());
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getOrderBy());
if (searchParameters.isSortOrderProvided()) {
sqlBuilder.append(' ').append(searchParameters.getSortOrder());
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getOrderBy());
}
} else {
sqlBuilder.append(" order by journalEntry.entry_date, journalEntry.id");

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