Compare commits
500
Commits
@@ -0,0 +1,17 @@
|
|||||||
|
github:
|
||||||
|
description: "Apache Fineract"
|
||||||
|
homepage: https://fineract.apache.org
|
||||||
|
labels:
|
||||||
|
- apache
|
||||||
|
- banking
|
||||||
|
- finance
|
||||||
|
- fintech
|
||||||
|
- group-lending
|
||||||
|
- group-savings
|
||||||
|
- java
|
||||||
|
- lending
|
||||||
|
- loans
|
||||||
|
- microfinance
|
||||||
|
- savings
|
||||||
|
- social-impact
|
||||||
|
- tech4good
|
||||||
@@ -1,35 +1,31 @@
|
|||||||
name: Fineract Docker build - MariaDB
|
name: Fineract Docker build - MariaDB
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
IMAGE_NAME: fineract
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
- name: Build the image
|
- name: Build the image
|
||||||
run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
|
run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
|
||||||
- name: Start the stack
|
- name: Start the stack
|
||||||
run: docker compose up -d
|
run: docker compose -f docker-compose.yml up -d
|
||||||
- name: Wait for stack to come up
|
|
||||||
run: sleep 500
|
|
||||||
- name: Check the stack
|
- name: Check the stack
|
||||||
run: docker ps
|
run: docker ps
|
||||||
- name: Check health
|
- name: Check health
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
||||||
- name: Check info
|
- name: Check info
|
||||||
run: (( $(curl -f -k --retry 5 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
||||||
|
|||||||
@@ -1,35 +1,31 @@
|
|||||||
name: Fineract Docker build - PostgreSQL
|
name: Fineract Docker build - PostgreSQL
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
IMAGE_NAME: fineract
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
- name: Build the image
|
- name: Build the image
|
||||||
run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
|
run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
|
||||||
- name: Start the Standalone Stack
|
- name: Start the Standalone Stack
|
||||||
run: docker compose -f docker-compose-postgresql.yml up -d
|
run: docker compose -f docker-compose-postgresql.yml up -d
|
||||||
- name: Wait for stack to come up
|
|
||||||
run: sleep 500
|
|
||||||
- name: Check the stack
|
- name: Check the stack
|
||||||
run: docker ps
|
run: docker ps
|
||||||
- name: Check health
|
- name: Check health
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
||||||
- name: Check info
|
- name: Check info
|
||||||
run: (( $(curl -f -k --retry 5 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
||||||
|
|||||||
@@ -1,36 +1,34 @@
|
|||||||
name: Fineract Documentation build
|
name: Fineract Documentation build
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle
|
||||||
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
|
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16
|
||||||
- name: Congfigure vega-cli
|
- name: Congfigure vega-cli
|
||||||
run: npm i -g vega-cli --unsafe
|
run: npm i -g vega-cli --unsafe
|
||||||
- name: Validate Gradle wrapper
|
- name: Validate Gradle wrapper
|
||||||
uses: gradle/wrapper-validation-action@88425854a36845f9c881450d9660b5fd46bee142
|
uses: gradle/wrapper-validation-action@f9c9c575b8b21b6485636a91ffecd10e558c62f6
|
||||||
- name: Install additional software
|
- name: Install additional software
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install ghostscript graphviz -y
|
sudo apt-get install ghostscript graphviz -y
|
||||||
|
|
||||||
- name: Documentation build
|
- name: Documentation build
|
||||||
run: ./gradlew --no-daemon --console=plain doc
|
run: ./gradlew --no-daemon --console=plain doc
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
name: Fineract Build Progressive Loan Embeddable Jar & Test with a Sample Application
|
||||||
|
on: [push, pull_request]
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'zulu'
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
|
- name: Build Embeddable Jar
|
||||||
|
run: ./gradlew --no-daemon --console=plain :fineract-progressive-loan-embeddable-schedule-generator:shadowJar
|
||||||
|
- name: Pick up the JAR filename
|
||||||
|
run: |
|
||||||
|
EMBEDDABLE_JAR_FILE=(`ls fineract-progressive-loan-embeddable-schedule-generator/build/libs/*-all.jar | head -n 1`)
|
||||||
|
echo "EMBEDDABLE_JAR_FILE=$EMBEDDABLE_JAR_FILE" >> $GITHUB_ENV
|
||||||
|
- name: Run unit tests
|
||||||
|
run: ./gradlew --no-daemon --console=plain :fineract-progressive-loan-embeddable-schedule-generator:test
|
||||||
|
- name: Build Sample Application
|
||||||
|
run: |
|
||||||
|
mkdir sample-app
|
||||||
|
javac -cp $EMBEDDABLE_JAR_FILE -d sample-app fineract-progressive-loan-embeddable-schedule-generator/misc/Main.java
|
||||||
|
env:
|
||||||
|
EMBEDDABLE_JAR_FILE: ${{ env.EMBEDDABLE_JAR_FILE }}
|
||||||
|
- name: Run Schedule Generator Sample Application
|
||||||
|
run: |
|
||||||
|
java -cp $EMBEDDABLE_JAR_FILE:sample-app Main
|
||||||
|
java -cp $EMBEDDABLE_JAR_FILE:sample-app Main 25
|
||||||
|
env:
|
||||||
|
EMBEDDABLE_JAR_FILE: ${{ env.EMBEDDABLE_JAR_FILE }}
|
||||||
|
- name: Archive test results
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
|
with:
|
||||||
|
name: test-results
|
||||||
|
path: |
|
||||||
|
build/reports/
|
||||||
|
fineract-progressive-loan-embeddable-schedule-generator/build/reports/
|
||||||
@@ -1,51 +1,42 @@
|
|||||||
name: Fineract Build & Test - MariaDB
|
name: Fineract Build & Test - MariaDB
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mariad:
|
mariad:
|
||||||
image: mariadb:11.2
|
image: mariadb:11.5.2
|
||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
env:
|
env:
|
||||||
MARIADB_ROOT_PASSWORD: mysql
|
MARIADB_ROOT_PASSWORD: mysql
|
||||||
options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=5s --health-timeout=2s --health-retries=3
|
options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||||
|
|
||||||
mock-oauth2-server:
|
mock-oauth2-server:
|
||||||
image: ghcr.io/navikt/mock-oauth2-server:2.1.1
|
image: ghcr.io/navikt/mock-oauth2-server:2.1.10
|
||||||
ports:
|
ports:
|
||||||
- 9000:9000
|
- 9000:9000
|
||||||
env:
|
env:
|
||||||
SERVER_PORT: 9000
|
SERVER_PORT: 9000
|
||||||
JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
|
JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
TZ: Asia/Kolkata
|
TZ: Asia/Kolkata
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle and Validate Wrapper
|
||||||
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
validate-wrappers: true
|
||||||
- name: Congfigure vega-cli
|
|
||||||
run: npm i -g vega-cli --unsafe
|
|
||||||
- name: Validate Gradle wrapper
|
|
||||||
uses: gradle/wrapper-validation-action@88425854a36845f9c881450d9660b5fd46bee142
|
|
||||||
- name: Verify MariaDB connection
|
- name: Verify MariaDB connection
|
||||||
run: |
|
run: |
|
||||||
while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
|
while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
|
||||||
@@ -66,11 +57,6 @@ jobs:
|
|||||||
sleep 10
|
sleep 10
|
||||||
docker exec localstack awslocal s3api create-bucket --bucket fineract-reports
|
docker exec localstack awslocal s3api create-bucket --bucket fineract-reports
|
||||||
echo "LocalStack initialization complete"
|
echo "LocalStack initialization complete"
|
||||||
- name: Install additional software
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install ghostscript graphviz -y
|
|
||||||
|
|
||||||
- name: Build & Test
|
- name: Build & Test
|
||||||
env:
|
env:
|
||||||
AWS_ENDPOINT_URL: http://localhost:4566
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
@@ -85,10 +71,9 @@ jobs:
|
|||||||
./gradlew --no-daemon --console=plain test -x :twofactor-tests:test -x :oauth2-test:test -x :fineract-e2e-tests-runner:test
|
./gradlew --no-daemon --console=plain test -x :twofactor-tests:test -x :oauth2-test:test -x :fineract-e2e-tests-runner:test
|
||||||
./gradlew --no-daemon --console=plain :twofactor-tests:test
|
./gradlew --no-daemon --console=plain :twofactor-tests:test
|
||||||
./gradlew --no-daemon --console=plain :oauth2-tests:test
|
./gradlew --no-daemon --console=plain :oauth2-tests:test
|
||||||
|
|
||||||
- name: Archive test results
|
- name: Archive test results
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: test-results
|
name: test-results
|
||||||
path: |
|
path: |
|
||||||
@@ -96,10 +81,9 @@ jobs:
|
|||||||
integration-tests/build/reports/
|
integration-tests/build/reports/
|
||||||
twofactor-tests/build/reports/
|
twofactor-tests/build/reports/
|
||||||
oauth2-tests/build/reports/
|
oauth2-tests/build/reports/
|
||||||
|
|
||||||
- name: Archive server logs
|
- name: Archive server logs
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: server-logs
|
name: server-logs
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
@@ -1,51 +1,42 @@
|
|||||||
name: Fineract Build & Test - MySQL
|
name: Fineract Build & Test - MySQL
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mariad:
|
mariad:
|
||||||
image: mysql:8.3
|
image: mysql:9.1
|
||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
env:
|
env:
|
||||||
MYSQL_ROOT_PASSWORD: mysql
|
MYSQL_ROOT_PASSWORD: mysql
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||||
|
|
||||||
mock-oauth2-server:
|
mock-oauth2-server:
|
||||||
image: ghcr.io/navikt/mock-oauth2-server:2.1.1
|
image: ghcr.io/navikt/mock-oauth2-server:2.1.10
|
||||||
ports:
|
ports:
|
||||||
- 9000:9000
|
- 9000:9000
|
||||||
env:
|
env:
|
||||||
SERVER_PORT: 9000
|
SERVER_PORT: 9000
|
||||||
JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
|
JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
TZ: Asia/Kolkata
|
TZ: Asia/Kolkata
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle and Validate Wrapper
|
||||||
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
validate-wrappers: true
|
||||||
- name: Congfigure vega-cli
|
|
||||||
run: npm i -g vega-cli --unsafe
|
|
||||||
- name: Validate Gradle wrapper
|
|
||||||
uses: gradle/wrapper-validation-action@88425854a36845f9c881450d9660b5fd46bee142
|
|
||||||
- name: Verify MariaDB connection
|
- name: Verify MariaDB connection
|
||||||
run: |
|
run: |
|
||||||
while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
|
while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
|
||||||
@@ -66,11 +57,6 @@ jobs:
|
|||||||
sleep 10
|
sleep 10
|
||||||
docker exec localstack awslocal s3api create-bucket --bucket fineract-reports
|
docker exec localstack awslocal s3api create-bucket --bucket fineract-reports
|
||||||
echo "LocalStack initialization complete"
|
echo "LocalStack initialization complete"
|
||||||
- name: Install additional software
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install ghostscript graphviz -y
|
|
||||||
|
|
||||||
- name: Build & Test
|
- name: Build & Test
|
||||||
env:
|
env:
|
||||||
AWS_ENDPOINT_URL: http://localhost:4566
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
@@ -85,10 +71,9 @@ jobs:
|
|||||||
./gradlew --no-daemon --console=plain test -x :twofactor-tests:test -x :oauth2-test:test :fineract-e2e-tests-runner:test -PdbType=mysql
|
./gradlew --no-daemon --console=plain test -x :twofactor-tests:test -x :oauth2-test:test :fineract-e2e-tests-runner:test -PdbType=mysql
|
||||||
./gradlew --no-daemon --console=plain :twofactor-tests:test -PdbType=mysql
|
./gradlew --no-daemon --console=plain :twofactor-tests:test -PdbType=mysql
|
||||||
./gradlew --no-daemon --console=plain :oauth2-tests:test -PdbType=mysql
|
./gradlew --no-daemon --console=plain :oauth2-tests:test -PdbType=mysql
|
||||||
|
|
||||||
- name: Archive test results
|
- name: Archive test results
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: test-results
|
name: test-results
|
||||||
path: |
|
path: |
|
||||||
@@ -96,10 +81,9 @@ jobs:
|
|||||||
integration-tests/build/reports/
|
integration-tests/build/reports/
|
||||||
twofactor-tests/build/reports/
|
twofactor-tests/build/reports/
|
||||||
oauth2-tests/build/reports/
|
oauth2-tests/build/reports/
|
||||||
|
|
||||||
- name: Archive server logs
|
- name: Archive server logs
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: server-logs
|
name: server-logs
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
@@ -1,52 +1,43 @@
|
|||||||
name: Fineract Build & Test - PostgreSQL
|
name: Fineract Build & Test - PostgreSQL
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgresql:
|
postgresql:
|
||||||
image: postgres:16.1
|
image: postgres:17.4
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
env:
|
env:
|
||||||
POSTGRES_USER: root
|
POSTGRES_USER: root
|
||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
options: --health-cmd="pg_isready -q -d postgres -U root" --health-interval=5s --health-timeout=2s --health-retries=3
|
options: --health-cmd="pg_isready -q -d postgres -U root" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||||
|
|
||||||
mock-oauth2-server:
|
mock-oauth2-server:
|
||||||
image: ghcr.io/navikt/mock-oauth2-server:2.1.1
|
image: ghcr.io/navikt/mock-oauth2-server:2.1.10
|
||||||
ports:
|
ports:
|
||||||
- 9000:9000
|
- 9000:9000
|
||||||
env:
|
env:
|
||||||
SERVER_PORT: 9000
|
SERVER_PORT: 9000
|
||||||
JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
|
JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
TZ: Asia/Kolkata
|
TZ: Asia/Kolkata
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle and Validate Wrapper
|
||||||
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
validate-wrappers: true
|
||||||
- name: Congfigure vega-cli
|
|
||||||
run: npm i -g vega-cli --unsafe
|
|
||||||
- name: Validate Gradle wrapper
|
|
||||||
uses: gradle/wrapper-validation-action@88425854a36845f9c881450d9660b5fd46bee142
|
|
||||||
- name: Verify PostgreSQL connection
|
- name: Verify PostgreSQL connection
|
||||||
run: |
|
run: |
|
||||||
while ! pg_isready -d postgres -U root -h 127.0.0.1 -p 5432 ; do
|
while ! pg_isready -d postgres -U root -h 127.0.0.1 -p 5432 ; do
|
||||||
@@ -67,11 +58,6 @@ jobs:
|
|||||||
sleep 10
|
sleep 10
|
||||||
docker exec localstack awslocal s3api create-bucket --bucket fineract-reports
|
docker exec localstack awslocal s3api create-bucket --bucket fineract-reports
|
||||||
echo "LocalStack initialization complete"
|
echo "LocalStack initialization complete"
|
||||||
- name: Install additional software
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install ghostscript graphviz -y
|
|
||||||
|
|
||||||
- name: Build & Test
|
- name: Build & Test
|
||||||
env:
|
env:
|
||||||
AWS_ENDPOINT_URL: http://localhost:4566
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
@@ -86,10 +72,9 @@ jobs:
|
|||||||
./gradlew --no-daemon --console=plain test -x :twofactor-tests:test -x :oauth2-test:test :fineract-e2e-tests-runner:test -PdbType=postgresql
|
./gradlew --no-daemon --console=plain test -x :twofactor-tests:test -x :oauth2-test:test :fineract-e2e-tests-runner:test -PdbType=postgresql
|
||||||
./gradlew --no-daemon --console=plain :twofactor-tests:test -PdbType=postgresql
|
./gradlew --no-daemon --console=plain :twofactor-tests:test -PdbType=postgresql
|
||||||
./gradlew --no-daemon --console=plain :oauth2-tests:test -PdbType=postgresql
|
./gradlew --no-daemon --console=plain :oauth2-tests:test -PdbType=postgresql
|
||||||
|
|
||||||
- name: Archive test results
|
- name: Archive test results
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: test-results
|
name: test-results
|
||||||
path: |
|
path: |
|
||||||
@@ -97,10 +82,9 @@ jobs:
|
|||||||
integration-tests/build/reports/
|
integration-tests/build/reports/
|
||||||
twofactor-tests/build/reports/
|
twofactor-tests/build/reports/
|
||||||
oauth2-tests/build/reports/
|
oauth2-tests/build/reports/
|
||||||
|
|
||||||
- name: Archive server logs
|
- name: Archive server logs
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: server-logs
|
name: server-logs
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
@@ -1,42 +1,41 @@
|
|||||||
name: Fineract Tests
|
name: Fineract Tests
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
IMAGE_NAME: fineract
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
- name: Build the image
|
- name: Build the image
|
||||||
run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
|
run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
|
||||||
- name: Start the Fineract stack
|
- name: Start the Fineract stack
|
||||||
run: docker compose -f docker-compose-postgresql.yml up -d
|
run: docker compose -f docker-compose-postgresql-test-activemq.yml up -d
|
||||||
- name: Wait for stack to come up
|
|
||||||
run: sleep 400
|
|
||||||
- name: Check the stack
|
- name: Check the stack
|
||||||
run: docker ps
|
run: docker ps
|
||||||
- name: Check health Manager
|
- name: Check health Manager
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
||||||
- name: Execute tests
|
- name: Execute tests
|
||||||
env:
|
env:
|
||||||
BASE_URL: https://localhost:8443
|
BASE_URL: https://localhost:8443
|
||||||
TEST_USERNAME: mifos
|
TEST_USERNAME: mifos
|
||||||
TEST_PASSWORD: password
|
TEST_PASSWORD: password
|
||||||
|
TEST_STRONG_PASSWORD: A1b2c3d4e5f$
|
||||||
TEST_TENANT_ID: default
|
TEST_TENANT_ID: default
|
||||||
INITIALIZATION_ENABLED: true
|
INITIALIZATION_ENABLED: true
|
||||||
EVENT_VERIFICATION_ENABLED: false
|
EVENT_VERIFICATION_ENABLED: true
|
||||||
run: ./gradlew --no-daemon --console=plain fineract-e2e-tests-runner:cucumber --tags 'not @Skip' allureReport
|
ACTIVEMQ_BROKER_URL: tcp://localhost:61616
|
||||||
|
ACTIVEMQ_TOPIC_NAME: events
|
||||||
|
run: ./gradlew --no-daemon --console=plain :fineract-e2e-tests-runner:cucumber --tags 'not @Skip' allureReport
|
||||||
|
|||||||
@@ -1,36 +1,52 @@
|
|||||||
name: Fineract Publish to DockerHub
|
name: Fineract Publish to DockerHub
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
tags:
|
tags:
|
||||||
- 1.*
|
- 1.*
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Source Code
|
- name: Checkout Source Code
|
||||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
|
|
||||||
- name: Extract branch name
|
- name: Extract branch name
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||||
id: extract_branch
|
id: extract_branch
|
||||||
|
|
||||||
|
- name: Get Git Hashes
|
||||||
|
run: |
|
||||||
|
echo "short_hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
echo "long_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
id: git_hashes
|
||||||
|
|
||||||
- name: Build the Apache Fineract image
|
- name: Build the Apache Fineract image
|
||||||
run: |
|
run: |
|
||||||
./gradlew --no-daemon --console=plain :fineract-provider:jib -x test -x cucumber -Djib.to.auth.username=${{secrets.DOCKERHUB_USER}} -Djib.to.auth.password=${{secrets.DOCKERHUB_TOKEN}} -Djib.from.platforms=linux/amd64,linux/arm64 -Djib.to.image=apache/fineract -Djib.to.tags=${{ steps.extract_branch.outputs.branch }}
|
TAGS=${{ steps.extract_branch.outputs.branch }}
|
||||||
|
if [ "${{ steps.extract_branch.outputs.branch }}" == "develop" ]; then
|
||||||
|
TAGS="$TAGS,${{ steps.git_hashes.outputs.short_hash }},${{ steps.git_hashes.outputs.long_hash }}"
|
||||||
|
fi
|
||||||
|
./gradlew --no-daemon --console=plain :fineract-provider:jib -x test -x cucumber \
|
||||||
|
-Djib.to.auth.username=${{secrets.DOCKERHUB_USER}} \
|
||||||
|
-Djib.to.auth.password=${{secrets.DOCKERHUB_TOKEN}} \
|
||||||
|
-Djib.from.platforms=linux/amd64,linux/arm64 \
|
||||||
|
-Djib.to.image=apache/fineract \
|
||||||
|
-Djib.to.tags=$TAGS
|
||||||
|
|||||||
@@ -1,41 +1,37 @@
|
|||||||
name: Fineract ActiveMQ Smoke
|
name: Fineract ActiveMQ Smoke
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
IMAGE_NAME: fineract
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
- name: Build the image
|
- name: Build the image
|
||||||
run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
|
run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
|
||||||
- name: Start the ActiveMQ Stack
|
- name: Start the ActiveMQ Stack
|
||||||
run: docker compose -f docker-compose-postgresql-activemq.yml up --scale fineract-worker=1 -d
|
run: docker compose -f docker-compose-postgresql-activemq.yml up --scale fineract-worker=1 -d
|
||||||
- name: Wait for stack to come up
|
|
||||||
run: sleep 500
|
|
||||||
- name: Check the stack
|
- name: Check the stack
|
||||||
run: docker ps
|
run: docker ps
|
||||||
- name: Check health Manager
|
- name: Check health Manager
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
||||||
- name: Check health Worker1
|
- name: Check health Worker1
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/health
|
||||||
- name: Check info Manager
|
- name: Check info Manager
|
||||||
run: (( $(curl -f -k --retry 5 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
||||||
- name: Check info Worker1
|
- name: Check info Worker1
|
||||||
run: (( $(curl -f -k --retry 5 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/info | wc --chars) > 100 ))
|
run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/info | wc --chars) > 100 ))
|
||||||
- name: Run Smoke Test with Remote COB
|
- name: Run Smoke Test with Remote COB
|
||||||
run: ./gradlew --no-daemon --console=plain :integration-tests:cleanTest :integration-tests:test --tests "org.apache.fineract.integrationtests.investor.externalassetowner.InitiateExternalAssetOwnerTransferTest.saleActiveLoanToExternalAssetOwnerAndBuybackADayLater" -PcargoDisabled
|
run: ./gradlew --no-daemon --console=plain :integration-tests:cleanTest :integration-tests:test --tests "org.apache.fineract.integrationtests.investor.externalassetowner.InitiateExternalAssetOwnerTransferTest.saleActiveLoanToExternalAssetOwnerAndBuybackADayLater" -PcargoDisabled
|
||||||
|
|||||||
@@ -1,41 +1,37 @@
|
|||||||
name: Fineract Kafka Smoke
|
name: Fineract Kafka Smoke
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
IMAGE_NAME: fineract
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
- name: Build the image
|
- name: Build the image
|
||||||
run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
|
run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
|
||||||
- name: Start the Kafka Stack
|
- name: Start the Kafka Stack
|
||||||
run: docker compose -f docker-compose-postgresql-kafka.yml up --scale fineract-worker=1 -d
|
run: docker compose -f docker-compose-postgresql-kafka.yml up --scale fineract-worker=1 -d
|
||||||
- name: Wait for stack to come up
|
|
||||||
run: sleep 500
|
|
||||||
- name: Check the stack
|
- name: Check the stack
|
||||||
run: docker ps
|
run: docker ps
|
||||||
- name: Check health Manager
|
- name: Check health Manager
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
|
||||||
- name: Check health Worker1
|
- name: Check health Worker1
|
||||||
run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/health
|
run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/health
|
||||||
- name: Check info Manager
|
- name: Check info Manager
|
||||||
run: (( $(curl -f -k --retry 5 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
|
||||||
- name: Check info Worker1
|
- name: Check info Worker1
|
||||||
run: (( $(curl -f -k --retry 5 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/info | wc --chars) > 100 ))
|
run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/info | wc --chars) > 100 ))
|
||||||
- name: Run Smoke Test with Remote COB
|
- name: Run Smoke Test with Remote COB
|
||||||
run: ./gradlew --no-daemon --console=plain :integration-tests:cleanTest :integration-tests:test --tests "org.apache.fineract.integrationtests.investor.externalassetowner.InitiateExternalAssetOwnerTransferTest.saleActiveLoanToExternalAssetOwnerAndBuybackADayLater" -PcargoDisabled
|
run: ./gradlew --no-daemon --console=plain :integration-tests:cleanTest :integration-tests:test --tests "org.apache.fineract.integrationtests.investor.externalassetowner.InitiateExternalAssetOwnerTransferTest.saleActiveLoanToExternalAssetOwnerAndBuybackADayLater" -PcargoDisabled
|
||||||
|
|||||||
@@ -3,13 +3,11 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
TZ: Asia/Kolkata
|
TZ: Asia/Kolkata
|
||||||
SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }}
|
SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }}
|
||||||
@@ -17,19 +15,23 @@ jobs:
|
|||||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
JAVA_BINARIES: .
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: gradle
|
- name: Setup Gradle and Validate Wrapper
|
||||||
- name: Validate Gradle wrapper
|
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||||
uses: gradle/wrapper-validation-action@88425854a36845f9c881450d9660b5fd46bee142
|
with:
|
||||||
- name: Sonarqube
|
validate-wrappers: true
|
||||||
run: ./gradlew --no-daemon --console=plain -Dsonar.verbose=true -Dsonar.login=$SONAR_TOKEN -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.projectKey=$SONAR_PROJECT_KEY --info --stacktrace sonarqube
|
- name: Build
|
||||||
|
run: ./gradlew --no-daemon --console=plain :fineract-provider:build -x test -x cucumber
|
||||||
|
- name: Sonar
|
||||||
|
run: ./gradlew --no-daemon --console=plain -Dsonar.verbose=true -Dsonar.token=$SONAR_TOKEN -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.java.binaries=$JAVA_BINARIES --info --stacktrace sonar
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ on:
|
|||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -15,7 +14,7 @@ jobs:
|
|||||||
pull-requests: write # for actions/stale to close stale PRs
|
pull-requests: write # for actions/stale to close stale PRs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9
|
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# stale-issue-message: 'Stale issue message'
|
# stale-issue-message: 'Stale issue message'
|
||||||
|
|||||||
@@ -30,3 +30,6 @@ fineract-provider/src/main/generated/
|
|||||||
|
|
||||||
**/out/
|
**/out/
|
||||||
gradleExp/
|
gradleExp/
|
||||||
|
|
||||||
|
.run/
|
||||||
|
.java-version
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
Apache Fineract: A Platform for Microfinance
|
Apache Fineract: A Platform for Microfinance
|
||||||
============
|
============
|
||||||
[](https://validator.swagger.io/validator/debug?url=https://sandbox.mifos.community/fineract-provider/swagger-ui/fineract.yaml) [](https://github.com/apache/fineract/actions/workflows/build.yml) [](https://hub.docker.com/r/apache/fineract) [](https://hub.docker.com/r/apache/fineract/builds) [](https://sonarcloud.io/summary/new_code?id=apache_fineract)
|
<!-- TODO Reactivate when there is a working CI-CD instance: [](https://validator.swagger.io/validator/debug?url=https://sandbox.mifos.community/fineract-provider/swagger-ui/fineract.yaml) -->
|
||||||
|
[](https://github.com/apache/fineract/actions/workflows/build-mariadb.yml)
|
||||||
|
[](https://hub.docker.com/r/apache/fineract)
|
||||||
|
[](https://github.com/apache/fineract/actions/workflows/publish-dockerhub.yml)
|
||||||
|
[](https://sonarcloud.io/summary/new_code?id=apache_fineract)
|
||||||
|
|
||||||
</b>
|
</b>
|
||||||
|
|
||||||
@@ -22,15 +26,15 @@ If you are interested in contributing to this project, but perhaps don't quite k
|
|||||||
REQUIREMENTS
|
REQUIREMENTS
|
||||||
============
|
============
|
||||||
* `Java >= 17` (Azul Zulu JVM is tested by our CI on GitHub Actions)
|
* `Java >= 17` (Azul Zulu JVM is tested by our CI on GitHub Actions)
|
||||||
* MariaDB `11.2`
|
* MariaDB `11.5.2`
|
||||||
|
|
||||||
You can run the required version of the database server in a container, instead of having to install it, like this:
|
You can run the required version of the database server in a container, instead of having to install it, like this:
|
||||||
|
|
||||||
docker run --name mariadb-11.2 -p 3306:3306 -e MARIADB_ROOT_PASSWORD=mysql -d mariadb:11.2
|
docker run --name mariadb-11.5 -p 3306:3306 -e MARIADB_ROOT_PASSWORD=mysql -d mariadb:11.5.2
|
||||||
|
|
||||||
and stop and destroy it like this:
|
and stop and destroy it like this:
|
||||||
|
|
||||||
docker rm -f mariadb-11.2
|
docker rm -f mariadb-11.5
|
||||||
|
|
||||||
<br>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/_/mariadb) re. how to make it persistent instead of ephemeral.<br>
|
<br>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/_/mariadb) re. how to make it persistent instead of ephemeral.<br>
|
||||||
|
|
||||||
@@ -75,11 +79,9 @@ Run the following commands:
|
|||||||
============
|
============
|
||||||
1. Clone the repository or download and extract the archive file to your local directory.
|
1. Clone the repository or download and extract the archive file to your local directory.
|
||||||
2. Run `./gradlew clean bootJar` to build a modern cloud native fully self contained JAR file which will be created at `fineract-provider/build/libs` directory.
|
2. Run `./gradlew clean bootJar` to build a modern cloud native fully self contained JAR file which will be created at `fineract-provider/build/libs` directory.
|
||||||
3. As we are not allowed to include a JDBC driver in the built JAR, download a JDBC driver of your choice. For example: `wget https://downloads.mariadb.com/Connectors/java/connector-java-3.3.2/mariadb-java-client-3.3.2.jar`
|
3. As we are not allowed to include a JDBC driver in the built JAR, download a JDBC driver of your choice. For example: `wget https://dlm.mariadb.com/4174416/Connectors/java/connector-java-3.5.2/mariadb-java-client-3.5.2.jar`
|
||||||
4. Start the jar and pass the directory where you have downloaded the JDBC driver as loader.path, for example: `java -Dloader.path=. -jar fineract-provider/build/libs/fineract-provider.jar` (does not require external Tomcat)
|
4. Start the jar and pass the directory where you have downloaded the JDBC driver as loader.path, for example: `java -Dloader.path=. -jar fineract-provider/build/libs/fineract-provider.jar` (does not require external Tomcat)
|
||||||
|
|
||||||
NOTE: we cannot upgrade to version 3.0.x of the MariaDB driver just yet; have to wait until 3.0.4 is out for a bug fix.
|
|
||||||
|
|
||||||
The tenants database connection details are configured [via environment variables (as with Docker container)](#instructions-to-run-using-docker-and-docker-compose), e.g. like this:
|
The tenants database connection details are configured [via environment variables (as with Docker container)](#instructions-to-run-using-docker-and-docker-compose), e.g. like this:
|
||||||
|
|
||||||
export FINERACT_HIKARI_PASSWORD=verysecret
|
export FINERACT_HIKARI_PASSWORD=verysecret
|
||||||
@@ -142,15 +144,54 @@ We recommend using the JAR instead of the WAR file deployment, because it's much
|
|||||||
Note that with the 1.4 release the tenants database pool configuration changed from Tomcat DBCP in XML to an embedded Hikari, configured by environment variables, see above.
|
Note that with the 1.4 release the tenants database pool configuration changed from Tomcat DBCP in XML to an embedded Hikari, configured by environment variables, see above.
|
||||||
|
|
||||||
|
|
||||||
INSTRUCTIONS: How to execute Integration Tests
|
INSTRUCTIONS: How to run tests
|
||||||
============
|
============
|
||||||
> Note that if this is the first time to access MySQL DB, then you may need to reset your password.
|
|
||||||
|
|
||||||
Run the following commands:
|
Unit tests
|
||||||
1. `./gradlew createDB -PdbName=fineract_tenants`
|
----------
|
||||||
1. `./gradlew createDB -PdbName=fineract_default`
|
|
||||||
1. `./gradlew clean test`
|
|
||||||
|
|
||||||
|
Here's how to run the set of relatviely fast and indepedent Fineract tests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew test -x :twofactor-tests:test -x :oauth2-tests:test -x :integration-tests:test
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs nearly 1,000 tests and completes in a few minutes on decent hardware.
|
||||||
|
They shouldn't need any special servers/services running.
|
||||||
|
|
||||||
|
Integration tests
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Running tests with external dependencies yourself is a multi-step process with many moving parts.
|
||||||
|
Sometimes there are arbitrary failures and the prerequisite setup can be daunting.
|
||||||
|
A full local integration test run (on a developer workstation) covering every possible test using every external service and every supported relational database engine could take an entire day, and that's assuming everything is properly configured and runs as expected.
|
||||||
|
|
||||||
|
Right now we depend on GitHub to know if "the build" is passing (it's actually multiple builds).
|
||||||
|
The authoritative source of truth for what commands/services/tests to run, how, and when are the files in `.github/workflows/`.
|
||||||
|
Output from runs based on those configuration files appears at <https://github.com/apache/fineract/actions>.
|
||||||
|
|
||||||
|
Note these builds are run in [short-lived virtual machines](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners), so locally reproducing the same may require additional effort, such as these extra clean-up procedures:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Destroy anything untracked by git.
|
||||||
|
# ⚠️ This may delete something important, e.g. a finely-tuned IDE configuration.
|
||||||
|
git clean --force -dx
|
||||||
|
|
||||||
|
# Destroy various caches and configs.
|
||||||
|
# ⚠️ This may delete gibibytes of cached data, making the next build very slow.
|
||||||
|
rm -rf ~/.gradle ~/.m2 /tmp/cargo*
|
||||||
|
|
||||||
|
# Destroy any Java containers left running.
|
||||||
|
# 💚 This is generally very safe to run between builds.
|
||||||
|
ps auxwww | grep [c]argo | awk '{ print $2 }' | xargs -r kill
|
||||||
|
```
|
||||||
|
|
||||||
|
Testing within IDEs
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
See the next section for testing in Eclipse.
|
||||||
|
|
||||||
|
See <https://fineract-academy.com> for testing in IntelliJ.
|
||||||
|
|
||||||
INSTRUCTIONS: How to run and debug in Eclipse IDE
|
INSTRUCTIONS: How to run and debug in Eclipse IDE
|
||||||
============
|
============
|
||||||
@@ -218,6 +259,21 @@ id -u ${GROUP}
|
|||||||
|
|
||||||
Please make sure that you are not checking in your changed values. The defaults should normally work for most people.
|
Please make sure that you are not checking in your changed values. The defaults should normally work for most people.
|
||||||
|
|
||||||
|
INSTRUCTIONS: How to build documentation
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew doc
|
||||||
|
```
|
||||||
|
|
||||||
|
Some dependencies are required (e.g. Ghostscript, Graphviz), see `.github/workflows/build-documentation.yml` for hints.
|
||||||
|
|
||||||
|
Additionally, IDEs such as IntelliJ are useful for editing the AsciiDoc source files while providing a live rendered preview.
|
||||||
|
|
||||||
|
HTML rendered from the AsciiDoc source files is also available online at <https://fineract.apache.org/docs/current/>.
|
||||||
|
|
||||||
Connection pool configuration
|
Connection pool configuration
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
@@ -448,7 +504,7 @@ Apache Fineract / Mifos X Demo (November 2016) - <https://www.youtube.com/watch?
|
|||||||
We use Swagger-UI to generate and maintain our API documentation, you can see the demo video [here](https://www.youtube.com/watch?v=FlVd-0YAo6c) or a live version
|
We use Swagger-UI to generate and maintain our API documentation, you can see the demo video [here](https://www.youtube.com/watch?v=FlVd-0YAo6c) or a live version
|
||||||
[here](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html). If you interested to know more about Swagger-UI you can check their [website](https://swagger.io/).
|
[here](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html). If you interested to know more about Swagger-UI you can check their [website](https://swagger.io/).
|
||||||
|
|
||||||
<br>GORVENANCE AND POLICIES
|
<br>GOVERNANCE AND POLICIES
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
[Becoming a Committer](https://cwiki.apache.org/confluence/display/FINERACT/Becoming+a+Committer)
|
[Becoming a Committer](https://cwiki.apache.org/confluence/display/FINERACT/Becoming+a+Committer)
|
||||||
|
|||||||
+127
-46
@@ -19,7 +19,7 @@
|
|||||||
// TODO: this is work in progress, please follow FINERACT-1171
|
// TODO: this is work in progress, please follow FINERACT-1171
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
jacocoVersion = '0.8.11'
|
jacocoVersion = '0.8.12'
|
||||||
retrofitVersion = '2.9.0'
|
retrofitVersion = '2.9.0'
|
||||||
okhttpVersion = '4.9.3'
|
okhttpVersion = '4.9.3'
|
||||||
oltuVersion = '1.0.1'
|
oltuVersion = '1.0.1'
|
||||||
@@ -46,7 +46,8 @@ buildscript {
|
|||||||
'fineract-avro-schemas',
|
'fineract-avro-schemas',
|
||||||
'fineract-e2e-tests-core',
|
'fineract-e2e-tests-core',
|
||||||
'fineract-e2e-tests-runner',
|
'fineract-e2e-tests-runner',
|
||||||
'fineract-progressive-loan'
|
'fineract-progressive-loan',
|
||||||
|
'fineract-progressive-loan-embeddable-schedule-generator'
|
||||||
].contains(it.name)
|
].contains(it.name)
|
||||||
}
|
}
|
||||||
fineractPublishProjects = subprojects.findAll{
|
fineractPublishProjects = subprojects.findAll{
|
||||||
@@ -66,7 +67,8 @@ buildscript {
|
|||||||
'fineract-report',
|
'fineract-report',
|
||||||
'fineract-branch',
|
'fineract-branch',
|
||||||
'fineract-document',
|
'fineract-document',
|
||||||
'fineract-progressive-loan'
|
'fineract-progressive-loan',
|
||||||
|
'fineract-progressive-loan-embeddable-schedule-generator'
|
||||||
].contains(it.name)
|
].contains(it.name)
|
||||||
}
|
}
|
||||||
npmRepository = 'https://npm.pkg.github.com'
|
npmRepository = 'https://npm.pkg.github.com'
|
||||||
@@ -77,42 +79,39 @@ buildscript {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.bmuschko:gradle-cargo-plugin:2.9.0'
|
classpath 'com.bmuschko:gradle-cargo-plugin:2.9.0'
|
||||||
classpath 'org.eclipse.persistence:eclipselink:4.0.0'
|
classpath 'org.eclipse.persistence:eclipselink:4.0.2'
|
||||||
classpath 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
|
classpath 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
|
||||||
classpath 'com.google.cloud.tools:jib-layer-filter-extension-gradle:0.3.0'
|
classpath 'com.google.cloud.tools:jib-layer-filter-extension-gradle:0.3.0'
|
||||||
classpath 'org.apache.commons:commons-lang3:3.14.0'
|
classpath 'org.apache.commons:commons-lang3:3.17.0'
|
||||||
classpath 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.22'
|
classpath 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.22'
|
||||||
classpath 'jakarta.servlet:jakarta.servlet-api:6.0.0'
|
classpath 'jakarta.servlet:jakarta.servlet-api:6.1.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'me.qoomon.git-versioning' version '6.4.3'
|
id 'me.qoomon.git-versioning' version '6.4.4'
|
||||||
id "org.barfuin.gradle.taskinfo" version "2.2.0"
|
id "org.barfuin.gradle.taskinfo" version "2.2.0"
|
||||||
id 'com.adarshr.test-logger' version '4.0.0'
|
id 'com.adarshr.test-logger' version '4.0.0'
|
||||||
id 'com.diffplug.spotless' version '6.25.0' apply false
|
id 'com.diffplug.spotless' version '6.25.0' apply false
|
||||||
id 'org.nosphere.apache.rat' version '0.8.1' apply false
|
id 'org.nosphere.apache.rat' version '0.8.1' apply false
|
||||||
id 'com.github.hierynomus.license' version '0.16.1' apply false
|
id 'com.github.hierynomus.license' version '0.16.1' apply false
|
||||||
id 'com.github.jk1.dependency-license-report' version '2.5' apply false
|
id 'com.github.jk1.dependency-license-report' version '2.9' apply false
|
||||||
id 'org.zeroturnaround.gradle.jrebel' version '1.2.0' apply false
|
id 'org.zeroturnaround.gradle.jrebel' version '1.2.0' apply false
|
||||||
id 'org.springframework.boot' version '3.2.6' apply false
|
id 'org.springframework.boot' version '3.4.4' apply false
|
||||||
id 'net.ltgt.errorprone' version '3.1.0' apply false
|
id 'net.ltgt.errorprone' version '4.1.0' apply false
|
||||||
id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.19' apply false
|
id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.23' apply false
|
||||||
id 'com.gorylenko.gradle-git-properties' version '2.4.1' apply false
|
id 'com.gorylenko.gradle-git-properties' version '2.4.2' apply false
|
||||||
id 'org.asciidoctor.jvm.convert' version '3.3.2' apply false
|
id 'org.asciidoctor.jvm.convert' version '3.3.2' apply false
|
||||||
id 'org.asciidoctor.jvm.pdf' version '3.3.2' apply false
|
id 'org.asciidoctor.jvm.pdf' version '3.3.2' apply false
|
||||||
id 'org.asciidoctor.jvm.epub' version '3.3.2' apply false
|
id 'com.google.cloud.tools.jib' version '3.4.4' apply false
|
||||||
// id 'org.asciidoctor.jvm.revealjs' version '3.3.2' apply false
|
id 'org.sonarqube' version '6.0.1.5171'
|
||||||
// id 'org.asciidoctor.jvm.gems' version '3.3.2' apply false
|
id 'com.github.andygoossens.modernizer' version '1.10.0' apply false
|
||||||
id 'org.asciidoctor.kindlegen.base' version '3.2.0' apply false
|
|
||||||
id 'com.google.cloud.tools.jib' version '3.4.2' apply false
|
|
||||||
id 'org.sonarqube' version '4.4.1.3373'
|
|
||||||
id 'com.github.andygoossens.modernizer' version '1.9.0' apply false
|
|
||||||
// TODO: upgrade to 6.0.4
|
// TODO: upgrade to 6.0.4
|
||||||
id 'com.github.spotbugs' version '5.2.5' apply false
|
id 'com.github.spotbugs' version '6.0.26' apply false
|
||||||
id 'se.thinkcode.cucumber-runner' version '0.0.11' apply false
|
id 'se.thinkcode.cucumber-runner' version '0.0.11' apply false
|
||||||
id "com.github.davidmc24.gradle.plugin.avro-base" version "1.9.1" apply false
|
id "com.github.davidmc24.gradle.plugin.avro-base" version "1.9.1" apply false
|
||||||
id 'org.openapi.generator' version '7.2.0' apply false
|
id 'org.openapi.generator' version '7.8.0' apply false
|
||||||
|
id 'com.gradleup.shadow' version '8.3.5' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "${rootDir}/buildSrc/src/main/groovy/org.apache.fineract.release.gradle"
|
apply from: "${rootDir}/buildSrc/src/main/groovy/org.apache.fineract.release.gradle"
|
||||||
@@ -151,11 +150,39 @@ allprojects {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
api {
|
||||||
|
canBeResolved = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
apply plugin: 'com.adarshr.test-logger'
|
apply plugin: 'com.adarshr.test-logger'
|
||||||
apply plugin: 'com.diffplug.spotless'
|
apply plugin: 'com.diffplug.spotless'
|
||||||
apply plugin: 'com.github.hierynomus.license'
|
apply plugin: 'com.github.hierynomus.license'
|
||||||
|
apply plugin: 'net.ltgt.errorprone'
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.errorprone {
|
||||||
|
disableWarningsInGeneratedCode = true
|
||||||
|
disable(
|
||||||
|
"CanIgnoreReturnValueSuggester",
|
||||||
|
"SameNameButDifferent", // Until errorprone recognizes Lombok
|
||||||
|
"MultiVariableDeclaration", // Until errorprone recognizes Lombok
|
||||||
|
"UnnecessaryDefaultInEnumSwitch", // FINERACT-1911
|
||||||
|
"AssertEqualsArgumentOrderChecker",
|
||||||
|
"RemoveUnusedImports" // For generated code
|
||||||
|
)
|
||||||
|
error(
|
||||||
|
"DefaultCharset",
|
||||||
|
"StringSplitter",
|
||||||
|
"MutablePublicArray",
|
||||||
|
"EqualsGetClass",
|
||||||
|
"FutureReturnValueIgnored"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
apply plugin: 'org.nosphere.apache.rat'
|
apply plugin: 'org.nosphere.apache.rat'
|
||||||
apply plugin: 'project-report'
|
|
||||||
apply plugin: 'com.github.jk1.dependency-license-report'
|
apply plugin: 'com.github.jk1.dependency-license-report'
|
||||||
|
|
||||||
// Configuration for the sonarqube plugin is now in GitHub Actions
|
// Configuration for the sonarqube plugin is now in GitHub Actions
|
||||||
@@ -173,7 +200,7 @@ allprojects {
|
|||||||
|
|
||||||
groovyGradle {
|
groovyGradle {
|
||||||
target '*.gradle', '**/*.gradle'
|
target '*.gradle', '**/*.gradle'
|
||||||
targetExclude '**/build/**'
|
targetExclude '**/build/**', '/**/build.gradle' // TODO: temporary disabled on build.gradle until someone fix this issue: https://github.com/diffplug/spotless/issues/1807
|
||||||
greclipse()
|
greclipse()
|
||||||
indentWithSpaces(4)
|
indentWithSpaces(4)
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
@@ -222,7 +249,6 @@ allprojects {
|
|||||||
'**/licenses/**',
|
'**/licenses/**',
|
||||||
'**/*.md',
|
'**/*.md',
|
||||||
'**/*.adoc',
|
'**/*.adoc',
|
||||||
'**/.asciidoctorconfig',
|
|
||||||
'**/*.puml',
|
'**/*.puml',
|
||||||
'**/*.github/**',
|
'**/*.github/**',
|
||||||
'**/MANIFEST.MF',
|
'**/MANIFEST.MF',
|
||||||
@@ -299,7 +325,9 @@ allprojects {
|
|||||||
'**/images/diag-*.svg',
|
'**/images/diag-*.svg',
|
||||||
'**/*.avsc',
|
'**/*.avsc',
|
||||||
"**/generated/**/*MapperImpl.java",
|
"**/generated/**/*MapperImpl.java",
|
||||||
'**/META-INF/fineract-test.config'
|
'**/META-INF/fineract-test.config',
|
||||||
|
// Apache-specific GitHub metadata settings file
|
||||||
|
'/.asf.yaml'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,10 +353,49 @@ configure(project.fineractJavaProjects) {
|
|||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'idea'
|
apply plugin: 'idea'
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
withSourcesJar()
|
||||||
|
withJavadocJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(ProcessResources) {
|
||||||
|
destinationDir = layout.buildDirectory.dir('classes/java/main').get().asFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add performance optimizations
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy {
|
||||||
|
cacheChangingModulesFor 0, 'seconds'
|
||||||
|
cacheDynamicVersionsFor 0, 'seconds'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.incremental = true
|
||||||
|
options.fork = true
|
||||||
|
outputs.cacheIf { true }
|
||||||
|
options.compilerArgs << '-parameters'
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
options.compilerArgs << '-Xlint:unchecked'
|
||||||
|
options.compilerArgs << '-Xlint:deprecation'
|
||||||
|
if (project.hasProperty('warnings') && project.warnings.contains('fail')) {
|
||||||
|
options.compilerArgs << '-Werror'
|
||||||
|
}
|
||||||
|
if (project.hasProperty('warnings') && project.warnings.contains('none')) {
|
||||||
|
options.compilerArgs << '-nowarn'
|
||||||
|
}
|
||||||
|
if (project.plugins.hasPlugin('org.springframework.boot')) {
|
||||||
|
options.generatedSourceOutputDirectory = file("$buildDir/generated/sources/annotationProcessor/java/main")
|
||||||
|
}
|
||||||
|
options.generatedSourceOutputDirectory = file("$buildDir/generated/sources/annotationProcessor/java/main")
|
||||||
|
}
|
||||||
|
|
||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
apply plugin: 'checkstyle'
|
apply plugin: 'checkstyle'
|
||||||
apply plugin: 'jacoco'
|
apply plugin: 'jacoco'
|
||||||
apply plugin: 'net.ltgt.errorprone'
|
|
||||||
apply plugin: 'com.github.spotbugs'
|
apply plugin: 'com.github.spotbugs'
|
||||||
apply plugin: 'com.github.andygoossens.modernizer'
|
apply plugin: 'com.github.andygoossens.modernizer'
|
||||||
apply from: "${rootDir}/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle"
|
apply from: "${rootDir}/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle"
|
||||||
@@ -336,9 +403,9 @@ configure(project.fineractJavaProjects) {
|
|||||||
group = 'org.apache.fineract'
|
group = 'org.apache.fineract'
|
||||||
|
|
||||||
/* define the valid syntax level for source files */
|
/* define the valid syntax level for source files */
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
// sourceCompatibility = JavaVersion.VERSION_17
|
||||||
/* define binary compatibility version */
|
// /* define binary compatibility version */
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
// targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
|
||||||
/* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */
|
/* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */
|
||||||
sourceSets.main.output.resourcesDir = sourceSets.main.java.classesDirectory
|
sourceSets.main.output.resourcesDir = sourceSets.main.java.classesDirectory
|
||||||
@@ -354,7 +421,6 @@ configure(project.fineractJavaProjects) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
implementation.setCanBeResolved(true)
|
|
||||||
api.setCanBeResolved(true)
|
api.setCanBeResolved(true)
|
||||||
}
|
}
|
||||||
tasks.withType(Copy) {
|
tasks.withType(Copy) {
|
||||||
@@ -362,10 +428,8 @@ configure(project.fineractJavaProjects) {
|
|||||||
}
|
}
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
options.compilerArgs += [
|
options.compilerArgs += [
|
||||||
"-Xlint:unchecked",
|
|
||||||
"-Xlint:cast",
|
"-Xlint:cast",
|
||||||
"-Xlint:auxiliaryclass",
|
"-Xlint:auxiliaryclass",
|
||||||
"-Xlint:deprecation",
|
|
||||||
"-Xlint:dep-ann",
|
"-Xlint:dep-ann",
|
||||||
"-Xlint:divzero",
|
"-Xlint:divzero",
|
||||||
"-Xlint:empty",
|
"-Xlint:empty",
|
||||||
@@ -399,6 +463,10 @@ configure(project.fineractJavaProjects) {
|
|||||||
options.deprecation = true
|
options.deprecation = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check {
|
||||||
|
dependsOn(rat, licenseMain, licenseTest)
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
spotbugsPlugins 'jp.skypencil.findbugs.slf4j:bug-pattern:1.5.0@jar'
|
spotbugsPlugins 'jp.skypencil.findbugs.slf4j:bug-pattern:1.5.0@jar'
|
||||||
}
|
}
|
||||||
@@ -455,7 +523,7 @@ configure(project.fineractJavaProjects) {
|
|||||||
// Configuration for the Checkstyle plugin
|
// Configuration for the Checkstyle plugin
|
||||||
// https://docs.gradle.org/current/userguide/checkstyle_plugin.html
|
// https://docs.gradle.org/current/userguide/checkstyle_plugin.html
|
||||||
dependencies {
|
dependencies {
|
||||||
checkstyle 'com.puppycrawl.tools:checkstyle:10.14.2'
|
checkstyle 'com.puppycrawl.tools:checkstyle:10.20.1'
|
||||||
checkstyle 'com.github.sevntu-checkstyle:sevntu-checks:1.44.1'
|
checkstyle 'com.github.sevntu-checkstyle:sevntu-checks:1.44.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,21 +538,22 @@ configure(project.fineractJavaProjects) {
|
|||||||
reports {
|
reports {
|
||||||
html.required = true
|
html.required = true
|
||||||
xml.required = true
|
xml.required = true
|
||||||
html.destination file("${buildDir}/code-coverage")
|
html.outputLocation = layout.buildDirectory.dir('code-coverage')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration for the errorprone plugin
|
// Configuration for the errorprone plugin
|
||||||
// https://github.com/tbroyer/gradle-errorprone-plugin
|
// https://github.com/tbroyer/gradle-errorprone-plugin
|
||||||
dependencies {
|
dependencies {
|
||||||
errorprone "com.google.errorprone:error_prone_core:2.26.1"
|
errorprone "com.google.errorprone:error_prone_core:2.35.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile).configureEach {
|
||||||
options.errorprone {
|
options.errorprone {
|
||||||
enabled = project.gradle.startParameter.taskNames.contains('build') || project.gradle.startParameter.taskNames.contains('check')
|
enabled = project.gradle.startParameter.taskNames.contains('build') || project.gradle.startParameter.taskNames.contains('check')
|
||||||
disableWarningsInGeneratedCode = true
|
if (project.path == ':fineract-client') {
|
||||||
excludedPaths = ".*/build/.*"
|
excludedPaths = '.*/build/generated/java/src/main/java/.*'
|
||||||
|
}
|
||||||
disable(
|
disable(
|
||||||
// TODO Remove disabled checks from this list, by fixing remaining usages
|
// TODO Remove disabled checks from this list, by fixing remaining usages
|
||||||
"UnusedVariable",
|
"UnusedVariable",
|
||||||
@@ -608,9 +677,10 @@ configure(project.fineractJavaProjects) {
|
|||||||
'org.bouncycastle:bcpkix-jdk15to18',
|
'org.bouncycastle:bcpkix-jdk15to18',
|
||||||
'org.bouncycastle:bcprov-jdk15to18',
|
'org.bouncycastle:bcprov-jdk15to18',
|
||||||
'org.awaitility:awaitility',
|
'org.awaitility:awaitility',
|
||||||
'com.google.truth:truth',
|
|
||||||
'com.google.truth.extensions:truth-java8-extension'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
testCompileOnly 'org.projectlombok:lombok'
|
||||||
|
testAnnotationProcessor 'org.projectlombok:lombok'
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
@@ -667,6 +737,19 @@ configure(project.fineractJavaProjects) {
|
|||||||
'java/util/Optional.get:()Ljava/lang/Object;' // Disable forcing the usage of Optional.orElseThrow(java.util.function.Supplier<? extends X>)
|
'java/util/Optional.get:()Ljava/lang/Object;' // Disable forcing the usage of Optional.orElseThrow(java.util.function.Supplier<? extends X>)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(Javadoc) {
|
||||||
|
options.addStringOption('Xdoclint:none', '-quiet')
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
// Disable strict checking to prevent build failures on invalid javadoc
|
||||||
|
options.addBooleanOption('html5', true)
|
||||||
|
// Add this if you're using Java 17 records or other modern features
|
||||||
|
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) {
|
||||||
|
options.addBooleanOption('html5', true)
|
||||||
|
}
|
||||||
|
// Ignore any errors during javadoc generation
|
||||||
|
failOnError = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(project.fineractCustomProjects) {
|
configure(project.fineractCustomProjects) {
|
||||||
@@ -708,14 +791,12 @@ configure(project.fineractCustomProjects) {
|
|||||||
'org.bouncycastle:bcpkix-jdk15to18',
|
'org.bouncycastle:bcpkix-jdk15to18',
|
||||||
'org.bouncycastle:bcprov-jdk15to18',
|
'org.bouncycastle:bcprov-jdk15to18',
|
||||||
'org.awaitility:awaitility',
|
'org.awaitility:awaitility',
|
||||||
'com.google.truth:truth',
|
|
||||||
'com.google.truth.extensions:truth-java8-extension',
|
|
||||||
'io.github.classgraph:classgraph',
|
'io.github.classgraph:classgraph',
|
||||||
'io.cucumber:cucumber-core',
|
'io.cucumber:cucumber-core',
|
||||||
'io.cucumber:cucumber-java:7.16.1',
|
'io.cucumber:cucumber-java:7.20.1',
|
||||||
'io.cucumber:cucumber-java8:7.16.1',
|
'io.cucumber:cucumber-java8:7.20.1',
|
||||||
'io.cucumber:cucumber-junit-platform-engine:7.16.1',
|
'io.cucumber:cucumber-junit-platform-engine:7.20.1',
|
||||||
'io.cucumber:cucumber-spring:7.16.1',
|
'io.cucumber:cucumber-spring:7.20.1',
|
||||||
)
|
)
|
||||||
|
|
||||||
testCompileOnly('org.projectlombok:lombok')
|
testCompileOnly('org.projectlombok:lombok')
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
import static org.slf4j.LoggerFactory.*
|
import static org.slf4j.LoggerFactory.*
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'io.spring.dependency-management' version '1.1.4'
|
id 'io.spring.dependency-management' version '1.1.6'
|
||||||
id 'groovy'
|
id 'groovy'
|
||||||
id 'java-gradle-plugin'
|
id 'java-gradle-plugin'
|
||||||
id 'groovy-gradle-plugin'
|
id 'groovy-gradle-plugin'
|
||||||
|
|||||||
@@ -23,19 +23,19 @@ apply plugin: 'io.spring.dependency-management'
|
|||||||
dependencyManagement {
|
dependencyManagement {
|
||||||
imports {
|
imports {
|
||||||
mavenBom 'com.squareup.okhttp3:okhttp-bom:4.12.0'
|
mavenBom 'com.squareup.okhttp3:okhttp-bom:4.12.0'
|
||||||
mavenBom 'org.slf4j:slf4j-bom:2.0.12'
|
mavenBom 'org.slf4j:slf4j-bom:2.0.17'
|
||||||
mavenBom 'io.micrometer:micrometer-bom:1.12.2'
|
mavenBom 'io.micrometer:micrometer-bom:1.13.6'
|
||||||
mavenBom 'org.springframework:spring-framework-bom:6.1.3'
|
mavenBom 'org.springframework:spring-framework-bom:6.2.5'
|
||||||
mavenBom 'org.springframework.boot:spring-boot-dependencies:3.2.6'
|
mavenBom 'org.springframework.boot:spring-boot-dependencies:3.4.4'
|
||||||
mavenBom 'io.awspring.cloud:spring-cloud-aws-dependencies:3.1.0'
|
mavenBom 'io.awspring.cloud:spring-cloud-aws-dependencies:3.2.1'
|
||||||
mavenBom 'io.opentelemetry:opentelemetry-bom:1.34.1'
|
mavenBom 'io.opentelemetry:opentelemetry-bom:1.44.1'
|
||||||
mavenBom 'org.jetbrains.kotlin:kotlin-bom:1.9.24'
|
mavenBom 'org.jetbrains.kotlin:kotlin-bom:2.0.21'
|
||||||
mavenBom 'org.junit:junit-bom:5.10.2'
|
mavenBom 'org.junit:junit-bom:5.11.3'
|
||||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.16.1'
|
mavenBom 'com.fasterxml.jackson:jackson-bom:2.18.3'
|
||||||
mavenBom 'io.cucumber:cucumber-bom:7.15.0'
|
mavenBom 'io.cucumber:cucumber-bom:7.20.1'
|
||||||
mavenBom 'io.netty:netty-bom:4.1.110.Final'
|
mavenBom 'io.netty:netty-bom:4.1.119.Final'
|
||||||
mavenBom 'org.mockito:mockito-bom:5.10.0'
|
mavenBom 'org.mockito:mockito-bom:5.14.2'
|
||||||
mavenBom 'software.amazon.awssdk:bom:2.23.18'
|
mavenBom 'software.amazon.awssdk:bom:2.29.9'
|
||||||
mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
|
mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,40 +44,38 @@ dependencyManagement {
|
|||||||
// We do not use :+ to get the latest available version available on Maven Central, as that could suddenly break things.
|
// We do not use :+ to get the latest available version available on Maven Central, as that could suddenly break things.
|
||||||
// We use the Renovate Bot to automatically propose Pull Requests (PRs) when upgrades for all of these versions are available.
|
// We use the Renovate Bot to automatically propose Pull Requests (PRs) when upgrades for all of these versions are available.
|
||||||
|
|
||||||
dependency 'ch.qos.logback:logback-core:1.5.3'
|
dependency 'ch.qos.logback:logback-core:1.5.17'
|
||||||
dependency 'ch.qos.logback:logback-classic:1.5.3'
|
dependency 'ch.qos.logback:logback-classic:1.5.17'
|
||||||
dependency 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
|
dependency 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
|
||||||
dependency 'ch.qos.logback.contrib:logback-jackson:0.1.5'
|
dependency 'ch.qos.logback.contrib:logback-jackson:0.1.5'
|
||||||
dependency 'org.codehaus.janino:janino:3.1.11'
|
dependency 'org.codehaus.janino:janino:3.1.12'
|
||||||
|
|
||||||
|
|
||||||
dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:4.0.0'
|
dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:4.0.2'
|
||||||
dependency 'com.google.guava:guava:32.0.0-jre'
|
dependency 'com.google.guava:guava:32.0.0-jre'
|
||||||
dependency 'com.google.code.gson:gson:2.10.1'
|
dependency 'com.google.code.gson:gson:2.11.0'
|
||||||
dependency 'com.google.truth:truth:1.4.0'
|
dependency 'com.google.googlejavaformat:google-java-format:1.24.0'
|
||||||
dependency 'com.google.truth.extensions:truth-java8-extension:1.4.0'
|
|
||||||
dependency 'com.google.googlejavaformat:google-java-format:1.19.2'
|
|
||||||
dependency 'org.apache.commons:commons-collections4:4.4'
|
dependency 'org.apache.commons:commons-collections4:4.4'
|
||||||
dependency ('software.amazon.msk:aws-msk-iam-auth:2.0.3') {
|
dependency ('software.amazon.msk:aws-msk-iam-auth:2.2.0') {
|
||||||
exclude 'commons-logging:commons-logging:'
|
exclude 'commons-logging:commons-logging:'
|
||||||
}
|
}
|
||||||
dependency ('org.apache.commons:commons-email:1.6.0') {
|
dependency ('org.apache.commons:commons-email:1.6.0') {
|
||||||
exclude 'com.sun.mail:javax.mail'
|
exclude 'com.sun.mail:javax.mail'
|
||||||
exclude 'javax.activation:activation'
|
exclude 'javax.activation:activation'
|
||||||
}
|
}
|
||||||
dependency 'commons-io:commons-io:2.15.1'
|
dependency 'commons-io:commons-io:2.17.0'
|
||||||
dependency 'com.github.librepdf:openpdf:2.0.0'
|
dependency 'com.github.librepdf:openpdf:2.0.3'
|
||||||
dependency ('org.mnode.ical4j:ical4j:3.2.14') {
|
dependency ('org.mnode.ical4j:ical4j:3.2.19') {
|
||||||
exclude 'com.sun.mail:javax.mail'
|
exclude 'com.sun.mail:javax.mail'
|
||||||
exclude 'org.codehaus.groovy:groovy'
|
exclude 'org.codehaus.groovy:groovy'
|
||||||
}
|
}
|
||||||
dependency 'org.apache.commons:commons-csv:1.10.0'
|
dependency 'org.apache.commons:commons-csv:1.12.0'
|
||||||
dependency 'org.quartz-scheduler:quartz:2.3.2'
|
dependency 'org.quartz-scheduler:quartz:2.5.0'
|
||||||
dependency 'org.ehcache:ehcache:3.10.8'
|
dependency 'org.ehcache:ehcache:3.10.8'
|
||||||
dependency 'com.github.spullara.mustache.java:compiler:0.9.11'
|
dependency 'com.github.spullara.mustache.java:compiler:0.9.14'
|
||||||
dependency 'com.jayway.jsonpath:json-path:2.9.0'
|
dependency 'com.jayway.jsonpath:json-path:2.9.0'
|
||||||
dependency 'org.apache.tika:tika-core:2.9.1'
|
dependency 'org.apache.tika:tika-core:2.9.3'
|
||||||
dependency ('org.apache.tika:tika-parser-microsoft-module:2.9.2') {
|
dependency ('org.apache.tika:tika-parser-microsoft-module:2.9.3') {
|
||||||
exclude 'org.bouncycastle:bcprov-jdk15on'
|
exclude 'org.bouncycastle:bcprov-jdk15on'
|
||||||
exclude 'org.bouncycastle:bcmail-jdk15on'
|
exclude 'org.bouncycastle:bcmail-jdk15on'
|
||||||
exclude 'org.bouncycastle:bcprov-jdk18on'
|
exclude 'org.bouncycastle:bcprov-jdk18on'
|
||||||
@@ -94,7 +92,7 @@ dependencyManagement {
|
|||||||
exclude 'org.apache.commons:commons-compress'
|
exclude 'org.apache.commons:commons-compress'
|
||||||
exclude 'xml-apis:xml-apis'
|
exclude 'xml-apis:xml-apis'
|
||||||
}
|
}
|
||||||
dependency ('org.apache.tika:tika-parser-miscoffice-module:2.9.2') {
|
dependency ('org.apache.tika:tika-parser-miscoffice-module:2.9.3') {
|
||||||
exclude 'org.bouncycastle:bcprov-jdk15on'
|
exclude 'org.bouncycastle:bcprov-jdk15on'
|
||||||
exclude 'org.bouncycastle:bcmail-jdk15on'
|
exclude 'org.bouncycastle:bcmail-jdk15on'
|
||||||
exclude 'org.bouncycastle:bcprov-jdk18on'
|
exclude 'org.bouncycastle:bcprov-jdk18on'
|
||||||
@@ -117,64 +115,63 @@ dependencyManagement {
|
|||||||
dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
|
dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
|
||||||
dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
|
dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
|
||||||
dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
|
dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
|
||||||
dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.5'
|
dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.10'
|
||||||
dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
|
dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
|
||||||
dependency 'org.apache.bval:org.apache.bval.bundle:3.0.0'
|
dependency 'org.apache.bval:org.apache.bval.bundle:3.0.2'
|
||||||
dependency 'joda-time:joda-time:2.12.7'
|
dependency 'joda-time:joda-time:2.13.1'
|
||||||
|
|
||||||
dependency 'io.github.classgraph:classgraph:4.8.168'
|
dependency 'io.github.classgraph:classgraph:4.8.179'
|
||||||
dependency 'org.awaitility:awaitility:4.2.1'
|
dependency 'org.awaitility:awaitility:4.2.2'
|
||||||
// TODO: upgrade to 4.8.3
|
// TODO: upgrade to 4.8.3
|
||||||
dependency 'com.github.spotbugs:spotbugs-annotations:4.8.3'
|
dependency 'com.github.spotbugs:spotbugs-annotations:4.8.6'
|
||||||
dependency 'javax.cache:cache-api:1.1.1'
|
dependency 'javax.cache:cache-api:1.1.1'
|
||||||
dependency 'org.mock-server:mockserver-junit-jupiter:5.15.0'
|
dependency 'org.mock-server:mockserver-junit-jupiter:5.15.0'
|
||||||
dependency 'org.webjars:webjars-locator-core:0.55'
|
dependency 'org.webjars:webjars-locator-core:0.59'
|
||||||
dependency 'com.icegreen:greenmail-junit5:2.0.1'
|
dependency 'com.icegreen:greenmail-junit5:2.0.1'
|
||||||
dependency 'com.intuit.karate:karate-junit5:1.4.1'
|
|
||||||
|
|
||||||
// fineract client dependencies
|
// fineract client dependencies
|
||||||
dependency "com.squareup.retrofit2:retrofit:2.9.0"
|
dependency "com.squareup.retrofit2:retrofit:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:retrofit-mock:2.9.0"
|
dependency "com.squareup.retrofit2:retrofit-mock:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:adapter-java8:2.9.0"
|
dependency "com.squareup.retrofit2:adapter-java8:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:adapter-rxjava2:2.9.0"
|
dependency "com.squareup.retrofit2:adapter-rxjava2:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
|
dependency "com.squareup.retrofit2:adapter-rxjava3:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:adapter-guava:2.9.0"
|
dependency "com.squareup.retrofit2:adapter-guava:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-wire:2.9.0"
|
dependency "com.squareup.retrofit2:converter-wire:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-jackson:2.9.0"
|
dependency "com.squareup.retrofit2:converter-jackson:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-simplexml:2.9.0"
|
dependency "com.squareup.retrofit2:converter-simplexml:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-jaxb:2.9.0"
|
dependency "com.squareup.retrofit2:converter-jaxb:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-java8:2.9.0"
|
dependency "com.squareup.retrofit2:converter-java8:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-scalars:2.9.0"
|
dependency "com.squareup.retrofit2:converter-scalars:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-gson:2.9.0"
|
dependency "com.squareup.retrofit2:converter-gson:2.11.0"
|
||||||
dependency "com.squareup.retrofit2:converter-protobuf:2.9.0"
|
dependency "com.squareup.retrofit2:converter-protobuf:2.11.0"
|
||||||
dependency 'io.reactivex.rxjava2:rxjava:2.2.21'
|
dependency 'io.reactivex.rxjava2:rxjava:2.2.21'
|
||||||
dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.common:1.0.1"
|
dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.common:1.0.1"
|
||||||
dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.1"
|
dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.1"
|
||||||
dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.httpclient4:1.0.1"
|
dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.httpclient4:1.0.1"
|
||||||
dependency "io.gsonfire:gson-fire:1.9.0"
|
dependency "io.gsonfire:gson-fire:1.9.0"
|
||||||
dependency "com.google.code.findbugs:jsr305:3.0.2"
|
dependency "com.google.code.findbugs:jsr305:3.0.2"
|
||||||
dependency "commons-codec:commons-codec:1.16.0"
|
dependency "commons-codec:commons-codec:1.17.1"
|
||||||
dependency "org.projectlombok:lombok:1.18.32"
|
dependency "org.projectlombok:lombok:1.18.36"
|
||||||
|
|
||||||
dependency 'org.bouncycastle:bcpkix-jdk15to18:1.77'
|
dependency 'org.bouncycastle:bcpkix-jdk15to18:1.79'
|
||||||
dependency 'org.bouncycastle:bcprov-jdk15to18:1.77'
|
dependency 'org.bouncycastle:bcprov-jdk15to18:1.79'
|
||||||
dependency 'org.bouncycastle:bcprov-jdk15on:1.70'
|
dependency 'org.bouncycastle:bcprov-jdk15on:1.70'
|
||||||
dependency 'org.bouncycastle:bcpg-jdk15on:1.70'
|
dependency 'org.bouncycastle:bcpg-jdk15on:1.70'
|
||||||
|
|
||||||
dependency 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
|
dependency 'org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r'
|
||||||
dependency 'org.eclipse.jgit:org.eclipse.jgit.ssh.apache:6.8.0.202311291450-r'
|
dependency 'org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.0.0.202409031743-r'
|
||||||
|
|
||||||
dependency 'org.tmatesoft.svnkit:svnkit:1.10.11'
|
dependency 'org.tmatesoft.svnkit:svnkit:1.10.11'
|
||||||
dependency 'com.vdurmont:semver4j:3.1.0'
|
dependency 'com.vdurmont:semver4j:3.1.0'
|
||||||
dependency 'org.beryx:text-io:3.4.1'
|
dependency 'org.beryx:text-io:3.4.1'
|
||||||
|
|
||||||
dependency ('org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0') {
|
dependency ('org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0') {
|
||||||
exclude 'io.swagger.core.v3:swagger-core'
|
exclude 'io.swagger.core.v3:swagger-core'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependency 'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.15.2'
|
dependency 'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.23.1'
|
||||||
|
|
||||||
dependency ('org.apache.activemq:activemq-client:6.0.1') {
|
dependency ('org.apache.activemq:activemq-client:6.1.6') {
|
||||||
exclude 'javax.annotation:javax.annotation-api'
|
exclude 'javax.annotation:javax.annotation-api'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,20 +183,20 @@ dependencyManagement {
|
|||||||
exclude 'jakarta.activation:jakarta.activation-api'
|
exclude 'jakarta.activation:jakarta.activation-api'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependency 'jakarta.annotation:jakarta.annotation-api:2.1.1'
|
dependency 'jakarta.annotation:jakarta.annotation-api:3.0.0'
|
||||||
dependency 'jakarta.activation:jakarta.activation-api:2.1.2'
|
dependency 'jakarta.activation:jakarta.activation-api:2.1.3'
|
||||||
dependency ('com.sun.mail:jakarta.mail:2.0.1') {
|
dependency ('com.sun.mail:jakarta.mail:2.0.1') {
|
||||||
// Spring needs this version
|
// Spring needs this version
|
||||||
exclude 'com.sun.activation:jakarta.activation'
|
exclude 'com.sun.activation:jakarta.activation'
|
||||||
}
|
}
|
||||||
dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.1') {
|
dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.2') {
|
||||||
exclude 'jakarta.activation:jakarta.activation-api'
|
exclude 'jakarta.activation:jakarta.activation-api'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependency ('org.liquibase:liquibase-core:4.25.1') {
|
dependency ('org.liquibase:liquibase-core:4.31.1') {
|
||||||
exclude 'javax.xml.bind:jaxb-api'
|
exclude 'javax.xml.bind:jaxb-api'
|
||||||
}
|
}
|
||||||
dependency 'org.liquibase.ext:liquibase-postgresql:4.25.1.1'
|
dependency 'org.liquibase.ext:liquibase-postgresql:4.31.1'
|
||||||
|
|
||||||
dependency ('org.dom4j:dom4j:2.1.4') {
|
dependency ('org.dom4j:dom4j:2.1.4') {
|
||||||
exclude 'relaxngDatatype:relaxngDatatype' // already in com.sun.xml.bind:jaxb-osgi:2.3.0.1
|
exclude 'relaxngDatatype:relaxngDatatype' // already in com.sun.xml.bind:jaxb-osgi:2.3.0.1
|
||||||
@@ -208,36 +205,37 @@ dependencyManagement {
|
|||||||
exclude 'pull-parser:pull-parser'
|
exclude 'pull-parser:pull-parser'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependency 'org.owasp.esapi:esapi:2.5.3.1'
|
dependency 'org.owasp.esapi:esapi:2.6.0.0'
|
||||||
dependency 'org.awaitility:awaitility:4.2.1'
|
dependency 'org.awaitility:awaitility:4.2.2'
|
||||||
|
|
||||||
dependencySet(group: 'org.apache.poi', version: '5.2.5') {
|
dependencySet(group: 'org.apache.poi', version: '5.3.0') {
|
||||||
entry 'poi'
|
entry 'poi'
|
||||||
entry 'poi-ooxml'
|
entry 'poi-ooxml'
|
||||||
entry 'poi-ooxml-schemas'
|
entry 'poi-ooxml-schemas'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencySet(group: 'io.rest-assured', version: '5.4.0') {
|
dependencySet(group: 'io.rest-assured', version: '5.5.1') {
|
||||||
entry 'rest-assured'
|
entry 'rest-assured'
|
||||||
entry 'json-path'
|
entry 'json-path'
|
||||||
entry 'xml-path'
|
entry 'xml-path'
|
||||||
}
|
}
|
||||||
dependency 'org.apache.groovy:groovy-xml:4.0.18'
|
dependency 'org.apache.groovy:groovy-xml:4.0.26'
|
||||||
dependency 'org.apache.groovy:groovy-json:4.0.18'
|
dependency 'org.apache.groovy:groovy-json:4.0.26'
|
||||||
|
|
||||||
dependency 'org.mapstruct:mapstruct:1.5.5.Final'
|
dependency 'org.mapstruct:mapstruct:1.6.3'
|
||||||
dependency 'org.mapstruct:mapstruct-processor:1.5.5.Final'
|
dependency 'org.mapstruct:mapstruct-processor:1.6.3'
|
||||||
|
|
||||||
dependency "org.apache.avro:avro:1.11.3"
|
dependency "org.apache.avro:avro:1.12.0"
|
||||||
|
|
||||||
dependency ('org.mariadb.jdbc:mariadb-java-client:3.3.2') {
|
dependency ('org.mariadb.jdbc:mariadb-java-client:3.5.2') {
|
||||||
exclude 'org.slf4j:jcl-over-slf4j'
|
exclude 'org.slf4j:jcl-over-slf4j'
|
||||||
exclude 'org.slf4j:slf4j-api'
|
exclude 'org.slf4j:slf4j-api'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependency 'org.postgresql:postgresql:42.7.3'
|
//v42.7.5: performance issue: https://github.com/pgjdbc/pgjdbc/issues/3511#issuecomment-2637277977
|
||||||
|
dependency 'org.postgresql:postgresql:42.7.4'
|
||||||
|
|
||||||
dependency 'org.assertj:assertj-core:3.25.3'
|
dependency 'org.assertj:assertj-core:3.26.3'
|
||||||
|
|
||||||
dependency 'org.apache.commons:commons-math3:3.6.1'
|
dependency 'org.apache.commons:commons-math3:3.6.1'
|
||||||
|
|
||||||
@@ -245,9 +243,9 @@ dependencyManagement {
|
|||||||
|
|
||||||
dependency 'com.github.tomakehurst:wiremock-standalone:3.0.1'
|
dependency 'com.github.tomakehurst:wiremock-standalone:3.0.1'
|
||||||
|
|
||||||
dependency 'io.cucumber:cucumber-java:7.16.1'
|
dependency 'io.cucumber:cucumber-java:7.20.1'
|
||||||
dependency 'io.cucumber:cucumber-java8:7.16.1'
|
dependency 'io.cucumber:cucumber-java8:7.20.1'
|
||||||
dependency 'io.cucumber:cucumber-junit-platform-engine:7.16.1'
|
dependency 'io.cucumber:cucumber-junit-platform-engine:7.20.1'
|
||||||
dependency 'io.cucumber:cucumber-spring:7.16.1'
|
dependency 'io.cucumber:cucumber-spring:7.20.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,8 +334,6 @@ class FineractPlugin implements Plugin<Project> {
|
|||||||
gpgService.sign(step.gpg)
|
gpgService.sign(step.gpg)
|
||||||
|
|
||||||
step.gpg.files.findAll {
|
step.gpg.files.findAll {
|
||||||
gpgService.md5(step.gpg)
|
|
||||||
|
|
||||||
gpgService.sha512(step.gpg)
|
gpgService.sha512(step.gpg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,29 +438,10 @@ class FineractPlugin implements Plugin<Project> {
|
|||||||
project.tasks.register("fineractReleaseStep12") {
|
project.tasks.register("fineractReleaseStep12") {
|
||||||
doFirst {
|
doFirst {
|
||||||
FineractPluginExtension.FineractPluginStep step = step(extension, "step12")
|
FineractPluginExtension.FineractPluginStep step = step(extension, "step12")
|
||||||
|
|
||||||
String version = project.properties?['fineract.release.version']
|
|
||||||
|
|
||||||
if(!version) {
|
|
||||||
TextIO textIO = TextIoFactory.getTextIO()
|
|
||||||
|
|
||||||
version = textIO.newStringInputReader()
|
|
||||||
.withPattern("\\d+.\\d+.\\d+")
|
|
||||||
.read("Release Version");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: input validation, see FINERACT-1610
|
// TODO: input validation, see FINERACT-1610
|
||||||
|
|
||||||
subversionService.checkout(step.subversion)
|
// TODO: implement this, see FINERACT-1817
|
||||||
|
printInstructions(project, "step12")
|
||||||
def directory = step.subversion.directory?:System.getProperty("java.io.tmpdir") + "/fineract-dist-release"
|
|
||||||
|
|
||||||
def source = new File("fineract-war/build/distributions")
|
|
||||||
def target = new File("${directory}/${version}")
|
|
||||||
|
|
||||||
FileUtils.copyDirectory(source, target, true)
|
|
||||||
|
|
||||||
subversionService.commit(step.subversion)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,15 +116,6 @@ class GpgService {
|
|||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void md5(FineractPluginExtension.FineractPluginGpgParams params) {
|
|
||||||
params.files.findAll {
|
|
||||||
def result = calc(new FileInputStream(it), MessageDigest.getInstance("MD5", BouncyCastleProvider.PROVIDER_NAME))
|
|
||||||
def file = new File("${it}.md5")
|
|
||||||
file.write result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512(FineractPluginExtension.FineractPluginGpgParams params) {
|
void sha512(FineractPluginExtension.FineractPluginGpgParams params) {
|
||||||
params.files.findAll {
|
params.files.findAll {
|
||||||
def result = calc(new FileInputStream(it), MessageDigest.getInstance("SHA-512", BouncyCastleProvider.PROVIDER_NAME))
|
def result = calc(new FileInputStream(it), MessageDigest.getInstance("SHA-512", BouncyCastleProvider.PROVIDER_NAME))
|
||||||
|
|||||||
@@ -20,15 +20,15 @@
|
|||||||
-->
|
-->
|
||||||
Hello everyone,
|
Hello everyone,
|
||||||
|
|
||||||
... we have created Apache Fineract ${project['fineract.release.version']} release, with the artifacts below up for a vote.
|
We are proud to present Apache Fineract ${project['fineract.release.version']}, with the artifacts below up for a vote. Releases are important for a number of reasons: They put a stamp of approval on a set of code changes and they build momentum for future improvements.
|
||||||
|
|
||||||
It fixes the following issues: https://cwiki.apache.org/confluence/display/FINERACT/${project['fineract.release.version']}+-+Apache+Fineract
|
Release notes and ChangeLog: https://cwiki.apache.org/confluence/display/FINERACT/${project['fineract.release.version']}+-+Apache+Fineract
|
||||||
|
|
||||||
Source & Binary files : https://dist.apache.org/repos/dist/dev/fineract/${project['fineract.release.version']}/
|
Source and binary artifacts: https://dist.apache.org/repos/dist/dev/fineract/${project['fineract.release.version']}/
|
||||||
|
|
||||||
Tag to be voted on (rc#): https://gitbox.apache.org/repos/asf?p=fineract.git;a=commit;h=refs/heads/${project['fineract.release.version']}
|
Tagged as ${project['fineract.release.version']}
|
||||||
|
|
||||||
Fineract's KEYS containing the PGP key we used to sign the release: https://dist.apache.org/repos/dist/dev/fineract/KEYS
|
Committer PGP keys, including the release signing key: https://dist.apache.org/repos/dist/dev/fineract/KEYS
|
||||||
|
|
||||||
Note that this release contains source and binary artifacts.
|
Note that this release contains source and binary artifacts.
|
||||||
|
|
||||||
@@ -38,6 +38,16 @@ This vote will be open for 72 hours:
|
|||||||
[ ] +0 no opinion
|
[ ] +0 no opinion
|
||||||
[ ] -1 disapprove (and reason why)
|
[ ] -1 disapprove (and reason why)
|
||||||
|
|
||||||
|
Please indicate if you are a binding vote (member of the PMC).
|
||||||
|
|
||||||
|
Please also indicate with "Tested: YES/NO/PARTIAL" if you have locally built and/or tested these artifacts and/or a clone of the code checked out to the release commit, following the form:
|
||||||
|
|
||||||
|
Tested: YES ... Verified integrity and signatures of release artifacts locally, built from source, ran jar/war: Did everything mentioned in the current release candidate verification guidance ( https://lists.apache.org/thread/hym94pdy3nk9gjspkz4qonv2v15n5dpo ). If you did more than that, please specify.
|
||||||
|
|
||||||
|
Tested: NO ... No testing performed on release candidate, e.g. relying on testing performed by other contributors and/or output of GitHub Actions, while exercising my right to vote.
|
||||||
|
|
||||||
|
Tested: PARTIAL ... Please specify.
|
||||||
|
|
||||||
Cheers,
|
Cheers,
|
||||||
|
|
||||||
${project['fineract.config.name']}
|
${project['fineract.config.name']}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
[INSTRUCTIONS:START]
|
||||||
|
|
||||||
|
Move the release candidate from the dev area to the release area using a Subversion server-side copy:
|
||||||
|
|
||||||
|
svn mv https://dist.apache.org/repos/dist/dev/fineract/${project['fineract.release.version']} https://dist.apache.org/repos/dist/release /fineract/
|
||||||
|
|
||||||
|
[INSTRUCTIONS:END]
|
||||||
@@ -27,9 +27,9 @@ Following are the typical things we need to verify before voting on a release ca
|
|||||||
Make sure release artifacts are hosted at https://dist.apache.org/repos/dist/dev/fineract
|
Make sure release artifacts are hosted at https://dist.apache.org/repos/dist/dev/fineract
|
||||||
|
|
||||||
* Release candidates should be in format apache-fineract-${project['fineract.release.version']}-binary.tar.gz
|
* Release candidates should be in format apache-fineract-${project['fineract.release.version']}-binary.tar.gz
|
||||||
* Verify signatures and hashes. You may have to import the public key of the release manager to verify the signatures. (`gpg --recv-key <key id>`)
|
* Verify signatures and hashes. You may have to import the public key of the release manager to verify the signatures. (gpg --import KEYS or gpg --recv-key <key id>)
|
||||||
* Git tag matches the released bits (diff -rf)
|
* Git tag matches the released bits (diff -rf)
|
||||||
* Can compile successfully from source
|
* Can compile docs and code successfully from source
|
||||||
* Verify DISCLAIMER, NOTICE and LICENSE (year etc)
|
* Verify DISCLAIMER, NOTICE and LICENSE (year etc)
|
||||||
* All files have correct headers (Rat check should be clean - gradlew rat)
|
* All files have correct headers (Rat check should be clean - gradlew rat)
|
||||||
* No jar files in the source artifacts
|
* No jar files in the source artifacts
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
fineract:
|
fineract:
|
||||||
# user: "${FINERACT_USER}:${FINERACT_GROUP}"
|
# user: "${FINERACT_USER}:${FINERACT_GROUP}"
|
||||||
image: fineract-custom:latest
|
image: ${IMAGE_NAME:-fineract-custom:latest}
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml
|
- ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml
|
||||||
- ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro
|
- ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
fineract:
|
fineract:
|
||||||
# user: "${FINERACT_USER}:${FINERACT_GROUP}"
|
# user: "${FINERACT_USER}:${FINERACT_GROUP}"
|
||||||
image: fineract:latest
|
image: ${IMAGE_NAME:-apache/fineract:latest}
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml
|
- ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml
|
||||||
- ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro
|
- ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
mariadb:
|
mariadb:
|
||||||
container_name: mariadb
|
container_name: mariadb
|
||||||
image: mariadb:11.2
|
image: mariadb:11.4
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/config/docker/mysql/conf.d/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf:ro
|
- ${PWD}/config/docker/mysql/conf.d/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf:ro
|
||||||
- ${PWD}/config/docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z,ro
|
- ${PWD}/config/docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z,ro
|
||||||
|
|||||||
Vendored
+5
@@ -17,5 +17,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=true
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=true
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_BROKER_URL=tcp://activemq:61616
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_BROKER_URL=tcp://activemq:61616
|
||||||
|
FINERACT_EXTERNAL_EVENTS_ENABLED=true
|
||||||
|
FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_ENABLED=true
|
||||||
|
FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_TOPIC_NAME=events
|
||||||
|
FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_BROKER_URL=tcp://activemq:61616
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
|
|||||||
FINERACT_DEFAULT_MASTER_PASSWORD=fineract
|
FINERACT_DEFAULT_MASTER_PASSWORD=fineract
|
||||||
FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE=health,info,prometheus
|
FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE=health,info,prometheus
|
||||||
FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION=fineract
|
FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION=fineract
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=true
|
||||||
FINERACT_INSECURE_HTTP_CLIENT=true
|
FINERACT_INSECURE_HTTP_CLIENT=true
|
||||||
SPRING_PROFILES_ACTIVE=test,diagnostics
|
SPRING_PROFILES_ACTIVE=test,diagnostics
|
||||||
OTEL_SERVICE_NAME=fineract
|
OTEL_SERVICE_NAME=fineract
|
||||||
|
|||||||
+1
@@ -17,6 +17,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=false
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=false
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED=true
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED=true
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS=b-3-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198,b-2-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198,b-1-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS=b-3-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198,b-2-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198,b-1-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198
|
||||||
|
|||||||
Vendored
+1
@@ -17,6 +17,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=false
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=false
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED=true
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED=true
|
||||||
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS=kafka:9092
|
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS=kafka:9092
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract external events'
|
description = 'ACME Fineract Event External Event'
|
||||||
|
|
||||||
group = 'com.acme.fineract.event'
|
group = 'com.acme.fineract.event'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-event-externalevent'
|
base {
|
||||||
|
archivesName = 'acme-fineract-event-externalevent'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract Event Starter'
|
description = 'ACME Fineract Event Starter'
|
||||||
|
|
||||||
group = 'com.acme.fineract.event'
|
group = 'com.acme.fineract.event'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-event-starter'
|
base {
|
||||||
|
archivesName = 'acme-fineract-event-starter'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract COB Loan'
|
description = 'ACME Fineract Loan COB'
|
||||||
|
|
||||||
group = 'com.acme.fineract'
|
group = 'com.acme.fineract'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-loan-cob'
|
base {
|
||||||
|
archivesName = 'acme-fineract-loan-cob'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract Loan Job'
|
description = 'ACME Fineract Loan Job'
|
||||||
|
|
||||||
group = 'com.acme.fineract'
|
group = 'com.acme.fineract'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-loan-job'
|
base {
|
||||||
|
archivesName = 'acme-fineract-loan-job'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
+5
-7
@@ -18,26 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
package com.acme.fineract.loan.job;
|
package com.acme.fineract.loan.job;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.batch.core.Job;
|
import org.springframework.batch.core.Job;
|
||||||
import org.springframework.batch.core.Step;
|
import org.springframework.batch.core.Step;
|
||||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||||
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
||||||
import org.springframework.batch.core.repository.JobRepository;
|
import org.springframework.batch.core.repository.JobRepository;
|
||||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class AcmeNoopJobConfiguration {
|
public class AcmeNoopJobConfiguration {
|
||||||
|
|
||||||
@Autowired
|
private final JobRepository jobRepository;
|
||||||
private JobRepository jobRepository;
|
private final PlatformTransactionManager transactionManager;
|
||||||
@Autowired
|
private final AcmeNoopJobTasklet tasklet;
|
||||||
private PlatformTransactionManager transactionManager;
|
|
||||||
@Autowired
|
|
||||||
private AcmeNoopJobTasklet tasklet;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
protected Step acmeNoopJobStep() {
|
protected Step acmeNoopJobStep() {
|
||||||
|
|||||||
@@ -42,4 +42,10 @@
|
|||||||
<column name="is_mismatched_job" valueBoolean="true"/>
|
<column name="is_mismatched_job" valueBoolean="true"/>
|
||||||
</insert>
|
</insert>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
<changeSet author="acme" id="2">
|
||||||
|
<update tableName="job">
|
||||||
|
<column name="short_name" value="ACM_NOOP"/>
|
||||||
|
<where>name='Acme Noop Job'</where>
|
||||||
|
</update>
|
||||||
|
</changeSet>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract Loan Transaction Processors'
|
description = 'ACME Fineract Loan Processor'
|
||||||
|
|
||||||
group = 'com.acme.fineract'
|
group = 'com.acme.fineract'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-loan-processor'
|
base {
|
||||||
|
archivesName = 'acme-fineract-loan-processor'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
+5
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.acme.fineract.loan.processor;
|
package com.acme.fineract.loan.processor;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.FineractStyleLoanRepaymentScheduleTransactionProcessor;
|
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.FineractStyleLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -28,6 +29,10 @@ public class AcmeLoanRepaymentScheduleTransactionProcessor extends FineractStyle
|
|||||||
|
|
||||||
public static final String STRATEGY_NAME = "ACME Corp.: standard loan transaction processing strategy";
|
public static final String STRATEGY_NAME = "ACME Corp.: standard loan transaction processing strategy";
|
||||||
|
|
||||||
|
public AcmeLoanRepaymentScheduleTransactionProcessor(ExternalIdFactory externalIdFactory) {
|
||||||
|
super(externalIdFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCode() {
|
public String getCode() {
|
||||||
return STRATEGY_CODE;
|
return STRATEGY_CODE;
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract COB Starter'
|
description = 'ACME Fineract Loan Starter'
|
||||||
|
|
||||||
group = 'com.acme.fineract'
|
group = 'com.acme.fineract'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-loan-starter'
|
base {
|
||||||
|
archivesName = 'acme-fineract-loan-starter'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract Note Service'
|
description = 'ACME Fineract Note Service'
|
||||||
|
|
||||||
group = 'com.acme.fineract.portfolio.note'
|
group = 'com.acme.fineract'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-note-service'
|
base {
|
||||||
|
archivesName = 'acme-fineract-note-service'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.acme.fineract.portfolio.note.service;
|
package com.acme.fineract.portfolio.note.service;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.portfolio.note.data.NoteData;
|
import org.apache.fineract.portfolio.note.data.NoteData;
|
||||||
import org.apache.fineract.portfolio.note.service.NoteReadPlatformService;
|
import org.apache.fineract.portfolio.note.service.NoteReadPlatformService;
|
||||||
@@ -42,7 +42,7 @@ public class AcmeNoteReadPlatformService implements NoteReadPlatformService, Ini
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<NoteData> retrieveNotesByResource(Long resourceId, Integer noteTypeId) {
|
public List<NoteData> retrieveNotesByResource(Long resourceId, Integer noteTypeId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -39,21 +39,21 @@ public class AcmeNoteWritePlatformService implements NoteWritePlatformService, I
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult createNote(JsonCommand command) {
|
public CommandProcessingResult createNote(JsonCommand command) {
|
||||||
return null;
|
throw new UnsupportedOperationException("createNote() is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult updateNote(JsonCommand command) {
|
public CommandProcessingResult updateNote(JsonCommand command) {
|
||||||
return null;
|
throw new UnsupportedOperationException("updateNote() is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult deleteNote(JsonCommand command) {
|
public CommandProcessingResult deleteNote(JsonCommand command) {
|
||||||
return null;
|
throw new UnsupportedOperationException("deleteNote() is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAndPersistClientNote(Client client, JsonCommand command) {
|
public void createAndPersistClientNote(Client client, JsonCommand command) {
|
||||||
|
log.warn("createAndPersistClientNote() is intentionally left empty and does nothing.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
description = 'ACME Corp.: Fineract Note Starter'
|
description = 'ACME Fineract Note Starter'
|
||||||
|
|
||||||
group = 'com.acme.fineract.portfolio.note'
|
group = 'com.acme.fineract'
|
||||||
|
|
||||||
archivesBaseName = 'acme-fineract-note-starter'
|
base {
|
||||||
|
archivesName = 'acme-fineract-note-starter'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
version: "3.7"
|
version: "3.7"
|
||||||
services:
|
services:
|
||||||
kafka:
|
kafka:
|
||||||
image: "bitnami/kafka:3.5.1-debian-11-r7"
|
image: "bitnami/kafka:3.8.1-debian-12-r1"
|
||||||
ports:
|
ports:
|
||||||
- "9092:9092"
|
- "9092:9092"
|
||||||
env_file:
|
env_file:
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# 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.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
activemq:
|
||||||
|
extends:
|
||||||
|
file: ./config/docker/compose/activemq.yml
|
||||||
|
service: activemq
|
||||||
|
|
||||||
|
db:
|
||||||
|
extends:
|
||||||
|
file: ./config/docker/compose/postgresql.yml
|
||||||
|
service: postgresql
|
||||||
|
|
||||||
|
fineract:
|
||||||
|
extends:
|
||||||
|
file: ./config/docker/compose/fineract.yml
|
||||||
|
service: fineract
|
||||||
|
ports:
|
||||||
|
- "8443:8443"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- ./config/docker/env/fineract.env
|
||||||
|
- ./config/docker/env/fineract-common.env
|
||||||
|
- ./config/docker/env/fineract-postgresql.env
|
||||||
|
- ./config/docker/env/activemq.env
|
||||||
@@ -20,7 +20,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
# Frontend service
|
# Frontend service
|
||||||
community-app:
|
community-app:
|
||||||
image: openmf/web-app:latest
|
image: openmf/web-app:master
|
||||||
container_name: mifos-web-app
|
container_name: mifos-web-app
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ compileJava.doLast {
|
|||||||
javaexec {
|
javaexec {
|
||||||
description = 'Performs EclipseLink static weaving of entity classes'
|
description = 'Performs EclipseLink static weaving of entity classes'
|
||||||
def target = source
|
def target = source
|
||||||
main 'org.eclipse.persistence.tools.weaving.jpa.StaticWeave'
|
mainClass = 'org.eclipse.persistence.tools.weaving.jpa.StaticWeave'
|
||||||
args '-persistenceinfo', source, source, target
|
args '-persistenceinfo', source, source, target
|
||||||
classpath sourceSets.main.runtimeClasspath
|
classpath sourceSets.main.runtimeClasspath
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -32,6 +32,7 @@ import jakarta.ws.rs.Path;
|
|||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.accounting.accrual.request.AccrualAccountRequest;
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
@@ -54,13 +55,10 @@ public class AccrualAccountingApiResource {
|
|||||||
@Operation(summary = "Executes Periodic Accrual Accounting", method = "POST", description = "Mandatory Fields\n" + "\n" + "tillDate\n")
|
@Operation(summary = "Executes Periodic Accrual Accounting", method = "POST", description = "Mandatory Fields\n" + "\n" + "tillDate\n")
|
||||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = AccrualAccountingApiResourceSwagger.PostRunaccrualsRequest.class)))
|
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = AccrualAccountingApiResourceSwagger.PostRunaccrualsRequest.class)))
|
||||||
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
|
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
|
||||||
public String executePeriodicAccrualAccounting(@Parameter(hidden = true) final String jsonRequestBody) {
|
public CommandProcessingResult executePeriodicAccrualAccounting(@Parameter(hidden = true) AccrualAccountRequest accrualAccountRequest) {
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().excuteAccrualAccounting()
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().excuteAccrualAccounting().withJson(jsonRequestBody).build();
|
.withJson(apiJsonSerializerService.serialize(accrualAccountRequest)).build();
|
||||||
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -24,9 +24,9 @@ public final class AccrualAccountingConstants {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String accrueTillParamName = "tillDate";
|
public static final String ACCRUE_TILL_PARAM_NAME = "tillDate";
|
||||||
public static final String localeParamName = "locale";
|
public static final String LOCALE_PARAM_NAME = "locale";
|
||||||
public static final String dateFormatParamName = "dateFormat";
|
public static final String DATE_FORMAT_PARAM_NAME = "dateFormat";
|
||||||
|
|
||||||
public static final String PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME = "periodicaccrual";
|
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 String PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE = "execution.failed";
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.request;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public record AccrualAccountRequest(String locale, String dateFormat, String tillDate) implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
+6
-6
@@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.accrual.serialization;
|
package org.apache.fineract.accounting.accrual.serialization;
|
||||||
|
|
||||||
|
import static org.apache.fineract.accounting.accrual.api.AccrualAccountingConstants.ACCRUE_TILL_PARAM_NAME;
|
||||||
import static org.apache.fineract.accounting.accrual.api.AccrualAccountingConstants.PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME;
|
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 com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
@@ -46,8 +46,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class AccrualAccountingDataValidator {
|
public final class AccrualAccountingDataValidator {
|
||||||
|
|
||||||
private static final Set<String> LOAN_PERIODIC_REQUEST_DATA_PARAMETERS = new HashSet<>(
|
private static final Set<String> LOAN_PERIODIC_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(ACCRUE_TILL_PARAM_NAME,
|
||||||
Arrays.asList(accrueTillParamName, AccrualAccountingConstants.localeParamName, AccrualAccountingConstants.dateFormatParamName));
|
AccrualAccountingConstants.LOCALE_PARAM_NAME, AccrualAccountingConstants.DATE_FORMAT_PARAM_NAME));
|
||||||
|
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
@@ -63,11 +63,11 @@ public final class AccrualAccountingDataValidator {
|
|||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
|
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
|
||||||
|
|
||||||
final LocalDate date = this.fromApiJsonHelper.extractLocalDateNamed(accrueTillParamName, element);
|
final LocalDate date = this.fromApiJsonHelper.extractLocalDateNamed(ACCRUE_TILL_PARAM_NAME, element);
|
||||||
baseDataValidator.reset().parameter(accrueTillParamName).value(date).notNull().validateDateBefore(DateUtils.getBusinessLocalDate());
|
baseDataValidator.reset().parameter(ACCRUE_TILL_PARAM_NAME).value(date).notNull()
|
||||||
|
.validateDateBefore(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
public void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public enum GLClosureJsonInputParams {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name().toString().replaceAll("_", " ");
|
return name().replace("_", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
|
|||||||
+22
-41
@@ -39,12 +39,10 @@ import jakarta.ws.rs.QueryParam;
|
|||||||
import jakarta.ws.rs.core.Context;
|
import jakarta.ws.rs.core.Context;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.UriInfo;
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.accounting.closure.data.GLClosureData;
|
import org.apache.fineract.accounting.closure.data.GLClosureData;
|
||||||
|
import org.apache.fineract.accounting.closure.data.request.GLClosureRequest;
|
||||||
import org.apache.fineract.accounting.closure.service.GLClosureReadPlatformService;
|
import org.apache.fineract.accounting.closure.service.GLClosureReadPlatformService;
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
@@ -66,10 +64,6 @@ import org.springframework.stereotype.Component;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GLClosuresApiResource {
|
public class GLClosuresApiResource {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
|
||||||
Arrays.asList("id", "officeId", "officeName", "closingDate", "deleted", "createdDate", "lastUpdatedDate", "createdByUserId",
|
|
||||||
"createdByUsername", "lastUpdatedByUserId", "lastUpdatedByUsername"));
|
|
||||||
|
|
||||||
private static final String RESOURCE_NAME_FOR_PERMISSION = "GLCLOSURE";
|
private static final String RESOURCE_NAME_FOR_PERMISSION = "GLCLOSURE";
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
@@ -85,14 +79,10 @@ public class GLClosuresApiResource {
|
|||||||
@Operation(summary = "List Accounting closures", description = "Example Requests:\n" + "\n" + "glclosures")
|
@Operation(summary = "List Accounting closures", description = "Example Requests:\n" + "\n" + "glclosures")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GLClosuresApiResourceSwagger.GetGlClosureResponse.class)))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GLClosuresApiResourceSwagger.GetGlClosureResponse.class)))) })
|
||||||
public String retrieveAllClosures(@Context final UriInfo uriInfo,
|
public List<GLClosureData> retrieveAllClosures(@QueryParam("officeId") @Parameter(name = "officeId") final Long officeId) {
|
||||||
@QueryParam("officeId") @Parameter(name = "officeId") final Long officeId) {
|
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
final List<GLClosureData> glClosureDatas = this.glClosureReadPlatformService.retrieveAllGLClosures(officeId);
|
return glClosureReadPlatformService.retrieveAllGLClosures(officeId);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, glClosureDatas, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -103,19 +93,17 @@ public class GLClosuresApiResource {
|
|||||||
+ "/glclosures/1?fields=officeName,closingDate")
|
+ "/glclosures/1?fields=officeName,closingDate")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.GetGlClosureResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.GetGlClosureResponse.class))) })
|
||||||
public String retreiveClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
|
public GLClosureData retreiveClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
|
||||||
@Context final UriInfo uriInfo) {
|
@Context final UriInfo uriInfo) {
|
||||||
|
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final GLClosureData glClosureData = glClosureReadPlatformService.retrieveGLClosureById(glClosureId);
|
||||||
|
|
||||||
final GLClosureData glClosureData = this.glClosureReadPlatformService.retrieveGLClosureById(glClosureId);
|
|
||||||
if (settings.isTemplate()) {
|
if (settings.isTemplate()) {
|
||||||
glClosureData.setAllowedOffices(this.officeReadPlatformService.retrieveAllOfficesForDropdown());
|
glClosureData.setAllowedOffices(officeReadPlatformService.retrieveAllOfficesForDropdown());
|
||||||
}
|
}
|
||||||
|
return glClosureData;
|
||||||
return this.apiJsonSerializerService.serialize(settings, glClosureData, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: proposal slight changes @Aleks
|
// NOTE: proposal slight changes @Aleks
|
||||||
@@ -126,13 +114,11 @@ public class GLClosuresApiResource {
|
|||||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PostGlClosuresRequest.class, description = "Request Body")))
|
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PostGlClosuresRequest.class, description = "Request Body")))
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PostGlClosuresResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PostGlClosuresResponse.class))) })
|
||||||
public String createGLClosure(@Parameter(hidden = true) final String jsonRequestBody) {
|
public CommandProcessingResult createGLClosure(@Parameter(hidden = true) GLClosureRequest glClosureRequest) {
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLClosure()
|
||||||
|
.withJson(apiJsonSerializerService.serialize(glClosureRequest)).build();
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLClosure().withJson(jsonRequestBody).build();
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@@ -143,13 +129,11 @@ public class GLClosuresApiResource {
|
|||||||
@RequestBody(content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PutGlClosuresRequest.class, required = true)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PutGlClosuresRequest.class, required = true)))
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PutGlClosuresResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.PutGlClosuresResponse.class))) })
|
||||||
public String updateGLClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
|
public CommandProcessingResult updateGLClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
|
||||||
@Parameter(hidden = true) final String jsonRequestBody) {
|
@Parameter(hidden = true) GLClosureRequest glClosureRequest) {
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLClosure(glClosureId).withJson(jsonRequestBody).build();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLClosure(glClosureId)
|
||||||
|
.withJson(apiJsonSerializerService.serialize(glClosureRequest)).build();
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@@ -159,12 +143,9 @@ public class GLClosuresApiResource {
|
|||||||
@Operation(summary = "Delete an accounting closure", description = "Note: Only the latest accounting closure associated with a branch may be deleted.")
|
@Operation(summary = "Delete an accounting closure", description = "Note: Only the latest accounting closure associated with a branch may be deleted.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.DeleteGlClosuresResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLClosuresApiResourceSwagger.DeleteGlClosuresResponse.class))) })
|
||||||
public String deleteGLClosure(@PathParam("glClosureId") @Parameter(description = "glclosureId") final Long glClosureId) {
|
public CommandProcessingResult deleteGLClosure(
|
||||||
|
@PathParam("glClosureId") @Parameter(description = "glclosureId") final Long glClosureId) {
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLClosure(glClosureId).build();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLClosure(glClosureId).build();
|
||||||
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-10
@@ -21,8 +21,6 @@ package org.apache.fineract.accounting.closure.command;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.apache.fineract.accounting.closure.api.GLClosureJsonInputParams;
|
import org.apache.fineract.accounting.closure.api.GLClosureJsonInputParams;
|
||||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||||
@@ -31,14 +29,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
|
|||||||
/**
|
/**
|
||||||
* Immutable command for adding an accounting closure
|
* Immutable command for adding an accounting closure
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
public record GLClosureCommand(Long id, Long officeId, LocalDate closingDate, String comments) {
|
||||||
@Getter
|
|
||||||
public class GLClosureCommand {
|
|
||||||
|
|
||||||
private final Long id;
|
|
||||||
private final Long officeId;
|
|
||||||
private final LocalDate closingDate;
|
|
||||||
private final String comments;
|
|
||||||
|
|
||||||
public void validateForCreate() {
|
public void validateForCreate() {
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.closure.data;
|
package org.apache.fineract.accounting.closure.data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -30,7 +32,10 @@ import org.apache.fineract.organisation.office.data.OfficeData;
|
|||||||
* Note: no getter/setters required as google-gson will produce json from fields of object.
|
* Note: no getter/setters required as google-gson will produce json from fields of object.
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GLClosureData {
|
public class GLClosureData implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
private final Long officeId;
|
private final Long officeId;
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.data.request;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public record GLClosureRequest(Long id, Long officeId, String closingDate, String comments, String dateFormat,
|
||||||
|
String locale) implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
||||||
+6
-6
@@ -32,21 +32,21 @@ public class GLClosureInvalidException extends AbstractPlatformDomainRuleExcepti
|
|||||||
FUTURE_DATE, ACCOUNTING_CLOSED;
|
FUTURE_DATE, ACCOUNTING_CLOSED;
|
||||||
|
|
||||||
public String errorMessage() {
|
public String errorMessage() {
|
||||||
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
|
if (name().equalsIgnoreCase("FUTURE_DATE")) {
|
||||||
return "Accounting closures cannot be made for a future date";
|
return "Accounting closures cannot be made for a future date";
|
||||||
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
|
} else if (name().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
|
||||||
return "Accounting Closure for this branch has already been defined for a greater date";
|
return "Accounting Closure for this branch has already been defined for a greater date";
|
||||||
}
|
}
|
||||||
return name().toString();
|
return name();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String errorCode() {
|
public String errorCode() {
|
||||||
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
|
if (name().equalsIgnoreCase("FUTURE_DATE")) {
|
||||||
return "error.msg.glclosure.invalid.future.date";
|
return "error.msg.glclosure.invalid.future.date";
|
||||||
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
|
} else if (name().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
|
||||||
return "error.msg.glclosure.invalid.accounting.closed";
|
return "error.msg.glclosure.invalid.accounting.closed";
|
||||||
}
|
}
|
||||||
return name().toString();
|
return name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-68
@@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.media.Content;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.DELETE;
|
import jakarta.ws.rs.DELETE;
|
||||||
@@ -41,6 +40,7 @@ import jakarta.ws.rs.core.UriInfo;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityAccountData;
|
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityAccountData;
|
||||||
|
import org.apache.fineract.accounting.financialactivityaccount.data.request.FinancialActivityAccRequest;
|
||||||
import org.apache.fineract.accounting.financialactivityaccount.service.FinancialActivityAccountReadPlatformService;
|
import org.apache.fineract.accounting.financialactivityaccount.service.FinancialActivityAccountReadPlatformService;
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
@@ -54,9 +54,17 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
@Path("/v1/financialactivityaccounts")
|
@Path("/v1/financialactivityaccounts")
|
||||||
@Component
|
@Component
|
||||||
@Tag(name = "Mapping Financial Activities to Accounts", description = "Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. Integrated accounting takes these accounts into consideration when an Account transfer is made between a savings to loan/savings account and vice-versa\n"
|
@Tag(name = "Mapping Financial Activities to Accounts", description = """
|
||||||
+ "\n" + "Field Descriptions\n" + "financialActivityId\n" + "The identifier of the Financial Activity\n" + "glAccountId\n"
|
Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. \
|
||||||
+ "The identifier of a GL Account ( Ledger Account) which shall be used as the default account for the selected Financial Activity")
|
Integrated accounting takes these accounts into consideration when an Account transfer is made between \
|
||||||
|
a savings to loan/savings account and vice-versa
|
||||||
|
|
||||||
|
Field Descriptions
|
||||||
|
financialActivityId
|
||||||
|
The identifier of the Financial Activity
|
||||||
|
glAccountId
|
||||||
|
The identifier of a GL Account ( Ledger Account) which shall be used as the default account for the selected Financial Activity
|
||||||
|
""")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class FinancialActivityAccountsApiResource {
|
public class FinancialActivityAccountsApiResource {
|
||||||
|
|
||||||
@@ -70,94 +78,72 @@ public class FinancialActivityAccountsApiResource {
|
|||||||
@Path("template")
|
@Path("template")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String retrieveTemplate(@Context final UriInfo uriInfo) {
|
public FinancialActivityAccountData retrieveTemplate() {
|
||||||
|
context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
||||||
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
return financialActivityAccountReadPlatformService.getFinancialActivityAccountTemplate();
|
||||||
|
|
||||||
FinancialActivityAccountData financialActivityAccountData = this.financialActivityAccountReadPlatformService
|
|
||||||
.getFinancialActivityAccountTemplate();
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, financialActivityAccountData,
|
|
||||||
FinancialActivityAccountsConstants.RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "List Financial Activities to Accounts Mappings", description = "Example Requests:\n" + "\n"
|
@Operation(summary = "List Financial Activities to Accounts Mappings", description = """
|
||||||
+ "financialactivityaccounts")
|
Example Requests:
|
||||||
@ApiResponses({
|
financialactivityaccounts""")
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class)))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class))))
|
||||||
public String retrieveAll(@Context final UriInfo uriInfo) {
|
public List<FinancialActivityAccountData> retrieveAll() {
|
||||||
|
context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
||||||
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
return financialActivityAccountReadPlatformService.retrieveAll();
|
||||||
final List<FinancialActivityAccountData> financialActivityAccounts = this.financialActivityAccountReadPlatformService.retrieveAll();
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, financialActivityAccounts,
|
|
||||||
FinancialActivityAccountsConstants.RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{mappingId}")
|
@Path("{mappingId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Retrieve a Financial Activity to Account Mapping\n", description = "Example Requests:\n" + "\n"
|
@Operation(summary = "Retrieve a Financial Activity to Account Mapping\n", description = """
|
||||||
+ "financialactivityaccounts/1")
|
Example Requests:
|
||||||
@ApiResponses({
|
financialactivityaccounts/1""")
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class)))
|
||||||
public String retreive(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId,
|
public FinancialActivityAccountData retreive(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId,
|
||||||
@Context final UriInfo uriInfo) {
|
@Context final UriInfo uriInfo) {
|
||||||
|
context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
FinancialActivityAccountData financialActivityAccountData = financialActivityAccountReadPlatformService.retrieve(mappingId);
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
FinancialActivityAccountData financialActivityAccountData = this.financialActivityAccountReadPlatformService.retrieve(mappingId);
|
|
||||||
if (settings.isTemplate()) {
|
if (settings.isTemplate()) {
|
||||||
financialActivityAccountData = this.financialActivityAccountReadPlatformService
|
financialActivityAccountData = financialActivityAccountReadPlatformService.addTemplateDetails(financialActivityAccountData);
|
||||||
.addTemplateDetails(financialActivityAccountData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, financialActivityAccountData,
|
return financialActivityAccountData;
|
||||||
FinancialActivityAccountsConstants.RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Create a new Financial Activity to Accounts Mapping", description = "Mandatory Fields\n"
|
@Operation(summary = "Create a new Financial Activity to Accounts Mapping", description = """
|
||||||
+ "financialActivityId, glAccountId")
|
Mandatory Fields
|
||||||
|
financialActivityId, glAccountId""")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class))) })
|
public CommandProcessingResult createGLAccount(@Parameter(hidden = true) FinancialActivityAccRequest activityAccRequest) {
|
||||||
public String createGLAccount(@Parameter(hidden = true) final String jsonRequestBody) {
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createOfficeToGLAccountMapping()
|
||||||
|
.withJson(apiJsonSerializerService.serialize(activityAccRequest)).build();
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createOfficeToGLAccountMapping().withJson(jsonRequestBody)
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
.build();
|
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{mappingId}")
|
@Path("{mappingId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Update a Financial Activity to Account Mapping", description = "the API updates the Ledger account linked to a Financial Activity \n")
|
@Operation(summary = "Update a Financial Activity to Account Mapping", description = "the API updates the Ledger account linked to a Financial Activity")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PutFinancialActivityAccountsResponse.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.PutFinancialActivityAccountsResponse.class))) })
|
public CommandProcessingResult updateGLAccount(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId,
|
||||||
public String updateGLAccount(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId,
|
@Parameter(hidden = true) FinancialActivityAccRequest activityAccRequest) {
|
||||||
@Parameter(hidden = true) final String jsonRequestBody) {
|
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateOfficeToGLAccountMapping(mappingId)
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateOfficeToGLAccountMapping(mappingId)
|
||||||
.withJson(jsonRequestBody).build();
|
.withJson(apiJsonSerializerService.serialize(activityAccRequest)).build();
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@@ -165,14 +151,9 @@ public class FinancialActivityAccountsApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Delete a Financial Activity to Account Mapping")
|
@Operation(summary = "Delete a Financial Activity to Account Mapping")
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.DeleteFinancialActivityAccountsResponse.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = FinancialActivityAccountsApiResourceSwagger.DeleteFinancialActivityAccountsResponse.class))) })
|
public CommandProcessingResult deleteGLAccount(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId) {
|
||||||
public String deleteGLAccount(@PathParam("mappingId") @Parameter(description = "mappingId") final Long mappingId) {
|
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteOfficeToGLAccountMapping(mappingId).build();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteOfficeToGLAccountMapping(mappingId).build();
|
||||||
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public enum FinancialActivityAccountsJsonInputParams {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name().toString().replaceAll("_", " ");
|
return name().replace("_", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.data.request;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public record FinancialActivityAccRequest(Long financialActivityId, Long glAccountId) implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
+6
-4
@@ -26,17 +26,19 @@ import org.springframework.dao.EmptyResultDataAccessException;
|
|||||||
*/
|
*/
|
||||||
public class FinancialActivityAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
public class FinancialActivityAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
private static final String DOES_NOT_EXIST = " does not exist";
|
||||||
|
private static final String ERROR_CODE = "error.msg.financialActivityAccount.not.found";
|
||||||
|
|
||||||
public FinancialActivityAccountNotFoundException(final Long id) {
|
public FinancialActivityAccountNotFoundException(final Long id) {
|
||||||
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with Id " + id + " does not exist", id);
|
super(ERROR_CODE, "Financial Activity account with Id " + id + DOES_NOT_EXIST, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FinancialActivityAccountNotFoundException(final Long id, EmptyResultDataAccessException e) {
|
public FinancialActivityAccountNotFoundException(final Long id, EmptyResultDataAccessException e) {
|
||||||
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with Id " + id + " does not exist", id, e);
|
super(ERROR_CODE, "Financial Activity account with Id " + id + DOES_NOT_EXIST, id, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FinancialActivityAccountNotFoundException(final Integer financialActivityType) {
|
public FinancialActivityAccountNotFoundException(final Integer financialActivityType) {
|
||||||
super("error.msg.financialActivityAccount.not.found",
|
super(ERROR_CODE, "Financial Activity account with for the financial Activity with Id " + financialActivityType + DOES_NOT_EXIST,
|
||||||
"Financial Activity account with for the financial Activity with Id " + financialActivityType + " does not exist",
|
|
||||||
financialActivityType);
|
financialActivityType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+96
-104
@@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.media.Content;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.DELETE;
|
import jakarta.ws.rs.DELETE;
|
||||||
@@ -41,14 +40,12 @@ import jakarta.ws.rs.core.MediaType;
|
|||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import jakarta.ws.rs.core.UriInfo;
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.accounting.common.AccountingConstants;
|
import org.apache.fineract.accounting.common.AccountingConstants;
|
||||||
import org.apache.fineract.accounting.common.AccountingDropdownReadPlatformService;
|
import org.apache.fineract.accounting.common.AccountingDropdownReadPlatformService;
|
||||||
|
import org.apache.fineract.accounting.glaccount.command.GLAccountCommand;
|
||||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||||
import org.apache.fineract.accounting.glaccount.service.GLAccountReadPlatformService;
|
import org.apache.fineract.accounting.glaccount.service.GLAccountReadPlatformService;
|
||||||
@@ -74,17 +71,13 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
@Path("/v1/glaccounts")
|
@Path("/v1/glaccounts")
|
||||||
@Component
|
@Component
|
||||||
@Tag(name = "General Ledger Account", description = "Ledger accounts represent an Individual account within an Organizations Chart Of Accounts(COA) and are assigned a name and unique number by which they can be identified. \n"
|
@Tag(name = "General Ledger Account", description = """
|
||||||
+ "All transactions relating to a company's assets, liabilities, owners' equity, revenue and expenses are recorded against these accounts")
|
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.
|
||||||
|
All transactions relating to a company's assets, liabilities, owners' equity, revenue and expenses are recorded against these accounts
|
||||||
|
""")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GLAccountsApiResource {
|
public class GLAccountsApiResource {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "parentId", "glCode", "disabled",
|
|
||||||
"manualEntriesAllowed", "type", "usage", "description", "assetHeaderAccountOptions", "liabilityHeaderAccountOptions",
|
|
||||||
"equityHeaderAccountOptions", "incomeHeaderAccountOptions", "expenseHeaderAccountOptions", "nameDecorated", "tagId",
|
|
||||||
"allowedAssetsTagOptions", "allowedLiabilitiesTagOptions", "allowedEquityTagOptions", "allowedIncomeTagOptions",
|
|
||||||
"allowedExpensesTagOptions", "creditAccounts", "debitAccounts"));
|
|
||||||
|
|
||||||
private static final String RESOURCE_NAME_FOR_PERMISSION = "GLACCOUNT";
|
private static final String RESOURCE_NAME_FOR_PERMISSION = "GLACCOUNT";
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
@@ -102,91 +95,103 @@ public class GLAccountsApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = {
|
@Operation(tags = {
|
||||||
"General Ledger Account" }, summary = "Retrieve GL Accounts Template", description = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
|
"General Ledger Account" }, summary = "Retrieve GL Accounts Template", description = """
|
||||||
+ "\n" + "Field Defaults\n" + "Allowed Value Lists\n" + "Example Request:\n" + "\n" + "glaccounts/template\n"
|
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:
|
||||||
+ "glaccounts/template?type=1\n" + "\n" + "type is optional and integer value from 1 to 5.\n" + "\n" + "1.Assets \n"
|
|
||||||
+ "2.Liabilities \n" + "3.Equity \n" + "4.Income \n" + "5.Expenses")
|
|
||||||
@ApiResponses({
|
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsTemplateResponse.class))) })
|
|
||||||
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo,
|
|
||||||
@QueryParam("type") @Parameter(description = "type") final Integer type) {
|
|
||||||
|
|
||||||
|
Field Defaults
|
||||||
|
Allowed Value Lists
|
||||||
|
Example Request:
|
||||||
|
|
||||||
|
glaccounts/template
|
||||||
|
glaccounts/template?type=1
|
||||||
|
|
||||||
|
type is optional and integer value from 1 to 5.
|
||||||
|
|
||||||
|
1.Assets
|
||||||
|
2.Liabilities
|
||||||
|
3.Equity
|
||||||
|
4.Income
|
||||||
|
5.Expenses
|
||||||
|
""")
|
||||||
|
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsTemplateResponse.class)))
|
||||||
|
public GLAccountData retrieveNewAccountDetails(@QueryParam("type") @Parameter(description = "type") final Integer type) {
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
|
|
||||||
GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveNewGLAccountDetails(type);
|
return handleTemplate(this.glAccountReadPlatformService.retrieveNewGLAccountDetails(type));
|
||||||
glAccountData = handleTemplate(glAccountData);
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, glAccountData, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = { "General Ledger Account" }, summary = "List General Ledger Accounts", description = "ARGUMENTS\n"
|
@Operation(tags = {
|
||||||
+ "type Integer optional manualEntriesAllowed boolean optional usage Integer optional disabled boolean optional parentId Long optional tagId Long optional\n"
|
"General Ledger Account" }, summary = "List General Ledger Account", description = """
|
||||||
+ "Example Requests:\n" + "\n" + "glaccounts\n" + "\n" + "\n"
|
ARGUMENTS
|
||||||
+ "glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false\n" + "\n" + "glaccounts?fetchRunningBalance=true")
|
type Integer optional manualEntriesAllowed boolean optional usage Integer optional disabled boolean optional parentId Long optional tagId Long optional
|
||||||
@ApiResponses({
|
Example Requests:
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class)))) })
|
|
||||||
public String retrieveAllAccounts(@Context final UriInfo uriInfo,
|
glaccounts
|
||||||
@QueryParam("type") @Parameter(description = "type") final Integer type,
|
|
||||||
|
glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false
|
||||||
|
|
||||||
|
glaccounts?fetchRunningBalance=true
|
||||||
|
""")
|
||||||
|
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class))))
|
||||||
|
public List<GLAccountData> retrieveAllAccounts(@QueryParam("type") @Parameter(description = "type") final Integer type,
|
||||||
@QueryParam("searchParam") @Parameter(description = "searchParam") final String searchParam,
|
@QueryParam("searchParam") @Parameter(description = "searchParam") final String searchParam,
|
||||||
@QueryParam("usage") @Parameter(description = "usage") final Integer usage,
|
@QueryParam("usage") @Parameter(description = "usage") final Integer usage,
|
||||||
@QueryParam("manualEntriesAllowed") @Parameter(description = "manualEntriesAllowed") final Boolean manualEntriesAllowed,
|
@QueryParam("manualEntriesAllowed") @Parameter(description = "manualEntriesAllowed") final Boolean manualEntriesAllowed,
|
||||||
@QueryParam("disabled") @Parameter(description = "disabled") final Boolean disabled,
|
@QueryParam("disabled") @Parameter(description = "disabled") final Boolean disabled,
|
||||||
@QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
|
@QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
|
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
|
||||||
final List<GLAccountData> glAccountDatas = this.glAccountReadPlatformService.retrieveAllGLAccounts(type, searchParam, usage,
|
return this.glAccountReadPlatformService.retrieveAllGLAccounts(type, searchParam, usage, manualEntriesAllowed, disabled,
|
||||||
manualEntriesAllowed, disabled, associationParametersData);
|
associationParametersData);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, glAccountDatas, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{glAccountId}")
|
@Path("{glAccountId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = { "General Ledger Account" }, summary = "Retrieve a General Ledger Account", description = "Example Requests:\n"
|
@Operation(tags = { "General Ledger Account" }, summary = "Retrieve a General Ledger Account", description = """
|
||||||
+ "\n" + "glaccounts/1\n" + "\n" + "\n" + "glaccounts/1?template=true\n" + "\n" + "\n" + "glaccounts/1?fields=name,glCode\n"
|
Example Requests:
|
||||||
+ "\n" + "\n" + "glaccounts/1?fetchRunningBalance=true")
|
|
||||||
@ApiResponses({
|
glaccounts/1
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class))) })
|
|
||||||
public String retreiveAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId,
|
glaccounts/1?template=true
|
||||||
|
|
||||||
|
glaccounts/1?fields=name,glCode
|
||||||
|
|
||||||
|
glaccounts/1?fetchRunningBalance=true
|
||||||
|
""")
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class)))
|
||||||
|
public GLAccountData retreiveAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId,
|
||||||
@Context final UriInfo uriInfo,
|
@Context final UriInfo uriInfo,
|
||||||
@QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
|
@QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
|
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
|
||||||
GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId, associationParametersData);
|
final GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId, associationParametersData);
|
||||||
if (settings.isTemplate()) {
|
return settings.isTemplate() ? handleTemplate(glAccountData) : glAccountData;
|
||||||
glAccountData = handleTemplate(glAccountData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, glAccountData, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = {
|
@Operation(tags = { "General Ledger Account" }, summary = "Create a General Ledger Account", description = """
|
||||||
"General Ledger Account" }, summary = "Create a General Ledger Account", description = "Note: You may optionally create Hierarchical Chart of Accounts by using the \"parentId\" property of an Account\n"
|
Note: You may optionally create Hierarchical Chart of Accounts by using the "parentId" property of an Account
|
||||||
+ "Mandatory Fields: \n" + "name, glCode, type, usage and manualEntriesAllowed")
|
Mandatory Fields:
|
||||||
|
name, glCode, type, usage and manualEntriesAllowed
|
||||||
|
""")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PostGLAccountsRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PostGLAccountsRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PostGLAccountsResponse.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PostGLAccountsResponse.class))) })
|
public CommandProcessingResult createGLAccount(@Parameter(hidden = true) GLAccountCommand glAccountCommand) {
|
||||||
public String createGLAccount(@Parameter(hidden = true) final String jsonRequestBody) {
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLAccount()
|
||||||
|
.withJson(apiJsonSerializerService.serialize(glAccountCommand)).build();
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLAccount().withJson(jsonRequestBody).build();
|
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@@ -195,16 +200,12 @@ public class GLAccountsApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = { "General Ledger Account" }, summary = "Update a GL Account", description = "Updates a GL Account")
|
@Operation(tags = { "General Ledger Account" }, summary = "Update a GL Account", description = "Updates a GL Account")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PutGLAccountsRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PutGLAccountsRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PutGLAccountsResponse.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.PutGLAccountsResponse.class))) })
|
public CommandProcessingResult updateGLAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId,
|
||||||
public String updateGLAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId,
|
@Parameter(hidden = true) GLAccountCommand accountCommand) {
|
||||||
@Parameter(hidden = true) final String jsonRequestBody) {
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLAccount(glAccountId)
|
||||||
|
.withJson(apiJsonSerializerService.serialize(accountCommand)).build();
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLAccount(glAccountId).withJson(jsonRequestBody).build();
|
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@@ -212,15 +213,30 @@ public class GLAccountsApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = { "General Ledger Account" }, summary = "Delete a GL Account", description = "Deletes a GL Account")
|
@Operation(tags = { "General Ledger Account" }, summary = "Delete a GL Account", description = "Deletes a GL Account")
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class))) })
|
public CommandProcessingResult deleteGLAccount(
|
||||||
public String deleteGLAccount(@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId) {
|
@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId) {
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
|
||||||
|
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
}
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
@POST
|
||||||
|
@Path("uploadtemplate")
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@RequestBody(description = "Upload GL accounts template", content = {
|
||||||
|
@Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) })
|
||||||
|
public Long postGlAccountsTemplate(@FormDataParam("file") InputStream uploadedInputStream,
|
||||||
|
@FormDataParam("file") FormDataContentDisposition fileDetail, @FormDataParam("locale") final String locale,
|
||||||
|
@FormDataParam("dateFormat") final String dateFormat) {
|
||||||
|
return bulkImportWorkbookService.importWorkbook(GlobalEntityType.CHART_OF_ACCOUNTS.toString(), uploadedInputStream, fileDetail,
|
||||||
|
locale, dateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GLAccountData handleTemplate(final GLAccountData glAccountData) {
|
private GLAccountData handleTemplate(final GLAccountData glAccountData) {
|
||||||
@@ -262,30 +278,6 @@ public class GLAccountsApiResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<GLAccountData> defaultIfEmpty(final List<GLAccountData> list) {
|
private List<GLAccountData> defaultIfEmpty(final List<GLAccountData> list) {
|
||||||
List<GLAccountData> returnList = null;
|
return list != null && !list.isEmpty() ? list : null;
|
||||||
if (list != null && !list.isEmpty()) {
|
|
||||||
returnList = list;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
@RequestBody(description = "Upload GL accounts template", content = {
|
|
||||||
@Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) })
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-15
@@ -20,8 +20,6 @@ package org.apache.fineract.accounting.glaccount.command;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.apache.fineract.accounting.glaccount.api.GLAccountJsonInputParams;
|
import org.apache.fineract.accounting.glaccount.api.GLAccountJsonInputParams;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountUsage;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountUsage;
|
||||||
@@ -32,20 +30,9 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
|
|||||||
/**
|
/**
|
||||||
* Immutable command for adding a general Ledger Account
|
* Immutable command for adding a general Ledger Account
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Getter
|
|
||||||
public class GLAccountCommand {
|
|
||||||
|
|
||||||
private final Long id;
|
public record GLAccountCommand(Long id, String name, Long parentId, String glCode, Boolean disabled, Boolean manualEntriesAllowed,
|
||||||
private final String name;
|
Integer type, Integer usage, String description, Long tagId) {
|
||||||
private final Long parentId;
|
|
||||||
private final String glCode;
|
|
||||||
private final Boolean disabled;
|
|
||||||
private final Boolean manualEntriesAllowed;
|
|
||||||
private final Integer type;
|
|
||||||
private final Integer usage;
|
|
||||||
private final String description;
|
|
||||||
private final Long tagId;
|
|
||||||
|
|
||||||
public void validateForCreate() {
|
public void validateForCreate() {
|
||||||
|
|
||||||
|
|||||||
+2
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.glaccount.data;
|
package org.apache.fineract.accounting.glaccount.data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -28,6 +29,7 @@ import lombok.experimental.Accessors;
|
|||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class GLAccountDataForLookup implements Serializable {
|
public class GLAccountDataForLookup implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|||||||
+8
-8
@@ -28,24 +28,24 @@ public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleE
|
|||||||
/*** Enum of reasons for invalid delete **/
|
/*** Enum of reasons for invalid delete **/
|
||||||
public enum GlAccountInvalidDeleteReason {
|
public enum GlAccountInvalidDeleteReason {
|
||||||
|
|
||||||
TRANSANCTIONS_LOGGED, HAS_CHILDREN;
|
TRANSACTIONS_LOGGED, HAS_CHILDREN;
|
||||||
|
|
||||||
public String errorMessage() {
|
public String errorMessage() {
|
||||||
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
|
if (name().equalsIgnoreCase("TRANSACTIONS_LOGGED")) {
|
||||||
return "This GL Account cannot be deleted as it has transactions logged against it";
|
return "This GL Account cannot be deleted as it has transactions logged against it";
|
||||||
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) {
|
} else if (name().equalsIgnoreCase("HAS_CHILDREN")) {
|
||||||
return "Cannot delete this Header GL Account without first deleting or reassinging its children";
|
return "Cannot delete this Header GL Account without first deleting or reassigning its children";
|
||||||
}
|
}
|
||||||
return name().toString();
|
return name();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String errorCode() {
|
public String errorCode() {
|
||||||
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
|
if (name().equalsIgnoreCase("TRANSACTIONS_LOGGED")) {
|
||||||
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
|
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
|
||||||
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) {
|
} else if (name().equalsIgnoreCase("HAS_CHILDREN")) {
|
||||||
return "error.msg.glaccount.glcode.invalid.delete.has.children";
|
return "error.msg.glaccount.glcode.invalid.delete.has.children";
|
||||||
}
|
}
|
||||||
return name().toString();
|
return name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-9
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.glaccount.jobs.updatetrialbalancedetails;
|
package org.apache.fineract.accounting.glaccount.jobs.updatetrialbalancedetails;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.TrialBalanceRepositoryWrapper;
|
import org.apache.fineract.accounting.glaccount.domain.TrialBalanceRepositoryWrapper;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
|
import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
|
||||||
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
||||||
@@ -27,22 +28,18 @@ import org.springframework.batch.core.job.builder.JobBuilder;
|
|||||||
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
||||||
import org.springframework.batch.core.repository.JobRepository;
|
import org.springframework.batch.core.repository.JobRepository;
|
||||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class UpdateTrialBalanceDetailsConfig {
|
public class UpdateTrialBalanceDetailsConfig {
|
||||||
|
|
||||||
@Autowired
|
private final JobRepository jobRepository;
|
||||||
private JobRepository jobRepository;
|
private final PlatformTransactionManager transactionManager;
|
||||||
@Autowired
|
private final RoutingDataSourceServiceFactory dataSourceServiceFactory;
|
||||||
private PlatformTransactionManager transactionManager;
|
private final TrialBalanceRepositoryWrapper trialBalanceRepositoryWrapper;
|
||||||
@Autowired
|
|
||||||
private RoutingDataSourceServiceFactory dataSourceServiceFactory;
|
|
||||||
@Autowired
|
|
||||||
private TrialBalanceRepositoryWrapper trialBalanceRepositoryWrapper;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
protected Step updateTrialBalanceDetailsStep() {
|
protected Step updateTrialBalanceDetailsStep() {
|
||||||
|
|||||||
+1
-2
@@ -20,7 +20,6 @@ package org.apache.fineract.accounting.glaccount.jobs.updatetrialbalancedetails;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -51,7 +50,7 @@ public class UpdateTrialBalanceDetailsTasklet implements Tasklet {
|
|||||||
.append("where je.transaction_date > (select coalesce(MAX(created_date),'2010-01-01') from m_trial_balance)");
|
.append("where je.transaction_date > (select coalesce(MAX(created_date),'2010-01-01') from m_trial_balance)");
|
||||||
final List<LocalDate> tbGaps = jdbcTemplate.queryForList(tbGapSqlBuilder.toString(), LocalDate.class);
|
final List<LocalDate> tbGaps = jdbcTemplate.queryForList(tbGapSqlBuilder.toString(), LocalDate.class);
|
||||||
for (LocalDate tbGap : tbGaps) {
|
for (LocalDate tbGap : tbGaps) {
|
||||||
int days = Math.toIntExact(ChronoUnit.DAYS.between(tbGap, DateUtils.getBusinessLocalDate()));
|
int days = DateUtils.getExactDifferenceInDays(tbGap, DateUtils.getBusinessLocalDate());
|
||||||
if (days < 1) {
|
if (days < 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-30
@@ -44,10 +44,12 @@ import org.springframework.stereotype.Service;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformService {
|
public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformService {
|
||||||
|
|
||||||
private static final String nameDecoratedBaseOnHierarchy = "concat(substring('........................................', 1, ((LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '.', '')) - 1) * 4)), name)";
|
private static final String NAME_DECORATED_BASE_ON_HIERARCHY = "concat(substring('........................................', 1, ((LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '.', '')) - 1) * 4)), name)";
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
private static final String SQL_AND = " and ";
|
||||||
|
|
||||||
private static final class GLAccountMapper implements RowMapper<GLAccountData> {
|
private static final class GLAccountMapper implements RowMapper<GLAccountData> {
|
||||||
|
|
||||||
private final JournalEntryAssociationParametersData associationParametersData;
|
private final JournalEntryAssociationParametersData associationParametersData;
|
||||||
@@ -65,7 +67,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
sb.append(
|
sb.append(
|
||||||
" gl.id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, ")
|
" gl.id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, ")
|
||||||
.append("classification_enum as classification, account_usage as accountUsage, gl.description as description, ")
|
.append("classification_enum as classification, account_usage as accountUsage, gl.description as description, ")
|
||||||
.append(nameDecoratedBaseOnHierarchy).append(" as nameDecorated, ")
|
.append(NAME_DECORATED_BASE_ON_HIERARCHY).append(" as nameDecorated, ")
|
||||||
.append("cv.id as codeId, cv.code_value as codeValue ");
|
.append("cv.id as codeId, cv.code_value as codeValue ");
|
||||||
if (this.associationParametersData.isRunningBalanceRequired()) {
|
if (this.associationParametersData.isRunningBalanceRequired()) {
|
||||||
sb.append(",gl_j.organization_running_balance as organizationRunningBalance ");
|
sb.append(",gl_j.organization_running_balance as organizationRunningBalance ");
|
||||||
@@ -109,29 +111,23 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
public List<GLAccountData> retrieveAllGLAccounts(final Integer accountClassification, final String searchParam, final Integer usage,
|
public List<GLAccountData> retrieveAllGLAccounts(final Integer accountClassification, final String searchParam, final Integer usage,
|
||||||
final Boolean manualTransactionsAllowed, final Boolean disabled,
|
final Boolean manualTransactionsAllowed, final Boolean disabled,
|
||||||
JournalEntryAssociationParametersData associationParametersData) {
|
JournalEntryAssociationParametersData associationParametersData) {
|
||||||
if (accountClassification != null) {
|
if (accountClassification != null && !checkValidGLAccountType(accountClassification)) {
|
||||||
if (!checkValidGLAccountType(accountClassification)) {
|
|
||||||
throw new GLAccountInvalidClassificationException(accountClassification);
|
throw new GLAccountInvalidClassificationException(accountClassification);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (usage != null) {
|
if (usage != null && !checkValidGLAccountUsage(usage)) {
|
||||||
if (!checkValidGLAccountUsage(usage)) {
|
|
||||||
throw new GLAccountInvalidClassificationException(accountClassification);
|
throw new GLAccountInvalidClassificationException(accountClassification);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
|
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
|
||||||
String sql = "select " + rm.schema();
|
String sql = "select " + rm.schema();
|
||||||
// append SQL statement for fetching account totals
|
// append SQL statement for fetching account totals
|
||||||
if (associationParametersData != null) {
|
if (associationParametersData != null && associationParametersData.isRunningBalanceRequired()) {
|
||||||
if (associationParametersData.isRunningBalanceRequired()) {
|
|
||||||
sql = sql + " and gl_j.id in (select t1.id from (select t2.account_id, max(t2.id) as id from "
|
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 = true "
|
+ "(select id, max(entry_date) as entry_date, account_id from acc_gl_journal_entry where is_running_balance_calculated = true "
|
||||||
+ "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 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)";
|
+ "group by t2.account_id desc) t1)";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
final Object[] parameterArray = new Object[3];
|
final Object[] parameterArray = new Object[3];
|
||||||
int arrayPos = 0;
|
int arrayPos = 0;
|
||||||
boolean filtersPresent = false;
|
boolean filtersPresent = false;
|
||||||
@@ -151,7 +147,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(searchParam)) {
|
if (StringUtils.isNotBlank(searchParam)) {
|
||||||
if (firstWhereConditionAdded) {
|
if (firstWhereConditionAdded) {
|
||||||
sql += " and ";
|
sql += SQL_AND;
|
||||||
}
|
}
|
||||||
sql += " ( name like %?% or gl_code like %?% )";
|
sql += " ( name like %?% or gl_code like %?% )";
|
||||||
parameterArray[arrayPos] = searchParam;
|
parameterArray[arrayPos] = searchParam;
|
||||||
@@ -162,7 +158,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
}
|
}
|
||||||
if (usage != null) {
|
if (usage != null) {
|
||||||
if (firstWhereConditionAdded) {
|
if (firstWhereConditionAdded) {
|
||||||
sql += " and ";
|
sql += SQL_AND;
|
||||||
}
|
}
|
||||||
if (GLAccountUsage.HEADER.getValue().equals(usage)) {
|
if (GLAccountUsage.HEADER.getValue().equals(usage)) {
|
||||||
sql += " account_usage = 2 ";
|
sql += " account_usage = 2 ";
|
||||||
@@ -173,7 +169,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
}
|
}
|
||||||
if (manualTransactionsAllowed != null) {
|
if (manualTransactionsAllowed != null) {
|
||||||
if (firstWhereConditionAdded) {
|
if (firstWhereConditionAdded) {
|
||||||
sql += " and ";
|
sql += SQL_AND;
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += " manual_journal_entries_allowed = " + manualTransactionsAllowed;
|
sql += " manual_journal_entries_allowed = " + manualTransactionsAllowed;
|
||||||
@@ -181,37 +177,32 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
}
|
}
|
||||||
if (disabled != null) {
|
if (disabled != null) {
|
||||||
if (firstWhereConditionAdded) {
|
if (firstWhereConditionAdded) {
|
||||||
sql += " and ";
|
sql += SQL_AND;
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += " disabled = " + disabled;
|
sql += " disabled = " + disabled;
|
||||||
firstWhereConditionAdded = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += " ORDER BY gl_code ASC";
|
sql += " ORDER BY gl_code ASC";
|
||||||
|
|
||||||
final Object[] finalObjectArray = Arrays.copyOf(parameterArray, arrayPos);
|
final Object[] finalObjectArray = Arrays.copyOf(parameterArray, arrayPos);
|
||||||
return this.jdbcTemplate.query(sql, rm, finalObjectArray); // NOSONAR
|
return this.jdbcTemplate.query(sql, rm, (Object[]) finalObjectArray);// NOSONAR
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GLAccountData retrieveGLAccountById(final long glAccountId, JournalEntryAssociationParametersData associationParametersData) {
|
public GLAccountData retrieveGLAccountById(final long glAccountId, JournalEntryAssociationParametersData associationParametersData) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
|
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
|
||||||
final StringBuilder sql = new StringBuilder();
|
final StringBuilder sql = new StringBuilder();
|
||||||
sql.append("select ").append(rm.schema());
|
sql.append("select ").append(rm.schema());
|
||||||
|
sql.append(" where gl.id = ?");
|
||||||
if (associationParametersData.isRunningBalanceRequired()) {
|
if (associationParametersData.isRunningBalanceRequired()) {
|
||||||
sql.append(" and gl_j.is_running_balance_calculated = true ");
|
sql.append(" and gl_j.is_running_balance_calculated = true ")
|
||||||
|
.append(" ORDER BY gl_j.entry_date DESC,gl_j.id DESC LIMIT 1");
|
||||||
}
|
}
|
||||||
sql.append("where gl.id = ?");
|
|
||||||
if (associationParametersData.isRunningBalanceRequired()) {
|
|
||||||
sql.append(" ORDER BY gl_j.entry_date DESC,gl_j.id DESC LIMIT 1");
|
|
||||||
}
|
|
||||||
final GLAccountData glAccountData = this.jdbcTemplate.queryForObject(sql.toString(), rm, new Object[] { glAccountId });
|
|
||||||
|
|
||||||
return glAccountData;
|
return this.jdbcTemplate.queryForObject(sql.toString(), rm, new Object[] { glAccountId });
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
throw new GLAccountNotFoundException(glAccountId, e);
|
throw new GLAccountNotFoundException(glAccountId, e);
|
||||||
}
|
}
|
||||||
@@ -261,15 +252,13 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
@Override
|
@Override
|
||||||
public List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType) {
|
public List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType) {
|
||||||
final GLAccountDataLookUpMapper mapper = new GLAccountDataLookUpMapper();
|
final GLAccountDataLookUpMapper mapper = new GLAccountDataLookUpMapper();
|
||||||
final String sql = "Select " + mapper.schema() + " where rule.id=? and tags.acc_type_enum=?";
|
final String sql = "Select " + GLAccountDataLookUpMapper.LOOKUP_SCHEMA + " where rule.id=? and tags.acc_type_enum=?";
|
||||||
return this.jdbcTemplate.query(sql, mapper, new Object[] { ruleId, transactionType }); // NOSONAR
|
return this.jdbcTemplate.query(sql, mapper, (Object[]) new Object[] { ruleId, transactionType });// NOSONAR
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class GLAccountDataLookUpMapper implements RowMapper<GLAccountDataForLookup> {
|
private static final class GLAccountDataLookUpMapper implements RowMapper<GLAccountDataForLookup> {
|
||||||
|
|
||||||
public String schema() {
|
private static final String LOOKUP_SCHEMA = " gl.id as id, gl.name as name, gl.gl_code as glCode from acc_accounting_rule rule join acc_rule_tags tags on tags.acc_rule_id = rule.id join acc_gl_account gl on gl.tag_id=tags.tag_id";
|
||||||
return " gl.id as id, gl.name as name, gl.gl_code as glCode from acc_accounting_rule rule join acc_rule_tags tags on tags.acc_rule_id = rule.id join acc_gl_account gl on gl.tag_id=tags.tag_id";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GLAccountDataForLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
public GLAccountDataForLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|||||||
+1
-1
@@ -194,7 +194,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
|||||||
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
||||||
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
|
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
|
||||||
if (journalEntriesForAccountExist) {
|
if (journalEntriesForAccountExist) {
|
||||||
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSANCTIONS_LOGGED, glAccountId);
|
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSACTIONS_LOGGED, glAccountId);
|
||||||
}
|
}
|
||||||
this.glAccountRepository.delete(glAccount);
|
this.glAccountRepository.delete(glAccount);
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -27,6 +27,7 @@ import jakarta.persistence.Table;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||||
@@ -54,6 +55,7 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
@Column(name = "currency_code", length = 3, nullable = false)
|
@Column(name = "currency_code", length = 3, nullable = false)
|
||||||
private String currencyCode;
|
private String currencyCode;
|
||||||
|
|
||||||
|
@Setter
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "reversal_id")
|
@JoinColumn(name = "reversal_id")
|
||||||
private JournalEntry reversalJournalEntry;
|
private JournalEntry reversalJournalEntry;
|
||||||
@@ -73,6 +75,7 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
@Column(name = "share_transaction_id")
|
@Column(name = "share_transaction_id")
|
||||||
private Long shareTransactionId;
|
private Long shareTransactionId;
|
||||||
|
|
||||||
|
@Setter
|
||||||
@Column(name = "reversed", nullable = false)
|
@Column(name = "reversed", nullable = false)
|
||||||
private boolean reversed = false;
|
private boolean reversed = false;
|
||||||
|
|
||||||
@@ -147,11 +150,8 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
return JournalEntryType.DEBIT.getValue().equals(this.type);
|
return JournalEntryType.DEBIT.getValue().equals(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReversalJournalEntry(final JournalEntry reversalJournalEntry) {
|
public boolean isCreditEntry() {
|
||||||
this.reversalJournalEntry = reversalJournalEntry;
|
return JournalEntryType.CREDIT.getValue().equals(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReversed(final boolean reversed) {
|
|
||||||
this.reversed = reversed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -29,6 +29,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||||
|
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
|
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
|
||||||
@@ -63,10 +64,14 @@ public class ProductToGLAccountMapping extends AbstractPersistableCustom<Long> {
|
|||||||
@Column(name = "financial_account_type", nullable = true)
|
@Column(name = "financial_account_type", nullable = true)
|
||||||
private int financialAccountType;
|
private int financialAccountType;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "charge_off_reason_id", nullable = true)
|
||||||
|
private CodeValue chargeOffReason;
|
||||||
|
|
||||||
public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType,
|
public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType,
|
||||||
final int financialAccountType) {
|
final int financialAccountType, final CodeValue chargeOffReason) {
|
||||||
|
|
||||||
return new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId).setProductType(productType)
|
return new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId).setProductType(productType)
|
||||||
.setFinancialAccountType(financialAccountType);
|
.setFinancialAccountType(financialAccountType).setChargeOffReason(chargeOffReason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-1
@@ -35,7 +35,7 @@ public interface ProductToGLAccountMappingRepository
|
|||||||
@Param("productType") int productType, @Param("financialAccountType") int financialAccountType,
|
@Param("productType") int productType, @Param("financialAccountType") int financialAccountType,
|
||||||
@Param("chargeId") Long ChargeId);
|
@Param("chargeId") Long ChargeId);
|
||||||
|
|
||||||
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=:financialAccountType and mapping.paymentType is NULL and mapping.charge is NULL")
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=:financialAccountType and mapping.paymentType is NULL and mapping.charge is NULL and mapping.chargeOffReason is NULL")
|
||||||
ProductToGLAccountMapping findCoreProductToFinAccountMapping(@Param("productId") Long productId, @Param("productType") int productType,
|
ProductToGLAccountMapping findCoreProductToFinAccountMapping(@Param("productId") Long productId, @Param("productType") int productType,
|
||||||
@Param("financialAccountType") int financialAccountType);
|
@Param("financialAccountType") int financialAccountType);
|
||||||
|
|
||||||
@@ -61,4 +61,25 @@ public interface ProductToGLAccountMappingRepository
|
|||||||
@Param("productType") int productType);
|
@Param("productType") int productType);
|
||||||
|
|
||||||
List<ProductToGLAccountMapping> findByProductIdAndProductType(Long productId, int productType);
|
List<ProductToGLAccountMapping> findByProductIdAndProductType(Long productId, int productType);
|
||||||
|
|
||||||
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.chargeOffReason is not NULL")
|
||||||
|
List<ProductToGLAccountMapping> findAllChargeOffReasonsMappings(@Param("productId") Long productId,
|
||||||
|
@Param("productType") int productType);
|
||||||
|
|
||||||
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.chargeOffReason.id =:chargeOffReasonId AND mapping.productId =:productId AND mapping.productType =:productType")
|
||||||
|
ProductToGLAccountMapping findChargeOffReasonMapping(@Param("productId") Long productId, @Param("productType") Integer productType,
|
||||||
|
@Param("chargeOffReasonId") Long chargeOffReasonId);
|
||||||
|
|
||||||
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge IS NULL AND mapping.paymentType IS NULL AND mapping.chargeOffReason IS NULL")
|
||||||
|
List<ProductToGLAccountMapping> findAllRegularMappings(@Param("productId") Long productId, @Param("productType") Integer productType);
|
||||||
|
|
||||||
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.paymentType is not NULL")
|
||||||
|
List<ProductToGLAccountMapping> findAllPaymentTypeMappings(@Param("productId") Long productId,
|
||||||
|
@Param("productType") Integer productType);
|
||||||
|
|
||||||
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge.penalty = TRUE")
|
||||||
|
List<ProductToGLAccountMapping> findAllPenaltyMappings(@Param("productId") Long productId, @Param("productType") Integer productType);
|
||||||
|
|
||||||
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge.penalty = FALSE")
|
||||||
|
List<ProductToGLAccountMapping> findAllFeeMappings(@Param("productId") Long productId, @Param("productType") Integer productType);
|
||||||
}
|
}
|
||||||
|
|||||||
+141
@@ -27,6 +27,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
|
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
|
||||||
@@ -39,7 +40,11 @@ import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGL
|
|||||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingInvalidException;
|
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingInvalidException;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||||
|
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||||
|
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepository;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.apache.fineract.portfolio.PortfolioProductType;
|
import org.apache.fineract.portfolio.PortfolioProductType;
|
||||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||||
@@ -53,6 +58,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class ProductToGLAccountMappingHelper {
|
public class ProductToGLAccountMappingHelper {
|
||||||
|
|
||||||
protected static final List<GLAccountType> ASSET_LIABILITY_TYPES = List.of(GLAccountType.ASSET, GLAccountType.LIABILITY);
|
protected static final List<GLAccountType> ASSET_LIABILITY_TYPES = List.of(GLAccountType.ASSET, GLAccountType.LIABILITY);
|
||||||
|
private static final Integer GL_ACCOUNT_EXPENSE_TYPE = 5;
|
||||||
|
|
||||||
protected final GLAccountRepository accountRepository;
|
protected final GLAccountRepository accountRepository;
|
||||||
protected final ProductToGLAccountMappingRepository accountMappingRepository;
|
protected final ProductToGLAccountMappingRepository accountMappingRepository;
|
||||||
@@ -60,6 +66,7 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
private final ChargeRepositoryWrapper chargeRepositoryWrapper;
|
private final ChargeRepositoryWrapper chargeRepositoryWrapper;
|
||||||
protected final GLAccountRepositoryWrapper accountRepositoryWrapper;
|
protected final GLAccountRepositoryWrapper accountRepositoryWrapper;
|
||||||
private final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper;
|
private final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper;
|
||||||
|
private final CodeValueRepository codeValueRepository;
|
||||||
|
|
||||||
public void saveProductToAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
public void saveProductToAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
final int placeHolderTypeId, final GLAccountType expectedAccountType, final PortfolioProductType portfolioProductType) {
|
final int placeHolderTypeId, final GLAccountType expectedAccountType, final PortfolioProductType portfolioProductType) {
|
||||||
@@ -194,6 +201,27 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveChargeOffReasonToGLAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||||
|
|
||||||
|
final String arrayName = LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue();
|
||||||
|
final JsonArray chargeOffReasonToExpenseAccountMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(arrayName, element);
|
||||||
|
|
||||||
|
if (chargeOffReasonToExpenseAccountMappingArray != null) {
|
||||||
|
if (changes != null) {
|
||||||
|
changes.put(arrayName, command.jsonFragment(arrayName));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < chargeOffReasonToExpenseAccountMappingArray.size(); i++) {
|
||||||
|
final JsonObject jsonObject = chargeOffReasonToExpenseAccountMappingArray.get(i).getAsJsonObject();
|
||||||
|
final Long reasonId = jsonObject.get(LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue()).getAsLong();
|
||||||
|
final Long expenseAccountId = jsonObject.get(LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue()).getAsLong();
|
||||||
|
|
||||||
|
saveChargeOffReasonToExpenseMapping(productId, reasonId, expenseAccountId, portfolioProductType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param command
|
* @param command
|
||||||
* @param element
|
* @param element
|
||||||
@@ -356,6 +384,65 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateChargeOffReasonToGLAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||||
|
|
||||||
|
final List<ProductToGLAccountMapping> existingChargeOffReasonToGLAccountMappings = this.accountMappingRepository
|
||||||
|
.findAllChargeOffReasonsMappings(productId, portfolioProductType.getValue());
|
||||||
|
final JsonArray chargeOffReasonToGLAccountMappingArray = this.fromApiJsonHelper
|
||||||
|
.extractJsonArrayNamed(LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(), element);
|
||||||
|
|
||||||
|
final Map<Long, Long> inputChargeOffReasonToGLAccountMap = new HashMap<>();
|
||||||
|
|
||||||
|
final Set<Long> existingChargeOffReasons = new HashSet<>();
|
||||||
|
if (chargeOffReasonToGLAccountMappingArray != null) {
|
||||||
|
if (changes != null) {
|
||||||
|
changes.put(LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(),
|
||||||
|
command.jsonFragment(LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < chargeOffReasonToGLAccountMappingArray.size(); i++) {
|
||||||
|
final JsonObject jsonObject = chargeOffReasonToGLAccountMappingArray.get(i).getAsJsonObject();
|
||||||
|
final Long expenseGlAccountId = jsonObject.get(LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue()).getAsLong();
|
||||||
|
final Long chargeOffReasonCodeValueId = jsonObject
|
||||||
|
.get(LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue()).getAsLong();
|
||||||
|
inputChargeOffReasonToGLAccountMap.put(chargeOffReasonCodeValueId, expenseGlAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If input map is empty, delete all existing mappings
|
||||||
|
if (inputChargeOffReasonToGLAccountMap.isEmpty()) {
|
||||||
|
this.accountMappingRepository.deleteAllInBatch(existingChargeOffReasonToGLAccountMappings);
|
||||||
|
} else {
|
||||||
|
for (final ProductToGLAccountMapping existingChargeOffReasonToGLAccountMapping : existingChargeOffReasonToGLAccountMappings) {
|
||||||
|
final Long currentChargeOffReasonId = existingChargeOffReasonToGLAccountMapping.getChargeOffReason().getId();
|
||||||
|
if (currentChargeOffReasonId != null) {
|
||||||
|
existingChargeOffReasons.add(currentChargeOffReasonId);
|
||||||
|
// update existing mappings (if required)
|
||||||
|
if (inputChargeOffReasonToGLAccountMap.containsKey(currentChargeOffReasonId)) {
|
||||||
|
final Long newGLAccountId = inputChargeOffReasonToGLAccountMap.get(currentChargeOffReasonId);
|
||||||
|
if (!newGLAccountId.equals(existingChargeOffReasonToGLAccountMapping.getGlAccount().getId())) {
|
||||||
|
final Optional<GLAccount> glAccount = accountRepository.findById(newGLAccountId);
|
||||||
|
if (glAccount.isPresent()) {
|
||||||
|
existingChargeOffReasonToGLAccountMapping.setGlAccount(glAccount.get());
|
||||||
|
this.accountMappingRepository.saveAndFlush(existingChargeOffReasonToGLAccountMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // deleted payment type
|
||||||
|
else {
|
||||||
|
this.accountMappingRepository.delete(existingChargeOffReasonToGLAccountMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only the newly added
|
||||||
|
for (Map.Entry<Long, Long> entry : inputChargeOffReasonToGLAccountMap.entrySet().stream()
|
||||||
|
.filter(e -> !existingChargeOffReasons.contains(e.getKey())).toList()) {
|
||||||
|
saveChargeOffReasonToExpenseMapping(productId, entry.getKey(), entry.getValue(), portfolioProductType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param productId
|
* @param productId
|
||||||
*
|
*
|
||||||
@@ -402,6 +489,26 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
this.accountMappingRepository.saveAndFlush(accountMapping);
|
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveChargeOffReasonToExpenseMapping(final Long productId, final Long reasonId, final Long expenseAccountId,
|
||||||
|
final PortfolioProductType portfolioProductType) {
|
||||||
|
|
||||||
|
final Optional<GLAccount> glAccount = accountRepository.findById(expenseAccountId);
|
||||||
|
|
||||||
|
final boolean reasonMappingExists = this.accountMappingRepository
|
||||||
|
.findAllChargeOffReasonsMappings(productId, portfolioProductType.getValue()).stream()
|
||||||
|
.anyMatch(mapping -> mapping.getChargeOffReason().getId().equals(reasonId));
|
||||||
|
|
||||||
|
final Optional<CodeValue> codeValueOptional = codeValueRepository.findById(reasonId);
|
||||||
|
|
||||||
|
if (glAccount.isPresent() && !reasonMappingExists && codeValueOptional.isPresent()) {
|
||||||
|
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount.get())
|
||||||
|
.setProductId(productId).setProductType(portfolioProductType.getValue())
|
||||||
|
.setFinancialAccountType(CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue()).setChargeOffReason(codeValueOptional.get());
|
||||||
|
|
||||||
|
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<GLAccountType> getAllowedAccountTypesForFeeMapping() {
|
private List<GLAccountType> getAllowedAccountTypesForFeeMapping() {
|
||||||
List<GLAccountType> allowedAccountTypes = new ArrayList<>();
|
List<GLAccountType> allowedAccountTypes = new ArrayList<>();
|
||||||
allowedAccountTypes.add(GLAccountType.INCOME);
|
allowedAccountTypes.add(GLAccountType.INCOME);
|
||||||
@@ -455,4 +562,38 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
this.accountMappingRepository.deleteAllInBatch(productToGLAccountMappings);
|
this.accountMappingRepository.deleteAllInBatch(productToGLAccountMappings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateChargeOffMappingsInDatabase(final List<JsonObject> mappings) {
|
||||||
|
final List<ApiParameterError> validationErrors = new ArrayList<>();
|
||||||
|
|
||||||
|
for (JsonObject jsonObject : mappings) {
|
||||||
|
final Long expenseGlAccountId = this.fromApiJsonHelper
|
||||||
|
.extractLongNamed(LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue(), jsonObject);
|
||||||
|
final Long chargeOffReasonCodeValueId = this.fromApiJsonHelper
|
||||||
|
.extractLongNamed(LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue(), jsonObject);
|
||||||
|
|
||||||
|
// Validation: chargeOffReasonCodeValueId must exist in the database
|
||||||
|
CodeValue codeValue = this.codeValueRepository.findByCodeNameAndId("ChargeOffReasons", chargeOffReasonCodeValueId);
|
||||||
|
if (codeValue == null) {
|
||||||
|
validationErrors.add(ApiParameterError.parameterError("validation.msg.chargeoffreason.invalid",
|
||||||
|
"Charge-off reason with ID " + chargeOffReasonCodeValueId + " does not exist",
|
||||||
|
LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validation: expenseGLAccountId must exist as a valid Expense GL account
|
||||||
|
final Optional<GLAccount> glAccount = accountRepository.findById(expenseGlAccountId);
|
||||||
|
|
||||||
|
if (glAccount.isEmpty() || !glAccount.get().getType().equals(GL_ACCOUNT_EXPENSE_TYPE)) {
|
||||||
|
validationErrors.add(ApiParameterError.parameterError("validation.msg.glaccount.not.found",
|
||||||
|
"GL Account with ID " + expenseGlAccountId + " does not exist or is not an Expense GL account",
|
||||||
|
LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue()));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw all collected validation errors, if any
|
||||||
|
if (!validationErrors.isEmpty()) {
|
||||||
|
throw new PlatformApiDataValidationException(validationErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -20,6 +20,7 @@ package org.apache.fineract.accounting.producttoaccountmapping.service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeOffReasonToGLAccountMapper;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
|
|
||||||
@@ -47,4 +48,5 @@ public interface ProductToGLAccountMappingReadPlatformService {
|
|||||||
|
|
||||||
List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(Long productId);
|
List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(Long productId);
|
||||||
|
|
||||||
|
List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappingsForLoanProduct(Long loanProductId);
|
||||||
}
|
}
|
||||||
|
|||||||
+85
-144
@@ -18,8 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.producttoaccountmapping.service;
|
package org.apache.fineract.accounting.producttoaccountmapping.service;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -37,14 +35,16 @@ import org.apache.fineract.accounting.common.AccountingConstants.SharesProductAc
|
|||||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||||
import org.apache.fineract.accounting.common.AccountingValidations;
|
import org.apache.fineract.accounting.common.AccountingValidations;
|
||||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
||||||
|
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeOffReasonToGLAccountMapper;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||||
|
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
|
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||||
import org.apache.fineract.portfolio.PortfolioProductType;
|
import org.apache.fineract.portfolio.PortfolioProductType;
|
||||||
import org.apache.fineract.portfolio.charge.data.ChargeData;
|
import org.apache.fineract.portfolio.charge.data.ChargeData;
|
||||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -54,73 +54,24 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
private static final class ProductToGLAccountMappingMapper implements RowMapper<Map<String, Object>> {
|
private final ProductToGLAccountMappingRepository productToGLAccountMappingRepository;
|
||||||
|
|
||||||
public String schema() {
|
|
||||||
return " mapping.id as id, mapping.gl_account_id as glAccountId,glaccount.name as name,glaccount.gl_code as code,"
|
|
||||||
+ " mapping.product_id as productId, mapping.product_type as productType,mapping.financial_account_type as financialAccountType, "
|
|
||||||
+ " mapping.payment_type as paymentTypeId,pt.value as paymentTypeValue, mapping.charge_id as chargeId, charge.is_penalty as penalty, "
|
|
||||||
+ " charge.name as chargeName "
|
|
||||||
+ " from acc_product_mapping mapping left join m_charge charge on mapping.charge_id=charge.id "
|
|
||||||
+ " left join acc_gl_account as glaccount on mapping.gl_account_id = glaccount.id"
|
|
||||||
+ " left join m_payment_type pt on mapping.payment_type=pt.id" + " where mapping.product_type= ? ";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
|
||||||
|
|
||||||
final Long id = rs.getLong("id");
|
|
||||||
final Long glAccountId = rs.getLong("glAccountId");
|
|
||||||
final Long productId = rs.getLong("productId");
|
|
||||||
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentTypeId");
|
|
||||||
final Long chargeId = rs.getLong("chargeId");
|
|
||||||
final Integer productType = rs.getInt("productType");
|
|
||||||
final String paymentTypeValue = rs.getString("paymentTypeValue");
|
|
||||||
final Integer financialAccountType = rs.getInt("financialAccountType");
|
|
||||||
final String glAccountName = rs.getString("name");
|
|
||||||
final String glCode = rs.getString("code");
|
|
||||||
final String chargeName = rs.getString("chargeName");
|
|
||||||
final Boolean penalty = rs.getBoolean("penalty");
|
|
||||||
|
|
||||||
final Map<String, Object> loanProductToGLAccountMap = new LinkedHashMap<>(5);
|
|
||||||
loanProductToGLAccountMap.put("id", id);
|
|
||||||
loanProductToGLAccountMap.put("glAccountId", glAccountId);
|
|
||||||
loanProductToGLAccountMap.put("productId", productId);
|
|
||||||
loanProductToGLAccountMap.put("productType", productType);
|
|
||||||
loanProductToGLAccountMap.put("financialAccountType", financialAccountType);
|
|
||||||
loanProductToGLAccountMap.put("paymentTypeId", paymentTypeId);
|
|
||||||
loanProductToGLAccountMap.put("paymentTypeValue", paymentTypeValue);
|
|
||||||
loanProductToGLAccountMap.put("chargeId", chargeId);
|
|
||||||
loanProductToGLAccountMap.put("chargeName", chargeName);
|
|
||||||
loanProductToGLAccountMap.put("penalty", penalty);
|
|
||||||
loanProductToGLAccountMap.put("glAccountName", glAccountName);
|
|
||||||
loanProductToGLAccountMap.put("glCode", glCode);
|
|
||||||
return loanProductToGLAccountMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> fetchAccountMappingDetailsForLoanProduct(final Long loanProductId, final Integer accountingType) {
|
public Map<String, Object> fetchAccountMappingDetailsForLoanProduct(final Long loanProductId, final Integer accountingType) {
|
||||||
|
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||||
|
|
||||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllRegularMappings(loanProductId,
|
||||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null";
|
PortfolioProductType.LOAN.getValue());
|
||||||
|
|
||||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
|
||||||
new Object[] { PortfolioProductType.LOAN.getValue(), loanProductId });
|
|
||||||
|
|
||||||
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
||||||
|
|
||||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
|
|
||||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
final CashAccountsForLoan glAccountForLoan = CashAccountsForLoan.fromInt(mapping.getFinancialAccountType());
|
||||||
final CashAccountsForLoan glAccountForLoan = CashAccountsForLoan.fromInt(financialAccountType);
|
|
||||||
|
|
||||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
|
|
||||||
if (glAccountForLoan.equals(CashAccountsForLoan.FUND_SOURCE)) {
|
if (glAccountForLoan.equals(CashAccountsForLoan.FUND_SOURCE)) {
|
||||||
accountMappingDetails.put(LoanProductAccountingDataParams.FUND_SOURCE.getValue(), gLAccountData);
|
accountMappingDetails.put(LoanProductAccountingDataParams.FUND_SOURCE.getValue(), gLAccountData);
|
||||||
@@ -166,14 +117,11 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
} else if (AccountingValidations.isAccrualBasedAccounting(accountingType)
|
} else if (AccountingValidations.isAccrualBasedAccounting(accountingType)
|
||||||
|| AccountingValidations.isUpfrontAccrualAccounting(accountingType)) {
|
|| AccountingValidations.isUpfrontAccrualAccounting(accountingType)) {
|
||||||
|
|
||||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
for (ProductToGLAccountMapping mapping : mappings) {
|
||||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
final AccrualAccountsForLoan glAccountForLoan = AccrualAccountsForLoan.fromInt(mapping.getFinancialAccountType());
|
||||||
final AccrualAccountsForLoan glAccountForLoan = AccrualAccountsForLoan.fromInt(financialAccountType);
|
|
||||||
|
|
||||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
|
|
||||||
if (glAccountForLoan.equals(AccrualAccountsForLoan.FUND_SOURCE)) {
|
if (glAccountForLoan.equals(AccrualAccountsForLoan.FUND_SOURCE)) {
|
||||||
accountMappingDetails.put(LoanProductAccountingDataParams.FUND_SOURCE.getValue(), gLAccountData);
|
accountMappingDetails.put(LoanProductAccountingDataParams.FUND_SOURCE.getValue(), gLAccountData);
|
||||||
@@ -229,18 +177,16 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(final Long savingsProductId, final Integer accountingType) {
|
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(final Long savingsProductId, final Integer accountingType) {
|
||||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
|
||||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null ";
|
|
||||||
|
|
||||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllRegularMappings(savingsProductId,
|
||||||
new Object[] { PortfolioProductType.SAVING.getValue(), savingsProductId });
|
PortfolioProductType.SAVING.getValue());
|
||||||
|
|
||||||
Map<String, Object> accountMappingDetails = null;
|
Map<String, Object> accountMappingDetails = null;
|
||||||
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
||||||
accountMappingDetails = setCashSavingsProductToGLAccountMaps(listOfProductToGLAccountMaps);
|
accountMappingDetails = setCashSavingsProductToGLAccountMaps(mappings);
|
||||||
|
|
||||||
} else if (AccountingValidations.isAccrualPeriodicBasedAccounting(accountingType)) {
|
} else if (AccountingValidations.isAccrualPeriodicBasedAccounting(accountingType)) {
|
||||||
accountMappingDetails = setAccrualPeriodicSavingsProductToGLAccountMaps(listOfProductToGLAccountMaps);
|
accountMappingDetails = setAccrualPeriodicSavingsProductToGLAccountMaps(mappings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,25 +209,15 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
*/
|
*/
|
||||||
private List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappings(final PortfolioProductType portfolioProductType,
|
private List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappings(final PortfolioProductType portfolioProductType,
|
||||||
final Long loanProductId) {
|
final Long loanProductId) {
|
||||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllPaymentTypeMappings(loanProductId,
|
||||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is not null";
|
portfolioProductType.getValue());
|
||||||
|
|
||||||
final List<Map<String, Object>> paymentTypeToFundSourceMappingsList = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
|
||||||
new Object[] { portfolioProductType.getValue(), loanProductId });
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
|
final PaymentTypeData paymentTypeData = PaymentTypeData.instance(mapping.getPaymentType().getId(),
|
||||||
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = null;
|
mapping.getPaymentType().getName());
|
||||||
for (final Map<String, Object> productToGLAccountMap : paymentTypeToFundSourceMappingsList) {
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
if (paymentTypeToGLAccountMappers == null) {
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
paymentTypeToGLAccountMappers = new ArrayList<>();
|
|
||||||
}
|
|
||||||
final Long paymentTypeId = (Long) productToGLAccountMap.get("paymentTypeId");
|
|
||||||
final String paymentTypeValue = (String) productToGLAccountMap.get("paymentTypeValue");
|
|
||||||
final PaymentTypeData paymentTypeData = PaymentTypeData.instance(paymentTypeId, paymentTypeValue);
|
|
||||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
|
||||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
|
||||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
|
||||||
|
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
|
|
||||||
final PaymentTypeToGLAccountMapper paymentTypeToGLAccountMapper = new PaymentTypeToGLAccountMapper()
|
final PaymentTypeToGLAccountMapper paymentTypeToGLAccountMapper = new PaymentTypeToGLAccountMapper()
|
||||||
.setPaymentType(paymentTypeData).setFundSourceAccount(gLAccountData);
|
.setPaymentType(paymentTypeData).setFundSourceAccount(gLAccountData);
|
||||||
@@ -312,29 +248,16 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final PortfolioProductType portfolioProductType,
|
private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final PortfolioProductType portfolioProductType,
|
||||||
final Long loanProductId, final boolean penalty) {
|
final Long loanProductId, final boolean penalty) {
|
||||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
final List<ProductToGLAccountMapping> mappings = penalty
|
||||||
String sql = "select " + rm.schema() + " and product_id = ? and mapping.charge_id is not null and charge.is_penalty=";
|
? productToGLAccountMappingRepository.findAllPenaltyMappings(loanProductId, portfolioProductType.getValue())
|
||||||
if (penalty) {
|
: productToGLAccountMappingRepository.findAllFeeMappings(loanProductId, portfolioProductType.getValue());
|
||||||
sql = sql + " true";
|
|
||||||
} else {
|
|
||||||
sql = sql + " false";
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Map<String, Object>> chargeToFundSourceMappingsList = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
List<ChargeToGLAccountMapper> chargeToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
|
||||||
new Object[] { portfolioProductType.getValue(), loanProductId });
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
List<ChargeToGLAccountMapper> chargeToGLAccountMappers = null;
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
for (final Map<String, Object> chargeToIncomeAccountMap : chargeToFundSourceMappingsList) {
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
if (chargeToGLAccountMappers == null) {
|
final ChargeData chargeData = ChargeData.builder().id(mapping.getCharge().getId()).name(mapping.getCharge().getName())
|
||||||
chargeToGLAccountMappers = new ArrayList<>();
|
.penalty(mapping.getCharge().isPenalty()).build();
|
||||||
}
|
|
||||||
final Long glAccountId = (Long) chargeToIncomeAccountMap.get("glAccountId");
|
|
||||||
final String glAccountName = (String) chargeToIncomeAccountMap.get("glAccountName");
|
|
||||||
final String glCode = (String) chargeToIncomeAccountMap.get("glCode");
|
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
final Long chargeId = (Long) chargeToIncomeAccountMap.get("chargeId");
|
|
||||||
final String chargeName = (String) chargeToIncomeAccountMap.get("chargeName");
|
|
||||||
final Boolean penalty1 = (Boolean) chargeToIncomeAccountMap.get("penalty");
|
|
||||||
final ChargeData chargeData = ChargeData.builder().id(chargeId).name(chargeName).penalty(penalty1).build();
|
|
||||||
final ChargeToGLAccountMapper chargeToGLAccountMapper = new ChargeToGLAccountMapper().setCharge(chargeData)
|
final ChargeToGLAccountMapper chargeToGLAccountMapper = new ChargeToGLAccountMapper().setCharge(chargeData)
|
||||||
.setIncomeAccount(gLAccountData);
|
.setIncomeAccount(gLAccountData);
|
||||||
chargeToGLAccountMappers.add(chargeToGLAccountMapper);
|
chargeToGLAccountMappers.add(chargeToGLAccountMapper);
|
||||||
@@ -342,26 +265,46 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
return chargeToGLAccountMappers;
|
return chargeToGLAccountMappers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappings(final PortfolioProductType portfolioProductType,
|
||||||
|
final Long loanProductId) {
|
||||||
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllChargeOffReasonsMappings(loanProductId,
|
||||||
|
portfolioProductType.getValue());
|
||||||
|
List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
|
||||||
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
|
final Long glAccountId = mapping.getGlAccount().getId();
|
||||||
|
final String glAccountName = mapping.getGlAccount().getName();
|
||||||
|
final String glCode = mapping.getGlAccount().getGlCode();
|
||||||
|
final GLAccountData chargeOffExpenseAccount = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||||
|
final Long chargeOffReasonId = mapping.getChargeOffReason().getId();
|
||||||
|
final String codeValue = mapping.getChargeOffReason().getLabel();
|
||||||
|
final String codeDescription = mapping.getChargeOffReason().getDescription();
|
||||||
|
final Integer orderPosition = mapping.getChargeOffReason().getPosition();
|
||||||
|
final boolean isActive = mapping.getChargeOffReason().isActive();
|
||||||
|
final boolean isMandatory = mapping.getChargeOffReason().isMandatory();
|
||||||
|
final CodeValueData chargeOffReasonsCodeValue = CodeValueData.builder().id(chargeOffReasonId).name(codeValue)
|
||||||
|
.description(codeDescription).position(orderPosition).active(isActive).mandatory(isMandatory).build();
|
||||||
|
|
||||||
|
final ChargeOffReasonToGLAccountMapper chargeOffReasonToGLAccountMapper = new ChargeOffReasonToGLAccountMapper()
|
||||||
|
.setChargeOffReasonCodeValue(chargeOffReasonsCodeValue).setExpenseAccount(chargeOffExpenseAccount);
|
||||||
|
chargeOffReasonToGLAccountMappers.add(chargeOffReasonToGLAccountMapper);
|
||||||
|
}
|
||||||
|
return chargeOffReasonToGLAccountMappers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> fetchAccountMappingDetailsForShareProduct(Long productId, Integer accountingType) {
|
public Map<String, Object> fetchAccountMappingDetailsForShareProduct(Long productId, Integer accountingType) {
|
||||||
|
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||||
|
|
||||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllRegularMappings(productId,
|
||||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null ";
|
PortfolioProductType.SHARES.getValue());
|
||||||
|
|
||||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
|
||||||
new Object[] { PortfolioProductType.SHARES.getValue(), productId });
|
|
||||||
|
|
||||||
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
final CashAccountsForShares glAccountForShares = CashAccountsForShares.fromInt(mapping.getFinancialAccountType());
|
||||||
final CashAccountsForShares glAccountForShares = CashAccountsForShares.fromInt(financialAccountType);
|
|
||||||
|
|
||||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
|
|
||||||
if (glAccountForShares.equals(CashAccountsForShares.SHARES_REFERENCE)) {
|
if (glAccountForShares.equals(CashAccountsForShares.SHARES_REFERENCE)) {
|
||||||
accountMappingDetails.put(SharesProductAccountingParams.SHARES_REFERENCE.getValue(), gLAccountData);
|
accountMappingDetails.put(SharesProductAccountingParams.SHARES_REFERENCE.getValue(), gLAccountData);
|
||||||
@@ -388,20 +331,21 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
return fetchChargeToIncomeAccountMappings(PortfolioProductType.SHARES, productId, false);
|
return fetchChargeToIncomeAccountMappings(PortfolioProductType.SHARES, productId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> setAccrualPeriodicSavingsProductToGLAccountMaps(
|
@Override
|
||||||
final List<Map<String, Object>> listOfProductToGLAccountMaps) {
|
public List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappingsForLoanProduct(Long loanProductId) {
|
||||||
|
return fetchChargeOffReasonMappings(PortfolioProductType.LOAN, loanProductId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> setAccrualPeriodicSavingsProductToGLAccountMaps(final List<ProductToGLAccountMapping> mappings) {
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||||
|
|
||||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
|
|
||||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
AccrualAccountsForSavings glAccountForSavings = AccrualAccountsForSavings.fromInt(mapping.getFinancialAccountType());
|
||||||
AccrualAccountsForSavings glAccountForSavings = AccrualAccountsForSavings.fromInt(financialAccountType);
|
|
||||||
|
|
||||||
if (glAccountForSavings != null) {
|
if (glAccountForSavings != null) {
|
||||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
final GLAccountData glAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
|
||||||
final GLAccountData glAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
|
|
||||||
// Assets
|
// Assets
|
||||||
if (glAccountForSavings.equals(AccrualAccountsForSavings.SAVINGS_REFERENCE)) {
|
if (glAccountForSavings.equals(AccrualAccountsForSavings.SAVINGS_REFERENCE)) {
|
||||||
@@ -435,26 +379,23 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
accountMappingDetails.put(SavingProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), glAccountData);
|
accountMappingDetails.put(SavingProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), glAccountData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("Accounting mapping null {}", financialAccountType);
|
log.error("Accounting mapping null {}", mapping.getFinancialAccountType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return accountMappingDetails;
|
return accountMappingDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> setCashSavingsProductToGLAccountMaps(final List<Map<String, Object>> listOfProductToGLAccountMaps) {
|
private Map<String, Object> setCashSavingsProductToGLAccountMaps(final List<ProductToGLAccountMapping> mappings) {
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||||
|
|
||||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
|
|
||||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
CashAccountsForSavings glAccountForSavings = CashAccountsForSavings.fromInt(mapping.getFinancialAccountType());
|
||||||
CashAccountsForSavings glAccountForSavings = CashAccountsForSavings.fromInt(financialAccountType);
|
|
||||||
|
|
||||||
if (glAccountForSavings != null) {
|
if (glAccountForSavings != null) {
|
||||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
final GLAccountData glAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
|
||||||
final GLAccountData glAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
|
||||||
|
|
||||||
// Assets
|
// Assets
|
||||||
if (glAccountForSavings.equals(CashAccountsForSavings.SAVINGS_REFERENCE)) {
|
if (glAccountForSavings.equals(CashAccountsForSavings.SAVINGS_REFERENCE)) {
|
||||||
@@ -482,7 +423,7 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
accountMappingDetails.put(SavingProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), glAccountData);
|
accountMappingDetails.put(SavingProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), glAccountData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("Accounting mapping null {}", financialAccountType);
|
log.error("Accounting mapping null {}", mapping.getFinancialAccountType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@
|
|||||||
package org.apache.fineract.accounting.producttoaccountmapping.service;
|
package org.apache.fineract.accounting.producttoaccountmapping.service;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ public interface ProductToGLAccountMappingWritePlatformService {
|
|||||||
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command, DepositAccountType accountType);
|
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command, DepositAccountType accountType);
|
||||||
|
|
||||||
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||||
int accountingRuleTypeId);
|
AccountingRuleType accountingRuleTypeId);
|
||||||
|
|
||||||
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
|
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||||
int accountingRuleTypeId, DepositAccountType accountType);
|
int accountingRuleTypeId, DepositAccountType accountType);
|
||||||
|
|||||||
+3
-2
@@ -29,6 +29,7 @@ import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
|
|||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
|
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepository;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.apache.fineract.portfolio.PortfolioProductType;
|
import org.apache.fineract.portfolio.PortfolioProductType;
|
||||||
@@ -42,9 +43,9 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
|||||||
public SavingsProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
public SavingsProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
||||||
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
||||||
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
|
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
|
||||||
final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper) {
|
final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper, final CodeValueRepository codeValueRepository) {
|
||||||
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
|
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
|
||||||
paymentTypeRepositoryWrapper);
|
paymentTypeRepositoryWrapper, codeValueRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|||||||
+3
-2
@@ -28,6 +28,7 @@ import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
|
|||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
|
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepository;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.apache.fineract.portfolio.PortfolioProductType;
|
import org.apache.fineract.portfolio.PortfolioProductType;
|
||||||
@@ -41,9 +42,9 @@ public class ShareProductToGLAccountMappingHelper extends ProductToGLAccountMapp
|
|||||||
public ShareProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
public ShareProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
||||||
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
||||||
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
|
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
|
||||||
final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper) {
|
final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper, final CodeValueRepository codeValueRepository) {
|
||||||
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
|
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
|
||||||
paymentTypeRepositoryWrapper);
|
paymentTypeRepositoryWrapper, codeValueRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|||||||
+64
-75
@@ -18,14 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.provisioning.api;
|
package org.apache.fineract.accounting.provisioning.api;
|
||||||
|
|
||||||
|
import static org.apache.fineract.accounting.provisioning.constant.ProvisioningEntriesApiConstants.CREATE_JOURNAL_ENTRY;
|
||||||
|
import static org.apache.fineract.accounting.provisioning.constant.ProvisioningEntriesApiConstants.RECREATE_PROVISION_IN_ENTRY;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
@@ -34,24 +35,17 @@ import jakarta.ws.rs.Path;
|
|||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.QueryParam;
|
import jakarta.ws.rs.QueryParam;
|
||||||
import jakarta.ws.rs.core.Context;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.UriInfo;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.accounting.provisioning.constant.ProvisioningEntriesApiConstants;
|
|
||||||
import org.apache.fineract.accounting.provisioning.data.LoanProductProvisioningEntryData;
|
import org.apache.fineract.accounting.provisioning.data.LoanProductProvisioningEntryData;
|
||||||
import org.apache.fineract.accounting.provisioning.data.ProvisioningEntryData;
|
import org.apache.fineract.accounting.provisioning.data.ProvisioningEntryData;
|
||||||
|
import org.apache.fineract.accounting.provisioning.data.request.ProvisionEntryRequest;
|
||||||
import org.apache.fineract.accounting.provisioning.service.ProvisioningEntriesReadPlatformService;
|
import org.apache.fineract.accounting.provisioning.service.ProvisioningEntriesReadPlatformService;
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
|
||||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||||
import org.apache.fineract.infrastructure.core.service.Page;
|
import org.apache.fineract.infrastructure.core.service.Page;
|
||||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||||
@@ -60,38 +54,42 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
@Path("/v1/provisioningentries")
|
@Path("/v1/provisioningentries")
|
||||||
@Component
|
@Component
|
||||||
@Tag(name = "Provisioning Entries", description = "This defines the Provisioning Entries for all active loan products\n" + "\n"
|
@Tag(name = "Provisioning Entries", description = """
|
||||||
+ "Field Descriptions\n" + "date\n" + "Date on which day provisioning entries should be created\n" + "createjournalentries\n"
|
This defines the Provisioning Entries for all active loan products
|
||||||
+ "Boolean variable whether to add journal entries for generated provisioning entries\n")
|
|
||||||
|
Field Descriptions
|
||||||
|
date
|
||||||
|
Date on which day provisioning entries should be created
|
||||||
|
createjournalentries
|
||||||
|
Boolean variable whether to add journal entries for generated provisioning entries
|
||||||
|
""")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ProvisioningEntriesApiResource {
|
public class ProvisioningEntriesApiResource {
|
||||||
|
|
||||||
private static final Set<String> PROVISIONING_ENTRY_PARAMETERS = new HashSet<>(
|
|
||||||
Arrays.asList(ProvisioningEntriesApiConstants.PROVISIONINGENTRY_PARAM, ProvisioningEntriesApiConstants.ENTRIES_PARAM));
|
|
||||||
private static final Set<String> ALL_PROVISIONING_ENTRIES = new HashSet<>(
|
|
||||||
Arrays.asList(ProvisioningEntriesApiConstants.PROVISIONINGENTRY_PARAM));
|
|
||||||
|
|
||||||
private final PlatformSecurityContext platformSecurityContext;
|
private final PlatformSecurityContext platformSecurityContext;
|
||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
private final DefaultToApiJsonSerializer<ProvisioningEntryData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<ProvisioningEntryData> toApiJsonSerializer;
|
||||||
private final DefaultToApiJsonSerializer<Object> entriesApiJsonSerializer;
|
|
||||||
private final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService;
|
private final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService;
|
||||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Create new Provisioning Entries", description = "Creates a new Provisioning Entries\n" + "\n"
|
@Operation(summary = "Create new Provisioning Entries", description = """
|
||||||
+ "Mandatory Fields\n" + "date\n" + "dateFormat\n" + "locale\n" + "Optional Fields\n" + "createjournalentries")
|
Creates a new Provisioning Entries
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PostProvisioningEntriesRequest.class)))
|
|
||||||
@ApiResponses({
|
Mandatory Fields
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PostProvisioningEntriesResponse.class))) })
|
date
|
||||||
public String createProvisioningEntries(@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
dateFormat
|
||||||
CommandWrapper commandWrapper = null;
|
locale
|
||||||
this.platformSecurityContext.authenticatedUser();
|
Optional Fields
|
||||||
commandWrapper = new CommandWrapperBuilder().createProvisioningEntries().withJson(apiRequestBodyAsJson).build();
|
createjournalentries""")
|
||||||
final CommandProcessingResult commandProcessingResult = this.commandsSourceWritePlatformService.logCommandSource(commandWrapper);
|
@RequestBody(content = @Content(schema = @Schema(implementation = ProvisionEntryRequest.class)))
|
||||||
return this.toApiJsonSerializer.serialize(commandProcessingResult);
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PostProvisioningEntriesResponse.class)))
|
||||||
|
public CommandProcessingResult createProvisioningEntries(@Parameter(hidden = true) ProvisionEntryRequest provisionEntryRequest) {
|
||||||
|
platformSecurityContext.authenticatedUser();
|
||||||
|
CommandWrapper commandWrapper = new CommandWrapperBuilder().createProvisioningEntries()
|
||||||
|
.withJson(toApiJsonSerializer.serialize(provisionEntryRequest)).build();
|
||||||
|
return commandsSourceWritePlatformService.logCommandSource(commandWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -100,25 +98,12 @@ public class ProvisioningEntriesApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Recreates Provisioning Entry", description = "Recreates Provisioning Entry | createjournalentry.")
|
@Operation(summary = "Recreates Provisioning Entry", description = "Recreates Provisioning Entry | createjournalentry.")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PutProvisioningEntriesRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PutProvisioningEntriesRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PutProvisioningEntriesResponse.class)))
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProvisioningEntriesApiResourceSwagger.PutProvisioningEntriesResponse.class))) })
|
public CommandProcessingResult modifyProvisioningEntry(@PathParam("entryId") @Parameter(description = "entryId") final Long entryId,
|
||||||
public String modifyProvisioningEntry(@PathParam("entryId") @Parameter(description = "entryId") final Long entryId,
|
|
||||||
@QueryParam("command") @Parameter(description = "command=createjournalentry\ncommand=recreateprovisioningentry") final String commandParam,
|
@QueryParam("command") @Parameter(description = "command=createjournalentry\ncommand=recreateprovisioningentry") final String commandParam,
|
||||||
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
@Parameter(hidden = true) String provisionCommandRequest) {
|
||||||
CommandWrapper commandWrapper = null;
|
platformSecurityContext.authenticatedUser();
|
||||||
this.platformSecurityContext.authenticatedUser();
|
return getResultByCommandParam(commandParam, entryId, provisionCommandRequest);
|
||||||
if ("createjournalentry".equals(commandParam)) {
|
|
||||||
commandWrapper = new CommandWrapperBuilder().createProvisioningJournalEntries(entryId).withJson(apiRequestBodyAsJson).build();
|
|
||||||
final CommandProcessingResult commandProcessingResult = this.commandsSourceWritePlatformService
|
|
||||||
.logCommandSource(commandWrapper);
|
|
||||||
return this.toApiJsonSerializer.serialize(commandProcessingResult);
|
|
||||||
} else if ("recreateprovisioningentry".equals(commandParam)) {
|
|
||||||
commandWrapper = new CommandWrapperBuilder().reCreateProvisioningEntries(entryId).withJson(apiRequestBodyAsJson).build();
|
|
||||||
final CommandProcessingResult commandProcessingResult = this.commandsSourceWritePlatformService
|
|
||||||
.logCommandSource(commandWrapper);
|
|
||||||
return this.toApiJsonSerializer.serialize(commandProcessingResult);
|
|
||||||
}
|
|
||||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -126,45 +111,49 @@ public class ProvisioningEntriesApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Retrieves a Provisioning Entry", description = "Returns the details of a generated Provisioning Entry.")
|
@Operation(summary = "Retrieves a Provisioning Entry", description = "Returns the details of a generated Provisioning Entry.")
|
||||||
@ApiResponses({
|
public ProvisioningEntryData retrieveProvisioningEntry(@PathParam("entryId") @Parameter(description = "entryId") final Long entryId) {
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProvisioningEntryData.class))) })
|
|
||||||
public String retrieveProvisioningEntry(@PathParam("entryId") @Parameter(description = "entryId") final Long entryId,
|
|
||||||
@Context final UriInfo uriInfo) {
|
|
||||||
platformSecurityContext.authenticatedUser();
|
platformSecurityContext.authenticatedUser();
|
||||||
ProvisioningEntryData data = this.provisioningEntriesReadPlatformService.retrieveProvisioningEntryData(entryId);
|
return provisioningEntriesReadPlatformService.retrieveProvisioningEntryData(entryId);
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.toApiJsonSerializer.serialize(settings, data, PROVISIONING_ENTRY_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("entries")
|
@Path("entries")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@ApiResponses({
|
public Page<LoanProductProvisioningEntryData> retrieveProviioningEntries(@QueryParam("entryId") final Long entryId,
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoanProductProvisioningEntryData.class))) })
|
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||||
public String retrieveProviioningEntries(@QueryParam("entryId") final Long entryId, @QueryParam("offset") final Integer offset,
|
@QueryParam("officeId") final Long officeId, @QueryParam("productId") final Long productId,
|
||||||
@QueryParam("limit") final Integer limit, @QueryParam("officeId") final Long officeId,
|
@QueryParam("categoryId") final Long categoryId) {
|
||||||
@QueryParam("productId") final Long productId, @QueryParam("categoryId") final Long categoryId,
|
platformSecurityContext.authenticatedUser();
|
||||||
@Context final UriInfo uriInfo) {
|
final SearchParameters params = SearchParameters.builder().limit(limit).offset(offset).provisioningEntryId(entryId)
|
||||||
this.platformSecurityContext.authenticatedUser();
|
.officeId(officeId).productId(productId).categoryId(categoryId).build();
|
||||||
SearchParameters params = SearchParameters.builder().limit(limit).offset(offset).provisioningEntryId(entryId).officeId(officeId)
|
|
||||||
.productId(productId).categoryId(categoryId).build();
|
return provisioningEntriesReadPlatformService.retrieveProvisioningEntries(params);
|
||||||
Page<LoanProductProvisioningEntryData> entries = this.provisioningEntriesReadPlatformService.retrieveProvisioningEntries(params);
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.entriesApiJsonSerializer.serialize(settings, entries, PROVISIONING_ENTRY_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "List all Provisioning Entries")
|
@Operation(summary = "List all Provisioning Entries")
|
||||||
@ApiResponses({
|
public Page<ProvisioningEntryData> retrieveAllProvisioningEntries(
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProvisioningEntryData.class)))) })
|
@QueryParam("offset") @Parameter(description = "offset") final Integer offset,
|
||||||
public String retrieveAllProvisioningEntries(@QueryParam("offset") @Parameter(description = "offset") final Integer offset,
|
@QueryParam("limit") @Parameter(description = "limit") final Integer limit) {
|
||||||
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) {
|
|
||||||
platformSecurityContext.authenticatedUser();
|
platformSecurityContext.authenticatedUser();
|
||||||
Page<ProvisioningEntryData> data = this.provisioningEntriesReadPlatformService.retrieveAllProvisioningEntries(offset, limit);
|
return provisioningEntriesReadPlatformService.retrieveAllProvisioningEntries(offset, limit);
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
}
|
||||||
return this.entriesApiJsonSerializer.serialize(settings, data, ALL_PROVISIONING_ENTRIES);
|
|
||||||
|
private CommandProcessingResult getResultByCommandParam(String commandParam, Long entryId, String apiRequestBodyAsJson) {
|
||||||
|
final CommandWrapperBuilder commandWrapperBuilder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
|
switch (commandParam) {
|
||||||
|
case CREATE_JOURNAL_ENTRY -> {
|
||||||
|
return commandsSourceWritePlatformService
|
||||||
|
.logCommandSource(commandWrapperBuilder.createProvisioningJournalEntries(entryId).build());
|
||||||
|
}
|
||||||
|
case RECREATE_PROVISION_IN_ENTRY -> {
|
||||||
|
return commandsSourceWritePlatformService
|
||||||
|
.logCommandSource(commandWrapperBuilder.reCreateProvisioningEntries(entryId).build());
|
||||||
|
}
|
||||||
|
default -> throw new UnrecognizedQueryParamException("command", commandParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -32,4 +32,7 @@ public interface ProvisioningEntriesApiConstants {
|
|||||||
|
|
||||||
String ENTRIES_PARAM = "entries";
|
String ENTRIES_PARAM = "entries";
|
||||||
|
|
||||||
|
String CREATE_JOURNAL_ENTRY = "createjournalentry";
|
||||||
|
String RECREATE_PROVISION_IN_ENTRY = "recreateprovisioningentry";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.accounting.provisioning.data;
|
package org.apache.fineract.accounting.provisioning.data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -29,7 +31,10 @@ import lombok.experimental.Accessors;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ProvisioningEntryData {
|
public class ProvisioningEntryData implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@@ -39,9 +44,9 @@ public class ProvisioningEntryData {
|
|||||||
|
|
||||||
private String createdUser;
|
private String createdUser;
|
||||||
|
|
||||||
LocalDate createdDate;
|
private LocalDate createdDate;
|
||||||
|
|
||||||
Long modifiedById;
|
private Long modifiedById;
|
||||||
|
|
||||||
private String modifiedUser;
|
private String modifiedUser;
|
||||||
|
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.provisioning.data.request;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public record ProvisionEntryRequest(String date, Boolean createjournalentries, String locale, String dateFormat) implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
+40
-96
@@ -20,7 +20,6 @@ package org.apache.fineract.accounting.rule.api;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
@@ -39,10 +38,8 @@ import jakarta.ws.rs.core.Context;
|
|||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.UriInfo;
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -52,6 +49,7 @@ import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
|||||||
import org.apache.fineract.accounting.glaccount.service.GLAccountReadPlatformService;
|
import org.apache.fineract.accounting.glaccount.service.GLAccountReadPlatformService;
|
||||||
import org.apache.fineract.accounting.rule.data.AccountingRuleData;
|
import org.apache.fineract.accounting.rule.data.AccountingRuleData;
|
||||||
import org.apache.fineract.accounting.rule.data.AccountingTagRuleData;
|
import org.apache.fineract.accounting.rule.data.AccountingTagRuleData;
|
||||||
|
import org.apache.fineract.accounting.rule.data.request.AccountRuleRequest;
|
||||||
import org.apache.fineract.accounting.rule.service.AccountingRuleReadPlatformService;
|
import org.apache.fineract.accounting.rule.service.AccountingRuleReadPlatformService;
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
@@ -81,11 +79,6 @@ import org.springframework.stereotype.Component;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AccountingRuleApiResource {
|
public class AccountingRuleApiResource {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
|
||||||
Arrays.asList("id", "officeId", "officeName", "accountToDebitId", "accountToCreditId", "name", "description", "systemDefined",
|
|
||||||
"allowedCreditTagOptions", "allowedDebitTagOptions", "debitTags", "creditTags", "creditAccounts", "debitAccounts",
|
|
||||||
"allowMultipleCreditEntries", "allowMultipleDebitEntries", "tag"));
|
|
||||||
|
|
||||||
private static final String RESOURCE_NAME_FOR_PERMISSION = "ACCOUNTINGRULE";
|
private static final String RESOURCE_NAME_FOR_PERMISSION = "ACCOUNTINGRULE";
|
||||||
|
|
||||||
private final AccountingRuleReadPlatformService accountingRuleReadPlatformService;
|
private final AccountingRuleReadPlatformService accountingRuleReadPlatformService;
|
||||||
@@ -103,17 +96,9 @@ public class AccountingRuleApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Retrieve Accounting Rule Details Template", description = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
|
@Operation(summary = "Retrieve Accounting Rule Details Template", description = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
|
||||||
+ "\n" + "Field Defaults\n" + "Allowed Value Lists\n" + "Example Request:\n" + "\n" + "accountingrules/template")
|
+ "\n" + "Field Defaults\n" + "Allowed Value Lists\n" + "Example Request:\n" + "\n" + "accountingrules/template")
|
||||||
@ApiResponses({
|
public AccountingRuleData retrieveTemplate() {
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.GetAccountRulesTemplateResponse.class))) })
|
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
public String retrieveTemplate(@Context final UriInfo uriInfo) {
|
return handleTemplate(null);
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
|
||||||
|
|
||||||
AccountingRuleData accountingRuleData = null;
|
|
||||||
accountingRuleData = handleTemplate(accountingRuleData);
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, accountingRuleData, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -121,30 +106,16 @@ public class AccountingRuleApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Retrieve Accounting Rules", description = "Returns the list of defined accounting rules.\n" + "\n"
|
@Operation(summary = "Retrieve Accounting Rules", description = "Returns the list of defined accounting rules.\n" + "\n"
|
||||||
+ "Example Requests:\n" + "\n" + "accountingrules")
|
+ "Example Requests:\n" + "\n" + "accountingrules")
|
||||||
@ApiResponses({
|
public List<AccountingRuleData> retrieveAllAccountingRules(@Context final UriInfo uriInfo) {
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.GetAccountRulesResponse.class)))) })
|
final AppUser currentUser = context.authenticatedUser();
|
||||||
public String retrieveAllAccountingRules(@Context final UriInfo uriInfo) {
|
|
||||||
|
|
||||||
final AppUser currentUser = this.context.authenticatedUser();
|
|
||||||
currentUser.validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
currentUser.validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
|
|
||||||
final String hierarchy = currentUser.getOffice().getHierarchy();
|
final String hierarchy = currentUser.getOffice().getHierarchy();
|
||||||
final String hierarchySearchString = hierarchy + "%";
|
final String hierarchySearchString = hierarchy + "%";
|
||||||
|
|
||||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
boolean isAssociationParametersExists = false;
|
boolean isAssociationParametersExists = !associationParameters.isEmpty() && associationParameters.contains("all");
|
||||||
if (!associationParameters.isEmpty()) {
|
return accountingRuleReadPlatformService.retrieveAllAccountingRules(hierarchySearchString, isAssociationParametersExists);
|
||||||
if (associationParameters.contains("all")) {
|
|
||||||
isAssociationParametersExists = true; // If true, retrieve
|
|
||||||
// additional fields for
|
|
||||||
// journal entry form.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final List<AccountingRuleData> accountingRuleDatas = this.accountingRuleReadPlatformService
|
|
||||||
.retrieveAllAccountingRules(hierarchySearchString, isAssociationParametersExists);
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, accountingRuleDatas, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -153,21 +124,15 @@ public class AccountingRuleApiResource {
|
|||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Retrieve a Accounting rule", description = "Returns the details of a defined Accounting rule.\n" + "\n"
|
@Operation(summary = "Retrieve a Accounting rule", description = "Returns the details of a defined Accounting rule.\n" + "\n"
|
||||||
+ "Example Requests:\n" + "\n" + "accountingrules/1")
|
+ "Example Requests:\n" + "\n" + "accountingrules/1")
|
||||||
@ApiResponses({
|
public AccountingRuleData retreiveAccountingRule(
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleData.class))) })
|
|
||||||
public String retreiveAccountingRule(
|
|
||||||
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId,
|
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId,
|
||||||
@Context final UriInfo uriInfo) {
|
@Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
AccountingRuleData accountingRuleData = this.accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId);
|
final AccountingRuleData accountingRuleData = accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId);
|
||||||
if (settings.isTemplate()) {
|
return settings.isTemplate() ? handleTemplate(accountingRuleData) : accountingRuleData;
|
||||||
accountingRuleData = handleTemplate(accountingRuleData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(settings, accountingRuleData, RESPONSE_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -176,16 +141,14 @@ public class AccountingRuleApiResource {
|
|||||||
@Operation(summary = "Create/Define a Accounting rule", description = "Define a new Accounting rule.\n" + "\n" + "Mandatory Fields\n"
|
@Operation(summary = "Create/Define a Accounting rule", description = "Define a new Accounting rule.\n" + "\n" + "Mandatory Fields\n"
|
||||||
+ "name, officeId,\n" + "accountToDebit OR debitTags,\n" + "accountToCredit OR creditTags.\n" + "\n" + "Optional Fields\n"
|
+ "name, officeId,\n" + "accountToDebit OR debitTags,\n" + "accountToCredit OR creditTags.\n" + "\n" + "Optional Fields\n"
|
||||||
+ "description")
|
+ "description")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.PostAccountingRulesRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = AccountRuleRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.PostAccountingRulesResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.PostAccountingRulesResponse.class))) })
|
||||||
public String createAccountingRule(@Parameter(hidden = true) final String jsonRequestBody) {
|
public CommandProcessingResult createAccountingRule(@Parameter(hidden = true) AccountRuleRequest accountRuleRequest) {
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createAccountingRule()
|
||||||
|
.withJson(apiJsonSerializerService.serialize(accountRuleRequest)).build();
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createAccountingRule().withJson(jsonRequestBody).build();
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@@ -193,18 +156,16 @@ public class AccountingRuleApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(summary = "Update a Accounting Rule", description = "Updates the details of a Accounting rule.")
|
@Operation(summary = "Update a Accounting Rule", description = "Updates the details of a Accounting rule.")
|
||||||
@RequestBody(content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.PutAccountingRulesRequest.class)))
|
@RequestBody(content = @Content(schema = @Schema(implementation = AccountRuleRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.PutAccountingRulesResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.PutAccountingRulesResponse.class))) })
|
||||||
public String updateAccountingRule(
|
public CommandProcessingResult updateAccountingRule(
|
||||||
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId,
|
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId,
|
||||||
@Parameter(hidden = true) final String jsonRequestBody) {
|
@Parameter(hidden = true) AccountRuleRequest accountRuleRequest) {
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateAccountingRule(accountingRuleId).withJson(jsonRequestBody)
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateAccountingRule(accountingRuleId)
|
||||||
.build();
|
.withJson(apiJsonSerializerService.serialize(accountRuleRequest)).build();
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@@ -214,55 +175,38 @@ public class AccountingRuleApiResource {
|
|||||||
@Operation(summary = "Delete a Accounting Rule", description = "Deletes a Accounting rule.")
|
@Operation(summary = "Delete a Accounting Rule", description = "Deletes a Accounting rule.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.DeleteAccountingRulesResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.DeleteAccountingRulesResponse.class))) })
|
||||||
public String deleteAccountingRule(
|
public CommandProcessingResult deleteAccountingRule(
|
||||||
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId) {
|
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId) {
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteAccountingRule(accountingRuleId).build();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteAccountingRule(accountingRuleId).build();
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccountingRuleData handleTemplate(AccountingRuleData accountingRuleData) {
|
private AccountingRuleData handleTemplate(AccountingRuleData accountingRuleData) {
|
||||||
final List<GLAccountData> allowedAccounts = this.accountReadPlatformService.retrieveAllEnabledDetailGLAccounts();
|
final List<GLAccountData> allowedAccounts = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts();
|
||||||
final List<OfficeData> allowedOffices = (List<OfficeData>) this.officeReadPlatformService.retrieveAllOfficesForDropdown();
|
final List<OfficeData> allowedOffices = (List<OfficeData>) officeReadPlatformService.retrieveAllOfficesForDropdown();
|
||||||
final Collection<CodeValueData> allowedTagOptions = this.codeValueReadPlatformService
|
final Collection<CodeValueData> allowedTagOptions = codeValueReadPlatformService
|
||||||
.retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME);
|
.retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME);
|
||||||
|
|
||||||
allowedTagOptions
|
allowedTagOptions
|
||||||
.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME));
|
.addAll(codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME));
|
||||||
allowedTagOptions
|
allowedTagOptions.addAll(codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME));
|
||||||
.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME));
|
allowedTagOptions.addAll(codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME));
|
||||||
allowedTagOptions
|
allowedTagOptions.addAll(codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME));
|
||||||
.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME));
|
|
||||||
allowedTagOptions
|
|
||||||
.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME));
|
|
||||||
|
|
||||||
if (accountingRuleData == null) {
|
if (accountingRuleData == null) {
|
||||||
|
|
||||||
final Collection<CodeValueData> allowedCreditTagOptions = allowedTagOptions;
|
|
||||||
final Collection<CodeValueData> allowedDebitTagOptions = allowedTagOptions;
|
|
||||||
|
|
||||||
accountingRuleData = new AccountingRuleData().setAllowedOffices(allowedOffices).setAllowedAccounts(allowedAccounts)
|
accountingRuleData = new AccountingRuleData().setAllowedOffices(allowedOffices).setAllowedAccounts(allowedAccounts)
|
||||||
.setAllowedCreditTagOptions(allowedCreditTagOptions).setAllowedDebitTagOptions(allowedDebitTagOptions);
|
.setAllowedCreditTagOptions(allowedTagOptions).setAllowedDebitTagOptions(allowedTagOptions);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
final Collection<CodeValueData> allowedCreditTagOptions;
|
final Collection<CodeValueData> allowedCreditTagOptions = accountingRuleData.getCreditTags() != null
|
||||||
final Collection<CodeValueData> allowedDebitTagOptions;
|
? retrieveSelectedTags(allowedTagOptions, accountingRuleData.getCreditTags())
|
||||||
|
: allowedTagOptions;
|
||||||
if (accountingRuleData.getCreditTags() != null) {
|
final Collection<CodeValueData> allowedDebitTagOptions = accountingRuleData.getDebitTags() != null
|
||||||
allowedCreditTagOptions = retrieveSelectedTags(allowedTagOptions, accountingRuleData.getCreditTags());
|
? retrieveSelectedTags(allowedTagOptions, accountingRuleData.getDebitTags())
|
||||||
} else {
|
: allowedTagOptions;
|
||||||
allowedCreditTagOptions = allowedTagOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accountingRuleData.getDebitTags() != null) {
|
|
||||||
allowedDebitTagOptions = retrieveSelectedTags(allowedTagOptions, accountingRuleData.getDebitTags());
|
|
||||||
} else {
|
|
||||||
allowedDebitTagOptions = allowedTagOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
accountingRuleData = new AccountingRuleData().setId(accountingRuleData.getId()).setOfficeId(accountingRuleData.getOfficeId())
|
accountingRuleData = new AccountingRuleData().setId(accountingRuleData.getId()).setOfficeId(accountingRuleData.getOfficeId())
|
||||||
.setOfficeName(accountingRuleData.getOfficeName()).setName(accountingRuleData.getName())
|
.setOfficeName(accountingRuleData.getOfficeName()).setName(accountingRuleData.getName())
|
||||||
|
|||||||
-67
@@ -19,11 +19,6 @@
|
|||||||
package org.apache.fineract.accounting.rule.api;
|
package org.apache.fineract.accounting.rule.api;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
|
||||||
import org.apache.fineract.accounting.rule.data.AccountingTagRuleData;
|
|
||||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sanyam on 26/7/17.
|
* Created by sanyam on 26/7/17.
|
||||||
@@ -34,57 +29,6 @@ final class AccountingRuleApiResourceSwagger {
|
|||||||
// For Swagger Documentation
|
// For Swagger Documentation
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "GetAccountRulesResponse")
|
|
||||||
public static final class GetAccountRulesResponse {
|
|
||||||
|
|
||||||
private GetAccountRulesResponse() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long id;
|
|
||||||
public Long officeId;
|
|
||||||
public String officeName;
|
|
||||||
public String name;
|
|
||||||
public String description;
|
|
||||||
public boolean systemDefined;
|
|
||||||
public boolean allowMultipleDebitEntries;
|
|
||||||
public boolean allowMultipleCreditEntries;
|
|
||||||
public List<AccountingTagRuleData> creditTags;
|
|
||||||
public List<AccountingTagRuleData> debitTags;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(description = "GetAccountRulesTemplateResponse")
|
|
||||||
public static final class GetAccountRulesTemplateResponse {
|
|
||||||
|
|
||||||
private GetAccountRulesTemplateResponse() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(example = "false")
|
|
||||||
public boolean systemDefined;
|
|
||||||
public List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
|
|
||||||
public List<GLAccountData> allowedAccounts = new ArrayList<GLAccountData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(description = "PostAccountingRulesRequest")
|
|
||||||
public static final class PostAccountingRulesRequest {
|
|
||||||
|
|
||||||
private PostAccountingRulesRequest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(example = "test")
|
|
||||||
public String name;
|
|
||||||
@Schema(example = "1")
|
|
||||||
public Long officeId;
|
|
||||||
@Schema(example = "21")
|
|
||||||
public Long accountToDebit;
|
|
||||||
@Schema(example = "9")
|
|
||||||
public Long accountToCredit;
|
|
||||||
@Schema(example = "Employee salary")
|
|
||||||
public String description;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(description = "PostAccountingRulesResponse")
|
@Schema(description = "PostAccountingRulesResponse")
|
||||||
public static final class PostAccountingRulesResponse {
|
public static final class PostAccountingRulesResponse {
|
||||||
|
|
||||||
@@ -98,17 +42,6 @@ final class AccountingRuleApiResourceSwagger {
|
|||||||
public Long resourceId;
|
public Long resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "PutAccountingRulesRequest")
|
|
||||||
public static final class PutAccountingRulesRequest {
|
|
||||||
|
|
||||||
private PutAccountingRulesRequest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(example = "Employee Salary posting rule")
|
|
||||||
public String name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Schema(description = "PutAccountingRulesResponse")
|
@Schema(description = "PutAccountingRulesResponse")
|
||||||
public static final class PutAccountingRulesResponse {
|
public static final class PutAccountingRulesResponse {
|
||||||
|
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.data.request;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public record AccountRuleRequest(String name, Long officeId, Long accountToDebit, Long accountToCredit,
|
||||||
|
String description) implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -26,18 +26,39 @@ apply plugin: 'com.github.davidmc24.gradle.plugin.avro-base'
|
|||||||
|
|
||||||
apply from: 'dependencies.gradle'
|
apply from: 'dependencies.gradle'
|
||||||
|
|
||||||
task preprocessAvroSchemas() {
|
abstract class PreprocessAvroSchemasTask extends DefaultTask {
|
||||||
doLast {
|
@InputDirectory
|
||||||
copy {
|
abstract DirectoryProperty getInputDir()
|
||||||
from "$projectDir/src/main/avro"
|
|
||||||
into "$buildDir/generated/avro/src/main/avro"
|
@InputFile
|
||||||
filter { line ->
|
abstract RegularFileProperty getBigDecimalTemplate()
|
||||||
line.replaceAll("\"bigdecimal\"", new File("$projectDir/src/main/resources/avro-templates/bigdecimal.avsc").getText("UTF-8"))
|
|
||||||
|
@OutputDirectory
|
||||||
|
abstract DirectoryProperty getOutputDir()
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
def preprocess() {
|
||||||
|
def template = getBigDecimalTemplate().get().asFile.getText("UTF-8")
|
||||||
|
def input = getInputDir().get().asFile
|
||||||
|
def output = getOutputDir().get().asFile
|
||||||
|
|
||||||
|
input.eachFileRecurse { file ->
|
||||||
|
if (file.isFile()) {
|
||||||
|
def relativePath = input.toPath().relativize(file.toPath())
|
||||||
|
def targetFile = output.toPath().resolve(relativePath).toFile()
|
||||||
|
targetFile.parentFile.mkdirs()
|
||||||
|
targetFile.text = file.text.replaceAll("\"bigdecimal\"", template)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register('preprocessAvroSchemas', PreprocessAvroSchemasTask) {
|
||||||
|
inputDir = file("$projectDir/src/main/avro")
|
||||||
|
bigDecimalTemplate = file("$projectDir/src/main/resources/avro-templates/bigdecimal.avsc")
|
||||||
|
outputDir = file("$buildDir/generated/avro/src/main/avro")
|
||||||
|
}
|
||||||
|
|
||||||
task buildJavaSdk(type: GenerateAvroJavaTask) {
|
task buildJavaSdk(type: GenerateAvroJavaTask) {
|
||||||
source("$buildDir/generated/avro/src/main/avro")
|
source("$buildDir/generated/avro/src/main/avro")
|
||||||
outputDir = file("$buildDir/generated/java/src/main/java")
|
outputDir = file("$buildDir/generated/java/src/main/java")
|
||||||
@@ -53,7 +74,33 @@ spotless {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildJavaSdk.dependsOn(preprocessAvroSchemas, spotlessJsonApply)
|
buildJavaSdk.dependsOn(preprocessAvroSchemas, spotlessJsonApply)
|
||||||
compileJava.dependsOn(buildJavaSdk, licenseFormatMain)
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDir file("$buildDir/generated/java/src/main/java")
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDir file("$projectDir/src/main/resources")
|
||||||
|
srcDir file("$projectDir/src/main/avro")
|
||||||
|
}
|
||||||
|
output.dir(file("$buildDir/generated/java/src/main/java"), builtBy: 'buildJavaSdk')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
from sourceSets.main.output
|
||||||
|
from("$buildDir/generated/java/src/main/java") {
|
||||||
|
include "**/*.java"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
dependsOn buildJavaSdk
|
||||||
|
source = sourceSets.main.java.srcDirs
|
||||||
|
options.compilerArgs += ['-parameters']
|
||||||
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// keep this at Java 8, not 17
|
// keep this at Java 8, not 17
|
||||||
@@ -61,7 +108,10 @@ java {
|
|||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.errorprone {
|
||||||
|
enabled = false // Disable ErrorProne for this module since it contains generated code
|
||||||
|
}
|
||||||
options.compilerArgs -= ["-Werror"]
|
options.compilerArgs -= ["-Werror"]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +124,10 @@ test {
|
|||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets.main.java.srcDir new File(buildDir, "generated/java/src/main/java")
|
|
||||||
|
|
||||||
licenseFormatMain.dependsOn buildJavaSdk
|
licenseFormatMain.dependsOn buildJavaSdk
|
||||||
licenseMain.dependsOn licenseFormatMain
|
licenseMain.dependsOn licenseFormatMain
|
||||||
|
|
||||||
|
tasks.named('sourcesJar') {
|
||||||
|
dependsOn tasks.named('buildJavaSdk')
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
{
|
{
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"doc": "The ID of the message to be sent",
|
"doc": "The ID of the message to be sent",
|
||||||
"type": "int"
|
"type": "long"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "type",
|
"name": "type",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
{
|
{
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"doc": "The ID of the message to be sent",
|
"doc": "The ID of the message to be sent",
|
||||||
"type": "int"
|
"type": "long"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "source",
|
"name": "source",
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "StringEnumOptionDataV1",
|
||||||
|
"namespace": "org.apache.fineract.avro.generic.v1",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "id",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"string"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "code",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"string"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "value",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"string"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -607,6 +607,17 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "loanTermVariations",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": "org.apache.fineract.avro.loan.v1.LoanTermVariationsDataV1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "clientActiveLoanOptions",
|
"name": "clientActiveLoanOptions",
|
||||||
@@ -709,6 +720,14 @@
|
|||||||
"org.apache.fineract.avro.generic.v1.EnumOptionDataV1"
|
"org.apache.fineract.avro.generic.v1.EnumOptionDataV1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "daysInYearCustomStrategy",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"org.apache.fineract.avro.generic.v1.StringEnumOptionDataV1"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "isInterestRecalculationEnabled",
|
"name": "isInterestRecalculationEnabled",
|
||||||
@@ -772,6 +791,57 @@
|
|||||||
"null",
|
"null",
|
||||||
"boolean"
|
"boolean"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "enableInstallmentLevelDelinquency",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "enableDownPayment",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "disbursedAmountPercentageForDownPayment",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"bigdecimal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "enableAutoRepaymentForDownPayment",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "interestRecognitionOnDisbursementDate",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "customData",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
{
|
||||||
|
"values": "bytes",
|
||||||
|
"type": "map"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,17 @@
|
|||||||
"null",
|
"null",
|
||||||
"string"
|
"string"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "customData",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
{
|
||||||
|
"values": "bytes",
|
||||||
|
"type": "map"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,14 @@
|
|||||||
"null",
|
"null",
|
||||||
"boolean"
|
"boolean"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "disallowInterestCalculationOnPastDue",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,14 @@
|
|||||||
"string"
|
"string"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "transferExternalGroupId",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"string"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "submittedDate",
|
"name": "submittedDate",
|
||||||
|
|||||||
@@ -419,6 +419,14 @@
|
|||||||
"org.apache.fineract.avro.generic.v1.EnumOptionDataV1"
|
"org.apache.fineract.avro.generic.v1.EnumOptionDataV1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "daysInYearCustomStrategy",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"org.apache.fineract.avro.generic.v1.StringEnumOptionDataV1"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "isInterestRecalculationEnabled",
|
"name": "isInterestRecalculationEnabled",
|
||||||
@@ -641,6 +649,14 @@
|
|||||||
"null",
|
"null",
|
||||||
"org.apache.fineract.avro.loan.v1.DelinquencyBucketDataV1"
|
"org.apache.fineract.avro.loan.v1.DelinquencyBucketDataV1"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "interestRecognitionOnDisbursementDate",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -146,6 +146,14 @@
|
|||||||
"null",
|
"null",
|
||||||
"boolean"
|
"boolean"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "disallowInterestCalculationOnPastDue",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,7 +437,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "totalUnpaidAccruedDueInterest",
|
"name": "totalUnpaidPayableDueInterest",
|
||||||
"type": [
|
"type": [
|
||||||
"null",
|
"null",
|
||||||
"bigdecimal"
|
"bigdecimal"
|
||||||
@@ -445,7 +445,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "totalUnpaidAccruedNotDueInterest",
|
"name": "totalUnpaidPayableNotDueInterest",
|
||||||
"type": [
|
"type": [
|
||||||
"null",
|
"null",
|
||||||
"bigdecimal"
|
"bigdecimal"
|
||||||
|
|||||||
@@ -244,6 +244,25 @@
|
|||||||
"null",
|
"null",
|
||||||
"string"
|
"string"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "customData",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
{
|
||||||
|
"values": "bytes",
|
||||||
|
"type": "map"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "reversed",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"logicalType": "decimal",
|
"logicalType": "decimal",
|
||||||
"precision": 20,
|
"precision": 27,
|
||||||
"scale": 8,
|
"scale": 8,
|
||||||
"type": "bytes"
|
"type": "bytes"
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-10
@@ -29,7 +29,6 @@ import java.time.LocalDate;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.organisation.teller.data.CashierData;
|
import org.apache.fineract.organisation.teller.data.CashierData;
|
||||||
import org.apache.fineract.organisation.teller.service.TellerManagementReadPlatformService;
|
import org.apache.fineract.organisation.teller.service.TellerManagementReadPlatformService;
|
||||||
@@ -41,20 +40,15 @@ import org.springframework.stereotype.Component;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CashierApiResource {
|
public class CashierApiResource {
|
||||||
|
|
||||||
private final DefaultToApiJsonSerializer<CashierData> jsonSerializer;
|
|
||||||
private final TellerManagementReadPlatformService readPlatformService;
|
private final TellerManagementReadPlatformService readPlatformService;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public String getCashierData(@QueryParam("officeId") final Long officeId, @QueryParam("tellerId") final Long tellerId,
|
public Collection<CashierData> getCashierData(@QueryParam("officeId") final Long officeId, @QueryParam("tellerId") final Long tellerId,
|
||||||
@QueryParam("staffId") final Long staffId, @QueryParam("date") final String date) {
|
@QueryParam("staffId") final Long staffId, @QueryParam("date") final String date) {
|
||||||
final DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE;
|
final LocalDate dateRestriction = date != null ? LocalDate.parse(date, DateTimeFormatter.BASIC_ISO_DATE)
|
||||||
|
: DateUtils.getBusinessLocalDate();
|
||||||
final LocalDate dateRestriction = (date != null ? LocalDate.parse(date, dateFormatter) : DateUtils.getBusinessLocalDate());
|
return readPlatformService.getCashierData(officeId, tellerId, staffId, dateRestriction);
|
||||||
|
|
||||||
final Collection<CashierData> allCashiers = this.readPlatformService.getCashierData(officeId, tellerId, staffId, dateRestriction);
|
|
||||||
|
|
||||||
return this.jsonSerializer.serialize(allCashiers);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user