Commit Graph
9550 Commits
Author SHA1 Message Date
Jaanu423andClaude Sonnet 4.6 048a4ecfde feat(election): election duration blocking, director tenure auto-fill, audit logging, and scheduler
- Add durationYears to ElectionConfig with Liquibase migration (0348)
- Block new election creation when previous election duration is still active (PostgreSQL-compatible native query)
- Auto-override director tenureEndDate from election durationEndDate on appoint and update
- Add ElectionSchedulerConfiguration to enable @Scheduled support
- Fix JPQL EclipseLink enum compatibility in expireByTenureDate query
- Add full audit logging to DirectorAppointmentServiceImpl (appoint, update, remove, auto-expire)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 12:25:43 +05:30
Jaanu423andClaude Sonnet 4.6 7ce7353e7a feat(election): Board of Directors — director appointment management
- DirectorAppointment entity + Liquibase migration (0347)
- CRUD API: POST/GET/PUT/DELETE /v1/election/directors with @Valid Bean Validation
- GET /v1/election/directors/pending — WON candidates not yet appointed
- Duplicate prevention: existsByElectionIdAndCandidateId check on appoint
- Business validation: tenure end must be after start; tenure start cannot be before appointment date
- @Scheduled daily midnight job to auto-expire tenure-ended directors via bulk JPQL UPDATE
- Full audit logging for all director actions (success + failure) via ElectionAuditService
- PendingDirectorData DTO; DirectorAppointmentStatus enum (ACTIVE/RESIGNED/REMOVED/TENURE_ENDED)
- ElectionAuditAction: added APPOINT_DIRECTOR, UPDATE_DIRECTOR_APPOINTMENT, REMOVE_DIRECTOR_APPOINTMENT + FAILED variants
- ElectionResultRepository: findByResult(String) for pending director lookup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 12:50:04 +05:30
Jaanu423andClaude Sonnet 4.6 ba199d78e7 feat(election): date validations, overdue-only NDC/loan checks, audit log gaps fixed
- Added ElectionDateViolationException for proper 4xx on date violations
- createElection: validates date order (nominationStart <= nominationEnd <= electionDate <= resultDate)
- withdrawNomination/resubmitNomination: blocked after nominationEndDate
- closeNominations: requires today >= nominationEndDate
- openVoting/closeVoting: requires today >= electionDate
- declareResults: requires today >= resultDate (or electionDate if no resultDate)
- NDC hasNoDues: checks overdue EMIs only (total_overdue_derived), not outstanding balance
- Director/guarantor/family loan checks: overdue-based only — pass if no missed EMIs
- MemberHasOutstandingDuesException: proper AbstractPlatformDomainRuleException (was IllegalStateException → 500)
- Audit gaps fixed: RESUBMIT_NOMINATION_FAILED added to enum, try/catch added for resubmit,
  createElection, updateElection; saveManualVoteCounts catches all RuntimeException

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 16:50:08 +05:30
Jaanu423andClaude Sonnet 4.6 99cc972804 feat(election): comprehensive audit log — rich details for all actions
- Fixed VARCHAR(500) overflow: description column changed to TEXT (Liquibase 0346)
- Fixed CEO pre-check 500 error: fm.firstname/lastname column name fix
- Fixed audit log showing wrong PASS/FAIL for CEO pre-check
- Fixed approval action not showing step name/number (read PENDING step before action)
- submitNomination: details JSON with applicantName, memberId, postId, gender, caste
- runEligibilityCheck: details JSON with all 5 check results + remarks
- runCeoPreCheck: details JSON with all 7 individual check results + remarks
- processApprovalStep: details JSON with action, stepName, stepNumber, remarks, rejectionReason
- activateElection/closeNominations/openVoting/closeVoting/cancelElection: details with electionTitle + newStatus
- updateElection: full request JSON via ObjectMapper
- approveCandidate: details with nominationId + applicantName
- updateCandidate: details with symbolUpdated, profileUpdated, briefProfile
- uploadCandidateSymbol: details with filename + mimeType
- declareResults: winner summary JSON array [{post, winner, votes}]
- saveManualVoteCounts: return type changed void→String, details JSON array with candidate vote data
- Added Liquibase migrations: 0344, 0345 for manual vote count, 0346 for TEXT column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 14:59:23 +05:30
Jaanu423andClaude Sonnet 4.6 99a89d5d81 feat(election): overall shareholder analysis API + analytics enhancements
- ElectionAnalyticsServiceImpl: fix SQL_FAMILY to count candidate's own family members who are active shareholders (candidate-specific, not system-wide)
- ElectionAnalyticsServiceImpl: SQL_SUB_CASTE now groups by m_client.lastname instead of sub_caste_cv_id
- ElectionAnalyticsServiceImpl: SQL_CANDIDATE_INFO fetches candidate client_id, lastname, religion for match highlighting
- ElectionAnalyticsServiceImpl: add getOverallShareholderAnalysis() — returns all demographic breakdowns with no candidate matching
- ElectionAnalyticsService: add getOverallShareholderAnalysis() interface method
- ElectionCandidateApiResource: add GET /{electionId}/shareholders/analysis endpoint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 18:36:02 +05:30
Jaanu423andClaude Sonnet 4.6 388af0a6a3 feat(election): candidate voter analysis API — multi-dimension breakdown + sub-caste migration
- New ElectionAnalyticsServiceImpl with 14 SQL breakdown queries:
  gender, age, area, social category (caste), sub-caste, religion,
  occupation, share-holding, tenure, loan, education, marital status,
  monthly income, savings account depth
