feat(investment): Interest Entry screen with coupon and provision schedule
Replace the dummy interest calculation tab with the real Interest Entry: pick Type / Script / Deal No and Retrieve the holding's schedule from the backend - every half-yearly coupon and every 31 Mar / 30 Sep closing provision up to maturity, with days (30/360), gross interest, amount already booked, net income and the Dr/Cr entry per line. Display only; nothing is posted to GL yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -169,6 +169,14 @@ export class InvestmentService {
|
||||
return this.http.get<InvestmentPurchaseDto[]>('/investment/purchases');
|
||||
}
|
||||
|
||||
/** Coupon and 31 Mar / 30 Sep provision lines of a holding up to maturity (calculated, not posted). */
|
||||
getInterestSchedule(purchaseId: number, asOnDate?: string): Observable<InvestmentInterestScheduleDto> {
|
||||
const params = asOnDate ? `?asOnDate=${encodeURIComponent(asOnDate)}` : '';
|
||||
return this.http.get<InvestmentInterestScheduleDto>(
|
||||
`/investment/purchases/${purchaseId}/interest-schedule${params}`
|
||||
);
|
||||
}
|
||||
|
||||
createPurchase(body: object): Observable<{ resourceId: number; resourceIdentifier: string }> {
|
||||
return this.http.post<{ resourceId: number; resourceIdentifier: string }>('/investment/purchases', body);
|
||||
}
|
||||
@@ -292,6 +300,42 @@ export function toHolding(p: InvestmentPurchaseDto): InvestmentHolding {
|
||||
};
|
||||
}
|
||||
|
||||
/** One line of a holding's interest schedule (see InvestmentInterestScheduleData in the backend). */
|
||||
export interface InvestmentInterestRowDto {
|
||||
type: 'COUPON' | 'PROVISION';
|
||||
intDate: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
days: number;
|
||||
grossInterest: number;
|
||||
alreadyBooked: number;
|
||||
amount: number;
|
||||
due: boolean;
|
||||
}
|
||||
|
||||
export interface InvestmentInterestScheduleDto {
|
||||
purchaseId: number;
|
||||
dealNo: string;
|
||||
certNo: string;
|
||||
scriptCode: string;
|
||||
scriptDesc: string;
|
||||
faceValue: number;
|
||||
unitValue: number;
|
||||
balanceUnits: number;
|
||||
purchaseRate: number;
|
||||
bookValue: number;
|
||||
intRate: number;
|
||||
dealDate: string;
|
||||
lastIntDate: string;
|
||||
maturityDate: string;
|
||||
purchasedAccruedInterest: number;
|
||||
couponPerHalfYear: number;
|
||||
asOnDate: string;
|
||||
interestGlCode: string;
|
||||
interestGlName: string;
|
||||
rows: InvestmentInterestRowDto[];
|
||||
}
|
||||
|
||||
/** The first validation / domain-rule message from a Fineract error response, for a toast. */
|
||||
export function apiErrorMessage(err: unknown): string {
|
||||
const e = err as HttpErrorResponse;
|
||||
|
||||
Reference in New Issue
Block a user