feat(shares,tasks): centralized Additional Shares approval queue, remove unused Share Savings Debit
- Add Approval Center tab "Share Addition Requests": lists every pending additional-share tranche across all accounts (backed by the new /v1/shareadditionrequests endpoint), with a detail popup showing the board resolution and the route-specific proof of funding (voucher(s) for cash, or the linked savings account for savings). Approve/Reject call the same native approveadditionalshares/rejectadditionalshares commands the account-page buttons already used. - Remove "Debit from Savings" dialog/button and the "Share Savings Debit" Checker Inbox tab -- zero rows ever recorded on either tenant since it was built. - Remove "Approve Additional Shares"/"Reject Additional Shares" from the account-page menu now that every tranche is reviewed from the centralized queue instead. - Harden SharesButtonsConfiguration.removeButton(): a not-found name fed to splice(-1, 1) was quietly deleting the LAST button in the array instead of doing nothing -- removing the two menu entries above would otherwise have silently broken the rest of the Active-account button bar. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -424,45 +424,16 @@ export class CashierService {
|
||||
return this.http.post(`/shareadvancecollection/${collectionId}/apply`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this share account can be settled from the member's linked savings, and for how much.
|
||||
*
|
||||
* Reports a shortfall before the clerk raises anything, so the member can be told at the counter
|
||||
* rather than after a request has been submitted and has to be rejected.
|
||||
* @returns {Observable<any>} `{ eligible, reason, shareAmount, chargeAmount, totalRequired,
|
||||
* savingsAccountNo, savingsBalance }`.
|
||||
*/
|
||||
getShareSavingsDebitEligibility(shareAccountId: number): Observable<any> {
|
||||
return this.http.get(`/sharesavingsdebit/eligibility/${shareAccountId}`);
|
||||
/** Every additional-share tranche awaiting approval, across every share account. */
|
||||
getShareAdditionRequests(): Observable<any> {
|
||||
return this.http.get('/shareadditionrequests');
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a request to settle a share application by debiting the member's savings. Nothing moves
|
||||
* until a manager approves it — unlike the cash route, where the cashier's receipt is already the
|
||||
* second pair of eyes.
|
||||
* Full detail for one pending tranche — the list row plus route-specific proof of funding: the
|
||||
* voucher(s) behind a cash tranche, or the savings account already debited for a savings tranche.
|
||||
*/
|
||||
submitShareSavingsDebit(data: any): Observable<any> {
|
||||
return this.http.post('/sharesavingsdebit', data);
|
||||
}
|
||||
|
||||
/** Savings-debit requests, PENDING by default. */
|
||||
getShareSavingsDebitRequests(status?: string, shareAccountId?: number): Observable<any> {
|
||||
const params: string[] = [];
|
||||
if (status) {
|
||||
params.push(`status=${status}`);
|
||||
}
|
||||
if (shareAccountId) {
|
||||
params.push(`shareAccountId=${shareAccountId}`);
|
||||
}
|
||||
return this.http.get(`/sharesavingsdebit${params.length ? '?' + params.join('&') : ''}`);
|
||||
}
|
||||
|
||||
/** Debits the member's savings and issues the shares. Manager only, and not the submitting clerk. */
|
||||
approveShareSavingsDebit(id: number): Observable<any> {
|
||||
return this.http.post(`/sharesavingsdebit/${id}/approve`, {});
|
||||
}
|
||||
|
||||
rejectShareSavingsDebit(id: number, rejectionReason?: string): Observable<any> {
|
||||
return this.http.post(`/sharesavingsdebit/${id}/reject`, { rejectionReason });
|
||||
getShareAdditionRequest(transactionId: number): Observable<any> {
|
||||
return this.http.get(`/shareadditionrequests/${transactionId}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user