- Cross-dimension match: caste + area simultaneously (core voter base)
- Zero-count row injection for caste/gender/sub-caste when candidate's
  category has no shareholder matches in GROUP BY result
- Liquibase 0343: sub_caste_cv_id column on m_client with 33 pre-seeded
  sub-caste values across General / OBC / SC / ST categories
- Liquibase 0342: election post eligibility columns
- CandidateVoterAnalysisData DTO with education, marital, income,
  savings, activeSavingsHolders, crossMatchCount fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 11:54:01 +05:30
Jaanu423andClaude Sonnet 4.6 34f84e1fc6 chore: remove tracked log files and ignore logs directory permanently
- Delete all fineract-provider/logs/*.log from version control
- Add fineract-provider/logs/ to .gitignore so runtime logs are
  never tracked again

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 13:06:54 +05:30
Jaanu423andClaude Sonnet 4.6 69513f25f3 feat(election): production-ready audit log with server-side filter + pagination
- Add m_election_audit_log table via Liquibase (0341)
- ElectionAuditLog entity, ElectionAuditAction enum (21 actions)
- ElectionAuditService: log() with double try-catch, getAuditLogPaged()
  with entityType/action/full-text filters, size cap at 100, page safety
- ElectionAuditLogRepository: findWithFilters() JPQL with optional params
- All 4 election API resources wired with audit calls (create/update/
  activate/nominations/voting/candidates/votes/results)
- GET /{electionId}/audit-log accepts ?entityType=&action=&search=&page=&size=

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 12:57:21 +05:30
Jaanu423andClaude Sonnet 4.6 3d30bdb788 feat(election): CBS ContentStore symbol upload, hasSymbol DTO, vote summary API
- ElectionCandidateData: replace String symbol with Boolean hasSymbol + add memberId
- ElectionCandidateApiResource: symbol upload/download via ContentStoreService
  (mimeType|storagePath format, backward-compatible with legacy base64 records)
- ElectionVotingApiResource: add GET /vote-summary endpoint (totalVotes, totalVoters,
  per-candidate breakdown) using ElectionVoteRepository queries
- ElectionVoteRepository: add countByElectionConfigId and voteSummaryByCandidate queries
- ElectionReadPlatformServiceImpl: map hasSymbol and memberId in candidate list response
- ElectionWritePlatformServiceImpl: set photoUrl from memberId on approveCandidate,
  delete old symbol file from ContentStore on removeCandidate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 18:39:28 +05:30
Jaanu423andClaude Sonnet 4.6 ed139d6e68 feat(election): server-side pagination, family loan CEO pre-check, extended checks
- PagedResponse<T>: generic paginated wrapper with statusCounts and summary fields
- ElectionConfigRepository: pageable query + countGroupByStatus
- ElectionNominationRepository: pageable queries + count-by-status helpers
- ElectionCandidateRepository: pageable queries by election and post
- ElectionReadPlatformService: all list methods return PagedResponse with page/size params
- ElectionReadPlatformServiceImpl: add missing Pageable import; paginated impls with summary data
- API resources: @QueryParam page/size with @DefaultValue on all 3 list endpoints
- ElectionCeoPrecheck: add familyLoanCheckResult + familyLoanCheckRemarks (7th auto-check)
- ElectionCeoPreCheckServiceImpl: fix directorLoan check (overdue only); add family loan check covering manual members (unverifiable→FAIL) and linked CBS clients (overdue→FAIL)
- Liquibase 0338/0339: extended CEO pre-check columns + family loan check columns
- changelog-tenant.xml: include both new changesets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 12:08:29 +05:30
Jaanu423andClaude Sonnet 4.6 fc80869d4b feat(guarantor): enrich guarantor accounts API with loan health and borrower details
- Add borrower name, savings account, guaranteed/released/remaining amounts, loan timeline, and overdue info to GuarantorAccountSummaryData
- Fix duplicate rows in GuarantorLoanAccountSummaryDataMapper by joining savings account via guarantor funding details instead of client ID
- Fix NPE in GuarantorDomainServiceImpl when loan product guarantee details are null

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 13:15:25 +05:30
Jaanu423andClaude Sonnet 4.6 1eba2c50ed fix(election): move additional permissions to new changeset to avoid Liquibase checksum error
The 5 missing permissions were added to the already-executed changeset
causing checksum mismatch on restart. Move them to a new changeset
0337_seed_election_permissions_v2 with a preCondition guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:13:39 +05:30
Jaanu423andClaude Sonnet 4.6 3367b7d935 fix(election): seed missing permissions in Liquibase migration 0337
Add 5 permissions that the write service enforces but were absent from
the DB seed: UPDATE_ELECTION, ELIGIBILITY_CHECK_ELECTION,
CEO_PRECHECK_ELECTION, APPROVE_ELECTION_NOMINATION,
APPROVE_ELECTION_CANDIDATE — without these, role assignments for those
operations would fail at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 10:48:46 +05:30
Jaanu423andClaude Sonnet 4.6 5899d2ca07 feat(election): add election module — config, nominations, candidates, voting, approval flow
- REST API resources: ElectionConfig, ElectionNomination, ElectionCandidate, ElectionVoting
- Domain entities, repositories, services (read + write) with maker-checker approval steps
- Eligibility checks, no-due-certificate, CEO pre-check services
- Liquibase migration 0337 creates all election module tables

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 17:39:43 +05:30
Jaanu423andClaude Sonnet 4.6 c1e23080fc fix(share-account+clerk): remove cashier collection validation, add NPE guards
ShareAccountWritePlatformServiceJpaRepositoryImpl:
- Remove m_share_cashier_collection validation from activateShareAccount() —
  cashier now enters GL directly via transaction entry workstation
- Mark all share account charges as paid on activation instead of posting
  duplicate GL (cashier already posted DR Cash -> CR Charges GL directly)
- Remove unused imports: java.sql.Date, EmptyResultDataAccessException, Collectors
- Update createShareAccount() comment to reflect new cashier GL flow

ClerkDisbursementRequestApiResource:
- Add null guard for clerk_id before cast in approve() — returns 500 with
  clear message if DB record is missing the field
- Add null/blank guard for credit_entries in approve() — returns 400 with
  clear message instead of NPE on gson.fromJson

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 18:46:17 +05:30
Jaanu423andClaude Sonnet 4.6 7354da8c1e feat(bank-transfer): add maker-checker support for bank transfers
- Added request_type column to m_clerk_disbursement_request via migration 0336
- submit() extracts requestType from body, stores in DB (defaults to DISBURSEMENT)
- approve() detects BANK_TRANSFER mode via request_type field:
    - DR entries: directDebitSavingsAccount / directDebitCurrentAccount
    - CR entries: directCreditSavingsAccount / directCreditCurrentAccount
    - GL: DR SavingsControl(per DR) / CR SavingsControl(per CR)
    - Audit INSERT into m_bank_transfer_log with unique BT voucher number
    - Existing disbursement/collection logic unchanged in else branch
- list(), myRequests(), loadRecord() all return request_type
- Migration 0335 (m_bank_transfer_log) also included

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:47:21 +05:30
Jaanu423andClaude Sonnet 4.6 bf5ce421df feat(clerk+gl): implement real CBS book transfer for savings and current account disbursements
- Replace Fineract cash deposit API with direct INSERT for both savings and current accounts
  → Zero CashVault entries created anywhere in DB for disbursements
- Savings: directCreditSavingsAccount now sets running_balance_derived and updates
  total_deposits_derived alongside account_balance_derived (parity with current account)
- Current: directCreditCurrentAccount — direct INSERT into m_current_account_transaction
  with running_balance_derived, total_deposits_derived update, and remarks audit field
- getCurrentControlGlId: looks up SAVINGS_CONTROL GL for current account products
  via acc_product_mapping (product_type=2, financial_account_type=2)
- directReverseCurrentCredit: compensation restores both account_balance_derived
  and total_deposits_derived on rollback
- GL: combined DR sourceGL / CR SavingsControl entry posted for both savings and
  current account credits; linkGlEntriesToSavingsAccounts sets entity_type_enum=2
  so ACCOUNT NO column shows in journal entries view
- Hide reversed=true GL entries from all GL views in JournalEntryReadPlatformServiceImpl

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 11:04:17 +05:30
Jaanu423andClaude Sonnet 4.6 d002fc0c9b feat(clerk): add collection flow backend — savings withdrawal + Cash@Vault GL offset
- ClerkDisbursementRequestApiResource: support collection mode (dbCr='Dr' entries); submit() separates DR/CR totals and validates balance; approve() detects mode, calls executeSavingsWithdrawal/executeCurrentAccountWithdrawal for DR entries, then posts GL offset via findCashVaultGlId(txnRefs, type_enum=1) → target GL
- ClerkWithdrawalRequestApiResource: minor updates
- DB migration: changelog-tenant.xml + 0333_rename_disbursed_to_withdrawn.xml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 15:27:32 +05:30
Jaanu423andClaude Sonnet 4.6 a6eae3d6e8 feat(clerk): add GL disbursement maker-checker backend
- Add ClerkDisbursementRequestApiResource with submit/list/my/approve/reject endpoints
- Approve posts savings/current deposits then offsets DR source GL / CR Cash at Vault
- Add Liquibase migration for m_clerk_disbursement_request table (IF NOT EXISTS indexes)
- Add VoucherService constants TYPE_DISBURSEMENT and REF_CLERK_DISBURSEMENT_REQUEST

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 10:44:04 +05:30
Jaanu423andClaude Sonnet 4.6 3e1abaef03 fix(cashier): fix NumberFormatException on GL deposit approval and add GL maker-checker flow
- Use parseTxnIdToLong() for voucherService.linkSavingsTransaction() to
  handle hex GL txnId (e.g. "a2070e542bab") without NumberFormatException
- Add GL deposit maker-checker: submit stores gl_account_id, contra_gl_id,
  office_id, currency_code; approve routes to executeGlJournalEntry()
- Save denomination at submit time (cash physically received); update
  txn_id to real Fineract ID on approve, delete on reject
- Add Liquibase migration 0331 to add GL columns to m_cashier_deposit_request

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:59:28 +05:30
Jaanu423andClaude Sonnet 4.6 40449ef0f7 fix(cashier+clerk): route CA deposits and withdrawals to current account commands
CashierDepositRequestApiResource:
- approve(): use isCurrentAccountById() to detect current accounts, route to
  executeCurrentAccountDeposit() instead of executeSavingsDeposit()
- Add executeCurrentAccountDeposit() using CommandWrapperBuilder.currentAccountDeposit()
- Add isCurrentAccountById() helper querying m_current_account table
- Add POST /{id}/reprocess endpoint to fix already-approved CA records that
  were wrongly posted to savings account

ClerkWithdrawalRequestApiResource:
- approve(): use isCurrentAccountById() to detect current accounts, route to
  executeCurrentAccountWithdrawal() instead of executeSavingsWithdrawal()
- Add executeCurrentAccountWithdrawal() using CommandWrapperBuilder.currentAccountWithdrawal()
- Add isCurrentAccountById() helper querying m_current_account table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 12:52:09 +05:30
Jaanu423andClaude Sonnet 4.6 33ea10689f feat(cashier+voucher): add cashier deposit maker-checker flow and central voucher system
- VoucherService: central voucher register with globally unique voucher numbers
- CashierDepositRequestApiResource: full submit/approve/reject/list flow
  - Cashier submits deposit request; balance credited only on manager approval
  - Self-approval blocked (maker cannot be checker)
  - Role guard: only manager/head-cashier/ALL_FUNCTIONS can approve/reject
  - Race condition guard: WHERE status='PENDING' on approve/reject UPDATE
  - Clean JSON error responses (no 500 stack traces) via apiError() helper
  - Denomination total validation at submit and approve
- ClerkWithdrawalRequestApiResource: refactored to use m_voucher
  - Voucher created at submit, linked to savings txn at approve
  - Same role guard and self-approval block as deposit flow
  - Disburse: denomination validation, null denoms for non-cash payments
- Migrations 0327-0330:
  - 0327: add voucher_no to m_clerk_withdrawal_request
  - 0328: add voucher_no to m_savings_account_transaction
  - 0329: create m_voucher central table (globally unique voucher_no)
  - 0330: create m_cashier_deposit_request table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 10:53:47 +05:30
Jaanu423andClaude Sonnet 4.6 8d5b4d1ce9 feat(clerk-withdrawal): add maker-checker withdrawal disbursement API
- ClerkWithdrawalRequestApiResource: full CRUD for withdrawal requests
- Endpoints: submit, list, myRequests, getById, getByToken, approve, reject, disburse, update
- Token uniqueness validated per day (validateTokenUniqueToday)
- Cashier disburse: amount match, race condition guard (WHERE status=APPROVED)
- Disbursement denomination saved to m_savings_txn_denomination for vault position tracking
- Liquibase migrations: 0321-0326 (create table, tok_no, manager fields, disbursement fields, drop unused counter)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 16:00:57 +05:30
Jaanu423andClaude Sonnet 4.6 db94056144 feat(cashier): add server-side pagination and date ordering to GL entries endpoint
- Add offset/limit query params with defaults (limit=20, offset=0)
- Return totalFilteredRecords + pageItems response structure
- Compute totalDr/totalCr from all records (not just current page)
- Fix ordering: ORDER BY MAX(created_at) for correct chronological sort

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:53:49 +05:30
Jaanu423andClaude Sonnet 4.6 19639c9e02 feat(cashier): add GL denomination tracking, live GL balance, and enhanced closing report
- Add CashierGlDenominationApiResource: new POST /v1/cashier/gl-denomination endpoint
  to record denomination breakdown for GL journal entries in m_savings_txn_denomination
- Fix GL account real-time balance in GLAccountReadPlatformServiceImpl using live SUM query
- Add Liquibase migrations 0318/0319/0320: make savings_account_id and txn_id nullable,
  add payment_type column to m_savings_txn_denomination
- Add validCheckSum to 0317b changeset to resolve checksum mismatch on existing installs
- Enhance GL entries closing report SQL with date, time, teller, payment type, txn source

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:31:12 +05:30
Jaanu423andClaude Sonnet 4.6 53b6a94bf8 fix(cashier): fix GL account search SQL bug, running balance, and add CASHIER role permissions
- Fix searchParam SQL syntax: parameterized LIKE with %value% instead of literal %?%
- Fix organizationRunningBalance: correlated subquery for latest journal entry (ORDER BY id DESC LIMIT 1)
- Migration 0317: grant READ_GLACCOUNT, READ_LOAN, READ_SHAREACCOUNT to CASHIER role

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 11:17:32 +05:30
Jaanu423andClaude Sonnet 4.6 6d0c1fe7f6 feat(clerk): add clerk role with cashier teller workstation permissions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:27:04 +05:30
Jaanu423andClaude Sonnet 4.6 edaeb674d5 feat(cashier): fix current account transactions search and withdrawal validations
CurrentAccountTransactionsApiResource:
- Fixed: search endpoint now queries m_current_account_transaction
  instead of m_savings_account_transaction (wrong table)
- Added remarks column to search query (column exists in CA table)
- Charge Deduction (type=7) mapped in transactionType value
- Removed sat.remarks that caused 500 (column doesn't exist in savings table)

CurrentAccountTransactionWritePlatformServiceImpl:
- Added min required balance validation in withdrawal()
- Throws GeneralPlatformDomainRuleException when balance after withdrawal
  would fall below minRequiredBalance (if enforceMinRequiredBalance=true)

StandingInstructionReadPlatformServiceImpl:
- Fixed SQL WHERE clause: fromAccountType + fromAccount condition
  now correctly adds WHERE when fromAccountId is set

Liquibase 0315:
- Fix standing instruction permission code (trim trailing space on id=449)
- Grant READ permissions to CASHIER role for transaction entry screen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 22:27:59 +05:30
Jaanu423andClaude Sonnet 4.6 2371ad98b1 feat(cashier): add role-based data filtering and pagination for teller workstation
- Add CashierRoleHelper service: detects CASHIER role via DB permission
  check, resolves cashier ID from staff/user linkage
- Role-based filtering on GET list endpoints (cashtransfer, cashsettlement,
  cashintercashier, cashexchange, cashreports): CASHIER sees only own data,
  ADMIN/HEAD sees all
- Pagination (offset/limit) added to all cashier list APIs returning
  standard Fineract Page format {totalFilteredRecords, pageItems}
- ShareCollectionApiResource: collect cash before account activation,
  post GL entries (Dr Cash Vault / Cr Share Sundry / Cr Income from Fees),
  mark charges paid to prevent duplicate GL on activation,
  GET status endpoint for collection check
- Migration 0315: grant READ_CLIENTKYC, READ_CLIENTNOMINEE, READ_ADDRESS,
  READ_FAMILYMEMBERS, READ_SAVINGSACCOUNT to CASHIER role

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 11:00:55 +05:30
Jaanu423andClaude Sonnet 4.6 9d944d0196 feat(share): add cashier share collection endpoint with GL posting and activation validation
- New POST /cashier/sharecollection endpoint: collects cash for share purchase,
  posts Dr Cash Vault / Cr Share Sundry / Cr Income GL entries, marks charges
  as paid and sets cashier_collected flag on the account
- GET /cashier/sharecollection/:id endpoint for collection status check
- Block share account activation if cashier has not collected cash first
  (validates m_share_cashier_collection record within last 30 days)
- Skip duplicate charge GL on activation when charge already collected upfront
- Suppress automatic GL posting at account submission time to prevent
  double entries; GL is now posted only via cashier collection endpoint
- Fix JdbcTemplate injection in ShareAccountWritePlatformServiceJpaRepositoryImpl
  via ShareAccountsConfiguration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 13:22:33 +05:30
Jaanu423andClaude Sonnet 4.6 6e31ac9acd fix(savings): allow modifyApplication for rejected Savings/FD/RD accounts
SavingsAccount.modifyApplication() previously blocked modification unless
the account was in SUBMITTED_AND_PENDING_APPROVAL state. Extended to also
allow REJECTED state so bank users can amend and re-submit rejected applications.

When a rejected account is modified, status resets to
SUBMITTED_AND_PENDING_APPROVAL (rejectedOnDate and rejectedBy cleared)
so the account re-enters the approval workflow.

Applies to Savings, FD, and RD accounts (all extend SavingsAccount).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 14:55:39 +05:30
Jaanu423andClaude Sonnet 4.6 a051faba5d feat(accounts): backend fixes for Modify Application feature (Current/Savings/FD/RD)
Current Account:
- CurrentAccountReadPlatformServiceImpl: add retrieveJointHolders() and retrievePartners()
- CurrentAccountWritePlatformServiceImpl: full modifyApplication() - updates all CBS fields,
  joint holders, partners, nominees, facility config, dates, introducer
- Fix cbsAccountType save: parse string account type from 'accountType' JSON field

Nominees:
- ClientNomineeWritePlatformService: add replaceNomineesForAccount() for atomic replace
- Savings/FD/RD modifyApplication: replace nominees on modify

FD/RD Read (DepositAccountReadPlatformServiceImpl):
- Add isSeniorCitizen, seniorCitizenInterestRate to BASE SQL SELECT
- Add setCbsAccountFields() call in FD/RD mappers reading accountStatus, modeOfOperation,
  introducerClientId, guardianFields, linkedAccountId, isSeniorCitizen from ResultSet
- Fix retrieveOne() to also fetch joint holders from m_savings_account_joint_holders
- Use explicit LinkedHashMap in joint holder query (camelCase keys for Angular)

FD/RD Data Classes:
- FixedDepositAccountData: add accountStatus, modeOfOperation, introducerClientId,
  linkedAccountId, jointHolders, isSeniorCitizen, seniorCitizenInterestRate fields
- RecurringDepositAccountData: same fields added
- Fix all factory methods (withInterestChartAndRecurringDetails, withClosureTemplateDetails,
  withTemplateOptions, associationsAndTemplate) to call copyCbsFieldsFrom()
- Fix SavingsAccountReadPlatformServiceImpl joint holders: use camelCase keys

FD Calculator:
- FixedDepositAccountInterestCalculationServiceImpl: add calculateExact() with actual
  calendar-based calculation matching PostingPeriod engine (exact same as account creation)
- Add submittedOnDate, daysInYear, interestPostingPeriodInMonths optional params
- Support interestCompoundingPeriodInMonths=0 (daily compounding) in both validator and calc
- DepositsApiConstants: add submittedOnDate/dateFormat/locale/daysInYear to allowed params
- DepositAccountDataValidator: allow 0 (daily) in interestCompoundingPeriodInMonths

Misc:
- SavingsProductData: null-check in isCashBased/isAccrualBased methods (NPE fix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 10:32:59 +05:30
Jaanu423andClaude Sonnet 4.6 7c4cf6260c feat(cashier): GL entries endpoint + remove vault-cashier GL postings
- GET /cashreports/gl-entries: returns voucher_no, ac_no, ac_name
  (customer name), dr (withdrawal), cr (deposit) for cashier transactions
  with optional cashierId/tellerId filter
- TellerWritePlatformServiceJpaImpl: removed ALLOCATE/SETTLE GL entries
- OrganisationTellerConfiguration: removed obsolete GL constructor args

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 10:47:22 +05:30
Jaanu423andClaude Sonnet 4.6 6bdcac7b77 feat(cashier): remove GL entries for vault-to-cashier transfers (Option A)
ALLOCATE (vault→cashier) and SETTLE (cashier→vault) no longer post
DR CASH_AT_TELLER / CR CASH_AT_MAINVAULT journal entries.

Rationale: Cash transfer between vault and teller drawer is an internal
physical movement — the denomination/amount is already tracked operationally
via m_cash_transfer and m_cash_settlement tables. A single Cash in Hand GL
(CASH_AT_MAINVAULT) covers all bank cash. GL entries now only occur on
actual customer deposit/withdrawal transactions (SAVINGS_REFERENCE ↔
SAVINGS_CONTROL), keeping the GL clean and RBI-compliant.

Removed unused imports and field injections:
  JournalEntryRepository, FinancialActivityAccountRepositoryWrapper,
  FinancialActivity, FinancialActivityAccount, GLAccount,
  JournalEntry, JournalEntryType

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:13:48 +05:30
Jaanu423andClaude Sonnet 4.6 8bf28a8033 fix(cashier): prevent duplicate cashier lookup crash + add missing migrations
- DenominationBreakdownWriter: add ORDER BY mc.id DESC LIMIT 1 to all cashier
  lookup queries so multiple cashier records per staff do not crash queryForObject
- CashReportApiResource: same LIMIT 1 fix for cashier-day-status and position endpoints
- 0311: fix m_client and m_savings_account NOT NULL columns (created_by, last_modified_by,
  created_on_utc, last_modified_on_utc, cif_number, is_lien_allowed, etc.)
- 0312: create CASHIER role if missing + grant all 34 cashier permissions (incl FD/RD)
- 0313: add missing m_cash_exchange columns (cashier_id, is_reversed, reversed_by,
  reversed_at, reverse_reason, customer_id_proof)
- 0314: unique constraint on m_cashiers.staff_id to prevent duplicate allocations
- application.properties: restore local postgres password after merge
- ExecuteOverdueAndCurrentStandingInstructionsTest: fix constructor call (5 args)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 18:23:31 +05:30
Jaanu423 d4262ebf6f Merge remote-tracking branch 'origin/feature/switch-integration-backend' into feature/account-charges 2026-06-01 13:23:22 +05:30
Jaanu423andClaude Sonnet 4.6 656a0b4f13 feat(cashier): add morning transfer validation & fix denomination SQL
- validateCashierHasMorningTransfer(): blocks all txns when no today's cash transfer in m_cash_transfer
- validatePreviousDayClosed(): blocks when previous business day unsettled
- Both validations called on deposit AND withdrawal in Savings, Current, FD, RD services
- cashier-day-status endpoint now returns morningTransferReceived field
- getCashierTotalCash SQL fixed: dm.denomination_value -> dm.denomination

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:15:52 +05:30
Aditya ae7017ca81 @
feat(fundtransfer+imps+mfa): fund transfer module, IMPS switch client, MFA log API

- Fund transfer: NEFT/RTGS/IMPS/internal strategies, limit resolution, bulk
  transfer, verification tokens, suspense GL, recall/approval flow, jobs
- IMPS CBS switch client with crypto (JWT/envelope) and transaction domain
- MFA log read API (audit of MFA events)
- Liquibase migrations 0300-0311 for fund transfer / IMPS tables, permissions,
  roles, and suspense account
- JobName, SecurityConfig, dependencies.gradle wiring

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-06-01 12:18:30 +05:30
Aditya 6413befe07 Merge self-hosted/feature/account-charges into feature/Backend-DSC-MFA 2026-06-01 12:14:49 +05:30
Jaanu423andClaude Sonnet 4.6 eae5b03d7e feat(cashier): denomination withdrawal validation, exchange detail fix, cash exchange in excess report
- Savings/Current/FD/RD withdrawal services: call validateWithdrawalStock() before
  validateBreakdown() to block withdrawal when cashier lacks the requested denomination
- CashExchangeApiResource: validate cashier denomination stock before giving to customer;
  fix saveAndFlush (EclipseLink does not flush on save() — getId() returned null causing
  exchange_id NOT NULL violation in m_cash_exchange_detail)
- CashReportApiResource excess(): include cash exchanges >= threshold in result,
  add type field (SAVINGS_TXN/EXCHANGE) and idProof for RBI/AML compliance;
  combined list sorted by amount DESC
- CashReportApiResource closing(): add denomination-wise exchange rows (already present)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 10:11:44 +05:30
Jaanu423andClaude Sonnet 4.6 49d64004cc feat(cashier): add cashier-morning balance endpoint and expose fromCashierId in settlement/transfer APIs
- GET /cashreports/cashier-morning: returns denomination-wise cash received by cashier from vault
  for a given date (only vault→cashier transfers, non-reversed)
- CashSettlementApiResource: include fromCashierId in list and detail responses
- CashTransferApiResource: include toCashierId in list and detail responses for traceability

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 08:55:09 +05:30
Jaanu423 ada24d7497 feat(cashier): implement expected balance for logged-in cashier, settlement checks, and reconciliation rules 2026-05-28 22:28:30 +05:30
Jaanu423andClaude Sonnet 4.6 b89e653bcb feat: cash management backend - transfer, settlement, inter-cashier, reconciliation + cashier /me position endpoint
OVERVIEW
--------
Added complete cash management backend covering the full cashier workflow:
vault transfers, inter-cashier transfers, end-of-day settlement, GL
reconciliation, and a new authenticated /me endpoint for cashier position
lookup without needing to pass a cashier ID.

NEW API ENDPOINT
----------------
GET /cashreports/cashier-position/me
- Auto-detects the authenticated user via PlatformSecurityContext
- Resolves appUser -> staff -> cashier via m_cashiers JOIN chain
- Accepts optional ?asOfDate=YYYY-MM-DD query param (defaults to today)
- Reuses existing buildPositionForCashier(cashierId, dateFilter) internally
- Returns: { cashierId, asOfDate, totalAmount, denominations[] }
- Non-cashier users get empty denominations array (no error thrown)
- Used by Angular UI to show opening/closing denomination panels

CASH TRANSFER (vault -> cashier)
---------------------------------
CashTransferApiResource.java   — REST endpoints (POST /cashtransfer, GET list/detail)
CashTransfer.java              — JPA entity (m_cash_transfer)
CashTransferDetail.java        — JPA entity (denomination breakdown, m_cash_transfer_detail)
CashTransferRepository.java    — Spring Data JPA repository
CashTransferDetailRepository.java

DB migrations:
  0014_cash_transfer.xml       — creates m_cash_transfer + m_cash_transfer_detail tables
  0015_cash_transfer_add_ids.xml — adds missing ID columns to transfer detail

CASH SETTLEMENT (end-of-day cashier close)
------------------------------------------
CashSettlementApiResource.java — REST endpoints (POST /cashsettlement, GET list/detail)
CashSettlement.java            — JPA entity (m_cash_settlement)
CashSettlementDetail.java      — JPA entity (denomination breakdown)
CashSettlementRepository.java
CashSettlementDetailRepository.java

DB migration:
  0016_cash_settlement.xml     — creates m_cash_settlement + m_cash_settlement_detail

INTER-CASHIER TRANSFER
-----------------------
CashInterCashierApiResource.java — REST endpoints (POST /cashintercashier, GET list/detail)
CashInterCashier.java            — JPA entity (m_cash_inter_cashier)
CashInterCashierDetail.java      — JPA entity (denomination breakdown)
CashInterCashierRepository.java
CashInterCashierDetailRepository.java

DB migration:
  0017_cash_inter_cashier.xml  — creates m_cash_inter_cashier + detail table

CASH RECONCILIATION
--------------------
CashReconciliationApiResource.java — REST endpoints (POST /cashreconciliation, GET list)
CashReconciliation.java            — JPA entity (m_cash_reconciliation)
CashReconciliationDetail.java      — JPA entity (denomination breakdown)
CashReconciliationRepository.java
CashReconciliationDetailRepository.java

DB migrations:
  0018_cash_reconciliation.xml — creates m_cash_reconciliation + detail table
  0019_cash_reversal_columns.xml — adds reversal tracking columns
  0020_cash_permissions.xml    — adds permissions for all cash management APIs

GL DISPATCH SERVICE
-------------------
GlDispatchService.java (portfolio/teller/service/)
- Shared service for posting GL journal entries for cash movements
- Used by settlement and reconciliation flows

CHANGELOG
---------
changelog-tenant.xml updated to include migrations 0014 through 0020.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 17:40:57 +05:30
Jaanu423andClaude Opus 4.7 9a30ede278 feat: denomination save+validation for all deposit types + cash exchange backend
- DenominationBreakdownWriter helper: validates breakdown total == amount and
  persists per-denomination rows; wired into current, FD and RD deposit flows
  (savings already had inline save) so all 4 deposit types now record the
  cash denomination breakdown.
- CIF on denomination rows now sourced from the client (getCifNumber) instead
  of the account external id.
- Allow denominationBreakdown param in the FD/RD transaction validator.
- Cash Exchange backend: m_cash_exchange + m_cash_exchange_detail tables,
  entities, repositories and JAX-RS API with received==given validation;
  registered the 0013 migration in changelog-tenant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 18:36:00 +05:30
Jaanu423andClaude Opus 4.7 ee915e395a feat: Denomination Master backend - master, audit, soft delete, txn breakdown
- m_denomination_master CRUD API with duplicate (denomination+kind)
  validation, soft delete + restore, and a full audit trail
  (m_denomination_master_audit logs CREATE/UPDATE/ACTIVATE/DEACTIVATE/
  DELETE/RESTORE with snapshot, changes, user and timestamp)
- m_savings_txn_denomination: persist per-transaction cash denomination
  breakdown on savings deposit; allow denominationBreakdown request param
- Liquibase 0012_denomination_master registered in tenant changelog

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 11:16:52 +05:30
Jaanu423andClaude Sonnet 4.6 7d4f409202 feat: fix standing instructions GL accounting for current account transfers
- AccountTransfersWritePlatformServiceImpl:
  * Direct GL posting for current↔savings/current transfers:
    DR debit-side account GL (with correct account entity_id)
    CR credit-side account GL (with correct account entity_id)
  * Prefix current account txn_id with CA (not C) so
    JournalEntryReadPlatformServiceImpl joins m_current_account
    and shows correct current account number on GL entries
  * Suppress redundant savings deposit/withdrawal GL entries
    (skipAccountingPostings=true) when current account handles
    the full double-entry directly
  * Separate performCurrentWithdrawalForLoan for Current→Loan
    transfers (loan domain service handles the other GL leg)
  * Reuse existing AccountTransferDetails for SI recurring runs
    so transactions appear in list-account-transactions history

- SavingsAccountDomainService / SavingsAccountDomainServiceJpa:
  * New handleDeposit overload with skipAccountingPostings flag
  * handleWithdrawal respects SavingsTransactionBooleanValues
    .isSkipAccountingPostings() to suppress redundant GL entries

- SavingsTransactionBooleanValues:
  * Added skipAccountingPostings field + overloaded constructor

- AccountingProcessorHelper:
  * New createDirectTransferJournalEntriesForSavings() method
    creates DR and CR entries with separate productId/entityId
    so each GL line shows the correct account number

- JournalEntryReadPlatformServiceImpl:
  * Join both m_savings_account and m_current_account always
  * COALESCE(ca.account_no, sa.account_no) to resolve correct
    account number regardless of transaction_id prefix

- ExecuteStandingInstructionsTasklet:
  * Load existing AccountTransferDetails via repository so
    subsequent SI runs link to the same transfer detail record

- ExecuteStandingInstructionsConfig / AccountConfiguration:
  * Wire AccountTransferDetailRepository and
    AccountingProcessorHelper into the relevant beans

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 16:30:04 +05:30
Jaanu423andClaude Sonnet 4.6 2251fd2259 feat: current account standing instructions - full backend support
- StandingInstructionData: rename conflicting Lombok getters (getInstructionType,
  getRecurrenceType, getRecurrenceFrequency, getFromAccountType, getToAccountType,
  getTransferType) to domain enum methods so Jackson serializes EnumOptionData fields
  as {id, code, value} objects instead of plain strings
- AccountTransfersWritePlatformServiceImpl: add current account transfer support for
  all 4 missing cases (Current->Savings, Savings->Current, Current->Current,
  Current->Loan) with performCurrentWithdrawal/performCurrentDeposit helpers
- AccountConfiguration: wire CurrentAccountRepository and CurrentAccountTransactionRepository
  into AccountTransfersWritePlatformService bean
- StandingInstructionApiResource: fix getValue() type mismatch after getter rename
- ExecuteStandingInstructionsTasklet: update to use renamed enum accessor methods
- PortfolioAccountType: add CURRENT(3) type support
- DB migration: 0301_add_current_account_to_transfer_details.xml adds
  from_current_account_id and to_current_account_id columns to transfer details table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 10:55:35 +05:30
AdityaandClaude Opus 4.7 45585ecc10 Fix family-member PUT 500; CORS POST 403; Hikari local password default
- ClientFamilyMembersWritePlatformServiceImpl#updateFamilyMember: guard
  maritalStatusId/genderId/professionId with != null instead of != 0 so a
  payload that omits these keys doesn't NPE when the boxed Long is unboxed.
- application.properties: fix the broken property name
  `fineract.security.cors.allowed-metho pas` -> `allowed-methods`. The typo
  left CORS allowed-methods empty, which made Spring reject every browser
  POST with "Invalid CORS request" 403 once the SPA sent an Origin header.
- application.properties: change the Hikari default password from 313863
  to root so the local devRun matches the tenant-DB default at line 49.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:07:24 +05:30
AdityaandClaude Opus 4.7 7dea88d30f Fix family-member PUT 500; CORS POST 403; Hikari local password default
- ClientFamilyMembersWritePlatformServiceImpl#updateFamilyMember: guard
  maritalStatusId/genderId/professionId with != null instead of != 0 so a
  payload that omits these keys doesn't NPE when the boxed Long is unboxed.
- application.properties: fix the broken property name
  `fineract.security.cors.allowed-metho pas` -> `allowed-methods`. The typo
  left CORS allowed-methods empty, which made Spring reject every browser
  POST with "Invalid CORS request" 403 once the SPA sent an Origin header.
- application.properties: change the Hikari default password from 313863
  to root so the local devRun matches the tenant-DB default at line 49.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:06:38 +05:30
Jaanu423 d32953ed76 Merge branch 'feature/account-charges' of https://git.zeptic.in/CBSNexora/JAVA-Backend-CBS-MAIN into feature/account-charges 2026-05-21 21:00:05 +05:30