feat(dds): FD-style account statuses, period-end interest, agent summary
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Waiting to run
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Waiting to run
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Waiting to run
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Waiting to run
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Waiting to run
Fineract Documentation build / build (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Waiting to run
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Waiting to run
Fineract Liquibase Only mode - PostgreSQL / test (push) Waiting to run
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Waiting to run
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Waiting to run
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Waiting to run

- Accounts move ACTIVE -> MATURED (nightly Post DDS Interest job) -> CLOSED on
  maturity payout, or to PREMATURE_CLOSED on early closure; both close the
  account themselves. Open-account queries treat MATURED as open; migration
  0628 brings existing accounts into line.
- Interest counts the opening day, runs through the day before the job date,
  and stops the day before maturity or closure; agent top-up counts the
  closing day.
- Calculation runs are applied as generated and empty runs are not saved.
- GET /dds/parties/summary adds up each agent's book (accounts, matured,
  premature closed, balance, collected, in arrears) with a partial index on
  collections (0627).
- Approvals: commission slab review data, and a pending premature closure
  shows what it will pay out rather than the bare balance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 18:33:06 +05:30
co-authored by Claude Opus 5.5
parent 375c2c95b6
commit 6508dbed67
14 changed files with 462 additions and 52 deletions
@@ -80,6 +80,10 @@ public class Party extends AbstractAuditableCustom {
public static final String STATUS_ACTIVE = "ACTIVE";
public static final String STATUS_CLOSED = "CLOSED";
/** Past its maturity date and not yet paid out - set by the nightly Post DDS Interest job, as FD's MATURED. */
public static final String STATUS_MATURED = "MATURED";
/** Closed before maturity, the shortfall settled - FD's Premature Closure. */
public static final String STATUS_PREMATURE_CLOSED = "PREMATURE_CLOSED";
@ManyToOne
@JoinColumn(name = "client_id", nullable = false)
@@ -566,8 +570,13 @@ public class Party extends AbstractAuditableCustom {
private static final String MINOR = "Minor";
private static final String ADULT = "Adult";
/** Closed either way - paid out at maturity, or broken before it. */
public boolean isClosed() {
return STATUS_CLOSED.equals(this.status);
return STATUS_CLOSED.equals(this.status) || STATUS_PREMATURE_CLOSED.equals(this.status);
}
public boolean isMatured() {
return STATUS_MATURED.equals(this.status);
}
/**
@@ -581,6 +590,12 @@ public class Party extends AbstractAuditableCustom {
this.closedByUserId = closedBy;
}
/** Closed before its term ran out, as a fixed deposit broken early is - kept apart from a maturity close. */
public void closePremature(final LocalDate closeDate, final Long closedBy) {
close(closeDate, closedBy);
this.status = STATUS_PREMATURE_CLOSED;
}
/** Ties the account to its product by id; called whenever subType is set or changed. */
public void linkProduct(final Long productId) {
this.accountTypeId = productId;