DDS: agent collection entry screen, per-agent GL account, maturity auto close
The Daily Transaction Entry screen no longer composes a Party Tran. An agent records their own round elsewhere; this screen reads back what they wrote down, shows what it adds up to, and settles the day once a clerk has counted the cash against it. Nothing is typed here and nothing is edited - what settles is what the entries say, to the rupee. Agent Master now asks which ledger account the agent's collections pass through, one agent to an account, and offers only the accounts that can carry them. The DDS scheme product is kept out of the agent's own savings list for the same reason the server refuses it: debits are blocked on those accounts, so commission paid into one would go in and never come out. The DDS product carries a Maturity Auto Close setting, asked as Yes/No to match the Auto Interest Post question directly above it, and Batch Processing offers the run that applies it. Also: the report viewer stops printing two money columns ungrouped and stops totalling a column that holds a word, and an agent's birth date cannot be picked later than eighteen years ago. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
57a61b3057
commit
e2eff9914f
@@ -272,6 +272,17 @@ export class OrganizationService {
|
||||
return this.http.get('/dds/parties');
|
||||
}
|
||||
|
||||
/**
|
||||
* The parties a given agent collects for — what the daily transaction screen works from, since
|
||||
* it handles one agent's round at a time.
|
||||
*
|
||||
* @param {string | number} agentId Agent ID.
|
||||
* @returns {Observable<any>} That agent's DDS Parties.
|
||||
*/
|
||||
getPartiesOfAgent(agentId: string | number): Observable<any> {
|
||||
return this.http.get('/dds/parties', { params: new HttpParams().set('agentId', String(agentId)) });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | number} partyId Party ID.
|
||||
* @returns {Observable<any>} DDS Party.
|
||||
@@ -306,6 +317,65 @@ export class OrganizationService {
|
||||
return this.http.post(`/dds/parties/${partyId}?command=close`, closeCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* The DDS accounts whose term has run out and which are still open - the branch's list of closures
|
||||
* waiting to be done. Nothing closes itself: a matured account is money the bank owes the customer,
|
||||
* and where it goes has to be agreed with them.
|
||||
*
|
||||
* @returns {Observable<any>} Accounts due for closure, oldest maturity first.
|
||||
*/
|
||||
getPartiesDueForClosure(): Observable<any> {
|
||||
return this.http.get('/dds/parties/dueforclosure');
|
||||
}
|
||||
|
||||
/**
|
||||
* The customer's own accounts a DDS maturity can be paid into - active savings accounts of theirs,
|
||||
* with fixed and recurring deposits and their other DDS scheme accounts left out.
|
||||
*
|
||||
* The server applies the same conditions the payout itself does, so this list can never offer a
|
||||
* choice that is then refused on save. Filtering here instead meant the two drifted apart: the
|
||||
* accounts on offer once included a scheme account of a party that had already closed.
|
||||
*
|
||||
* @param {string | number} clientId Client ID.
|
||||
* @returns {Observable<any>} id, accountNo, productName and balance for each.
|
||||
*/
|
||||
getCreditableAccounts(clientId: string | number): Observable<any> {
|
||||
return this.http.get('/dds/parties/creditaccounts', { params: { clientId: String(clientId) } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Pays a matured DDS account out and closes it. What is paid is what the account holds, not the
|
||||
* figure quoted at opening.
|
||||
*
|
||||
* @param {string | number} partyId Party ID.
|
||||
* @param {any} payoutCommand { toSavingsAccountNo } - another savings account of the same customer
|
||||
* to move the money into. Omit it when they have none here: the money is then parked in the
|
||||
* matured-deposits payable account for the branch to send on to their account at another bank.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
payOutParty(partyId: string | number, payoutCommand: any): Observable<any> {
|
||||
return this.http.post(`/dds/parties/${partyId}?command=payout`, payoutCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a DDS account before its term is up, and pays out what is left - one act, unlike a
|
||||
* maturity payout, which leaves the account open for the clerk to close separately.
|
||||
*
|
||||
* @param {string | number} partyId Party ID.
|
||||
* @param {any} closeCommand { shortfallBorneBy, closeDate, dateFormat, locale, toSavingsAccountNo? }.
|
||||
* closeDate, dateFormat and locale go up exactly as they do on an ordinary close.
|
||||
* shortfallBorneBy is mandatory
|
||||
* and is CUSTOMER (their interest is recalculated at the scheme's reduced rate and the
|
||||
* difference taken back) or AGENT (the customer keeps a full month's interest and the agent
|
||||
* funds the days left in it). The agent is charged a share of their commission either way.
|
||||
* toSavingsAccountNo works as it does for a payout. The lock-in, the rate reduction and the
|
||||
* agent's share come from the scheme and are applied by the server.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
prematureCloseParty(partyId: string | number, closeCommand: any): Observable<any> {
|
||||
return this.http.post(`/dds/parties/${partyId}?command=prematureclose`, closeCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} transaction Daily transaction batch (PARTY_TRAN collections or a WITHDRAW_DEPOSITE transfer) to post.
|
||||
* @returns {Observable<any>}
|
||||
@@ -314,6 +384,39 @@ export class OrganizationService {
|
||||
return this.http.post('/dds/partytransactions', transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* What an agent wrote down on their round for a date, with what it adds up to.
|
||||
*
|
||||
* The counter reads it to count cash against; the agent's own screen shows it back as the record
|
||||
* of their round. One call for both, so the two can never disagree about the same day.
|
||||
*/
|
||||
getAgentCollectionDay(agentId: any, entryDate: string): Observable<any> {
|
||||
return this.http.get(`/dds/collectionentries?agentId=${agentId}&entryDate=${entryDate}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an agent's outstanding entries for a date into real credits - all of them, together.
|
||||
*
|
||||
* No amount is sent. What settles is what the entries say, to the rupee: a figure typed at the
|
||||
* counter would be a second opinion about a total the entries already give.
|
||||
*/
|
||||
settleAgentCollections(settlement: any): Observable<any> {
|
||||
return this.http.post('/dds/collectionentries/settle', settlement);
|
||||
}
|
||||
|
||||
/**
|
||||
* An agent's DDS transactions. The daily entry screen uses this to show what has already been
|
||||
* keyed for the agent today, so the same collection book is not entered twice.
|
||||
*
|
||||
* @param {string | number} agentId Agent ID.
|
||||
* @returns {Observable<any>} That agent's transactions.
|
||||
*/
|
||||
getPartyTransactionsOfAgent(agentId: string | number): Observable<any> {
|
||||
return this.http.get('/dds/partytransactions', {
|
||||
params: new HttpParams().set('agentId', String(agentId))
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Observable<any>} DDS Commission Slabs data
|
||||
*/
|
||||
@@ -329,6 +432,18 @@ export class OrganizationService {
|
||||
return this.http.post('/dds/commissionslabs', { slabs });
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrects one saved commission slab. The backend re-checks the corrected range against the other
|
||||
* slabs of its type and refuses an overlap.
|
||||
*
|
||||
* @param {string | number} slabId Commission slab ID.
|
||||
* @param {any} slab The corrected slab.
|
||||
* @returns {Observable<any>} Command result.
|
||||
*/
|
||||
updateCommissionSlab(slabId: string | number, slab: any): Observable<any> {
|
||||
return this.http.put(`/dds/commissionslabs/${slabId}`, slab);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} batch Batch run filters (jobType, branchScope, jobDate, agentFrom/To, partyFrom/To) to generate a preview for.
|
||||
* @returns {Observable<any>}
|
||||
@@ -345,6 +460,24 @@ export class OrganizationService {
|
||||
return this.http.get(`/dds/batchruns/${batchRunId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Observable<any>} Every batch run, most recent first — who ran what, and whether it was posted.
|
||||
*/
|
||||
getDdsBatchRuns(): Observable<any> {
|
||||
return this.http.get('/dds/batchruns');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the relationship with an agent. Refused while they still have accounts assigned, hold
|
||||
* collected cash, or are owed commission — distinct from deactivating, which is never refused.
|
||||
*
|
||||
* @param {string | number} agentId Agent ID.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
closeAgent(agentId: string | number): Observable<any> {
|
||||
return this.http.post(`/dds/agents/${agentId}`, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | number} batchRunId Batch run ID to post - applies exactly the rows it previewed.
|
||||
* @returns {Observable<any>}
|
||||
|
||||
Reference in New Issue
Block a user