From 0832017508ac386c3d3218a46abb2646d9edb26a Mon Sep 17 00:00:00 2001 From: Nitesh Yadav Date: Sat, 1 Aug 2026 19:20:53 +0530 Subject: [PATCH] feat(investment,reconciliation): add Export to Excel across Investment, fix export popup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a shared Export to Excel utility (investment-export.ts) and wires it into every listing/report screen in the Investment module — Dashboard (break-up + allocation), Reports (all ~20 report shapes), Interest (per active tab), the FD/Bond/Share Holdings registers, and Masters (per active master tab). Entry/transaction forms intentionally have no export button. No sign-off is included here, matching the request to keep that feature reconciliation-only. Also fixes the Reconciliation export flow: the Prepared/Checked/Approved sign-off is now an optional one-off popup shown when "Export to Excel" is clicked (fields are blank by default and downloading works whether or not they're filled), replacing the earlier always-visible sign-off card. Also fixes three reconciliation reports (Sundry Dr/Cr, NEFT/RTGS, UDIR) whose labels contain "/" — an Excel-forbidden worksheet-name character — which was silently aborting their export. --- .../bond-investment.component.html | 5 + .../bond-investment.component.ts | 64 +++ .../fd-investment.component.html | 7 + .../fd-investment/fd-investment.component.ts | 64 +++ .../investment-dashboard.component.html | 7 + .../investment-dashboard.component.ts | 86 ++++ src/app/investment/investment-export.ts | 89 +++++ .../investment-interest.component.html | 5 + .../investment-interest.component.ts | 293 ++++++++++++++ .../investment-masters.component.html | 5 + .../investment-masters.component.ts | 253 ++++++++++++ .../investment-reports.component.html | 7 + .../investment-reports.component.ts | 366 ++++++++++++++++++ .../share-investment.component.html | 7 + .../share-investment.component.ts | 55 +++ .../reconciliation-report.component.html | 43 ++ .../reconciliation-report.component.ts | 172 ++++++++ .../reconciliation/reconciliation-shared.scss | 82 ++++ 18 files changed, 1610 insertions(+) create mode 100644 src/app/investment/investment-export.ts diff --git a/src/app/investment/bond-investment/bond-investment.component.html b/src/app/investment/bond-investment/bond-investment.component.html index 10f310bd8..d2561a1d6 100644 --- a/src/app/investment/bond-investment/bond-investment.component.html +++ b/src/app/investment/bond-investment/bond-investment.component.html @@ -25,6 +25,11 @@ } + @if (activeTab === 'holdings') { + + {{ generating ? 'Exporting…' : 'Export to Excel' }} + + } diff --git a/src/app/investment/bond-investment/bond-investment.component.ts b/src/app/investment/bond-investment/bond-investment.component.ts index de971e980..9b65964c2 100644 --- a/src/app/investment/bond-investment/bond-investment.component.ts +++ b/src/app/investment/bond-investment/bond-investment.component.ts @@ -43,6 +43,7 @@ import { yearsBetween, todayDDMMYYYY } from '../investment-data'; +import { exportWorkbook } from '../investment-export'; type BondType = 'GOVT_SECURITY' | 'NON_SLR' | 'BOND' | 'MUTUAL_FUND'; type BondTab = @@ -210,6 +211,7 @@ export class BondInvestmentComponent { readonly intTypeOptions = INT_TYPE_OPTIONS; readonly authorityOptions = AUTHORITY_OPTIONS; + generating = false; toastMsg = ''; toastVisible = false; private toastTimer: ReturnType | undefined; @@ -1092,6 +1094,68 @@ export class BondInvestmentComponent { return `inv-badge inv-badge--${h.status.toLowerCase()}`; } + // -------------------- Export to Excel (Holdings register) -------------------- + async exportExcel(): Promise { + this.generating = true; + try { + await exportWorkbook( + [ + { + sheetName: this.instrumentLabel(this.bondType), + title: `${this.instrumentLabel(this.bondType)} Holdings Register`, + subtitle: `As on ${this.asOnDate}`, + headers: [ + 'Cert No', + 'Script', + 'Party', + 'Units', + 'Face Value', + 'Rate', + 'Purchase Date', + 'Maturity Date', + 'Accrued Interest', + 'Maturity Value', + 'Status' + ], + widths: [ + 14, + 26, + 22, + 12, + 16, + 10, + 14, + 14, + 16, + 16, + 12 + ], + rows: this.holdingsForType.map((h) => [ + h.certNo, + h.scriptName, + h.party, + h.units, + h.faceValue, + h.interestRate, + h.purchaseDate, + h.maturityDate, + this.accrued(h), + this.maturity(h), + h.status + ]) + } + ], + `${this.instrumentLabel(this.bondType)}-Holdings-${this.asOnDate}` + ); + this.toast(`${this.instrumentLabel(this.bondType)} Holdings exported.`); + } catch (err) { + console.error('Bond Holdings export failed', err); + this.toast('Could not generate the workbook — please retry.'); + } finally { + this.generating = false; + } + } + private toast(msg: string): void { this.toastMsg = msg; this.toastVisible = true; diff --git a/src/app/investment/fd-investment/fd-investment.component.html b/src/app/investment/fd-investment/fd-investment.component.html index bac98204f..fffa89741 100644 --- a/src/app/investment/fd-investment/fd-investment.component.html +++ b/src/app/investment/fd-investment/fd-investment.component.html @@ -16,6 +16,13 @@ Part-Payment entries.
+ Fill in Prepared / Checked / Approved details if this copy needs them for the record — or leave them blank and + download straight away. +