Files
cbsnexora/src/app/letter-mgmt/certificates/share-certificate/share-certificate.component.ts
T
nitesh b03efef84e fix(letter-mgmt): make share certificate bank identity dynamic and fix broken printing
- Certificate PDFs, the preview dialog, and both share-certificate list views
  (demo + live) now pull bank name/address/reg no/seal text from the
  Institution Profile instead of a hardcoded "Nexora" identity.
- Certificate preview dialog print CSS was clipped to the dialog's on-screen
  scroll viewport (maxHeight config); switched to position:fixed + unclipped
  overlay ancestors so the full certificate prints, not just a border sliver.
- Global print stylesheet now also hides the app shell's real 2-row nav menu
  (.main-header/.kpi-ticker, not routed through <mifosx-toolbar>) and frees
  the CDK sidenav/tab-body scroll clipping, so printing any page no longer
  captures the nav chrome or gets cut off to one screen's height.
2026-09-14 16:58:18 +05:30

291 lines
8.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Copyright since 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { Component, inject, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import {
CertificatePreviewDialogComponent,
CertificatePreviewDialogData
} from '../certificate-preview-dialog/certificate-preview-dialog.component';
import { downloadShareCertificatePdf, setBankIdentity } from '../certificate-pdf';
import { DscSignService } from '../../dsc-sign-dialog/dsc-sign.service';
import { OrganizationService } from '../../../organization/organization.service';
import { RealShareAccountsViewComponent } from './real-share-accounts-view/real-share-accounts-view.component';
export type ShareClass = 'ORDINARY' | 'PREFERENCE';
export interface ShareCertificateRecord {
certificateNo: string;
folioNo: string;
memberId: string;
memberName: string;
memberPan: string;
memberAddress: string;
branch: string;
joiningDate: string;
shareClass: ShareClass;
shareCount: number;
faceValue: number;
issueDate: string;
/** Distinct numeric range of share numbers held (e.g. 1001–1100). */
shareNoFrom: number;
shareNoTo: number;
/** Total dividend received since joining. */
dividendYtd: number;
}
@Component({
selector: 'mifosx-share-certificate',
templateUrl: './share-certificate.component.html',
styleUrls: ['../certificates.shared.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
CommonModule,
FormsModule,
FaIconComponent,
MatTooltip,
RealShareAccountsViewComponent
]
})
export class ShareCertificateComponent implements OnInit {
private dialog = inject(MatDialog);
private snack = inject(MatSnackBar);
private dscSign = inject(DscSignService);
private organizationService = inject(OrganizationService);
/** Toggles between the static sample table and the live m_share_account view. */
viewMode: 'demo' | 'real' = 'demo';
// ── Filters ──
search = '';
classFilter: '' | ShareClass = '';
branchFilter = '';
records: ShareCertificateRecord[] = [];
readonly classOptions: { value: ShareClass; label: string }[] = [
{ value: 'ORDINARY', label: 'Ordinary' },
{ value: 'PREFERENCE', label: 'Preference' }
];
ngOnInit(): void {
this.records = seedShareCertificates();
// Download here builds the PDF directly, without necessarily opening the preview dialog first,
// so this list must set the shared bank identity itself.
this.organizationService.getInstitutionProfile().subscribe({
next: (profile: any) => setBankIdentity(profile || {}),
error: () => {}
});
}
// ── Derived list ──
get filteredRecords(): ShareCertificateRecord[] {
const q = this.search.trim().toLowerCase();
const branch = this.branchFilter.trim().toLowerCase();
return this.records.filter((r) => {
if (this.classFilter && r.shareClass !== this.classFilter) return false;
if (branch && !r.branch.toLowerCase().includes(branch)) return false;
if (!q) return true;
return (
r.certificateNo.toLowerCase().includes(q) ||
r.folioNo.toLowerCase().includes(q) ||
r.memberId.toLowerCase().includes(q) ||
r.memberName.toLowerCase().includes(q) ||
r.memberPan.toLowerCase().includes(q)
);
});
}
get branchOptions(): string[] {
return Array.from(new Set(this.records.map((r) => r.branch))).sort();
}
classLabel(c: ShareClass): string {
return this.classOptions.find((o) => o.value === c)?.label || c;
}
totalShares(): number {
return this.filteredRecords.reduce((s, r) => s + r.shareCount, 0);
}
totalShareValue(): number {
return this.filteredRecords.reduce((s, r) => s + r.shareCount * r.faceValue, 0);
}
// ── Actions ──
clearFilters(): void {
this.search = '';
this.classFilter = '';
this.branchFilter = '';
}
viewCertificate(r: ShareCertificateRecord): void {
const data: CertificatePreviewDialogData = {
kind: 'share',
shareCertificate: r
};
this.dialog.open(CertificatePreviewDialogComponent, {
width: '880px',
maxWidth: '96vw',
maxHeight: '92vh',
autoFocus: false,
panelClass: 'cert-preview-dialog',
data
});
}
downloadCertificate(r: ShareCertificateRecord): void {
this.dscSign.promptThenDownload(
{
title: 'Share Certificate',
reference: `${r.certificateNo} · Folio ${r.folioNo} · ${r.memberName}`,
filename: `Share-Certificate-${r.certificateNo}.pdf`
},
(dsc) => downloadShareCertificatePdf(r, dsc)
);
}
/** Switches between the static sample table and the live m_share_account view. */
toggleViewMode(): void {
this.viewMode = this.viewMode === 'demo' ? 'real' : 'demo';
}
}
// ───────────────────── Mock seed (top-level export) ─────────────────────
export function seedShareCertificates(): ShareCertificateRecord[] {
return [
{
certificateNo: 'SC-2024-000123',
folioNo: 'F-00482',
memberId: 'MBR000482',
memberName: 'Rohan S. Mehta',
memberPan: 'ABCPM1234E',
memberAddress: 'Flat 902, Skyline Apt, Andheri (E), Mumbai 400069',
branch: 'Mumbai — Andheri (E)',
joiningDate: '2018-04-22',
shareClass: 'ORDINARY',
shareCount: 100,
faceValue: 100,
issueDate: '2018-04-22',
shareNoFrom: 48201,
shareNoTo: 48300,
dividendYtd: 7200
},
{
certificateNo: 'SC-2024-000124',
folioNo: 'F-00713',
memberId: 'MBR000713',
memberName: 'Anita Verma',
memberPan: 'EFGHV5678A',
memberAddress: 'B-12, Connaught Pl, New Delhi 110001',
branch: 'New Delhi — Connaught Place',
joiningDate: '2019-08-11',
shareClass: 'ORDINARY',
shareCount: 50,
faceValue: 100,
issueDate: '2019-08-11',
shareNoFrom: 71301,
shareNoTo: 71350,
dividendYtd: 3000
},
{
certificateNo: 'SC-2024-000125',
folioNo: 'F-01102',
memberId: 'MBR001102',
memberName: 'Karthik Rao',
memberPan: 'PQRSR2233Z',
memberAddress: '24, MG Road, Bengaluru 560001',
branch: 'Bengaluru — MG Road',
joiningDate: '2020-02-04',
shareClass: 'ORDINARY',
shareCount: 200,
faceValue: 100,
issueDate: '2020-02-04',
shareNoFrom: 110201,
shareNoTo: 110400,
dividendYtd: 14400
},
{
certificateNo: 'SC-2024-000126',
folioNo: 'F-01277',
memberId: 'MBR001277',
memberName: 'Madhavi Singh',
memberPan: 'TUVWS3344K',
memberAddress: 'D-5, Greater Kailash, New Delhi 110048',
branch: 'New Delhi — Connaught Place',
joiningDate: '2017-11-19',
shareClass: 'PREFERENCE',
shareCount: 75,
faceValue: 1000,
issueDate: '2017-11-19',
shareNoFrom: 12721,
shareNoTo: 12795,
dividendYtd: 67500
},
{
certificateNo: 'SC-2024-000127',
folioNo: 'F-01498',
memberId: 'MBR001498',
memberName: 'Vikram Joshi',
memberPan: 'LMNOJ9988X',
memberAddress: 'Office 3B, Koregaon Park Road, Pune 411001',
branch: 'Pune — Koregaon Park',
joiningDate: '2016-06-30',
shareClass: 'PREFERENCE',
shareCount: 250,
faceValue: 1000,
issueDate: '2016-06-30',
shareNoFrom: 14981,
shareNoTo: 15230,
dividendYtd: 225000
},
{
certificateNo: 'SC-2024-000128',
folioNo: 'F-01902',
memberId: 'MBR001902',
memberName: 'Lakshmi Naidu',
memberPan: 'XYZAN7788Q',
memberAddress: 'Plot 14, Road No. 3, Banjara Hills, Hyderabad 500034',
branch: 'Hyderabad — Banjara Hills',
joiningDate: '2021-03-15',
shareClass: 'ORDINARY',
shareCount: 30,
faceValue: 100,
issueDate: '2021-03-15',
shareNoFrom: 190201,
shareNoTo: 190230,
dividendYtd: 1800
},
{
certificateNo: 'SC-2024-000129',
folioNo: 'F-02011',
memberId: 'MBR002011',
memberName: 'Arjun Banerjee',
memberPan: 'TUVWB4455F',
memberAddress: '42, Park Street, Kolkata 700016',
branch: 'Kolkata — Park Street',
joiningDate: '2021-09-08',
shareClass: 'ORDINARY',
shareCount: 40,
faceValue: 100,
issueDate: '2021-09-08',
shareNoFrom: 201101,
shareNoTo: 201140,
dividendYtd: 2400
}
];
}