fix(cashier): realistic branch-aware account numbers, dynamic date tags in summary report
Account No now always holds a genuine reference for its transaction type (customer account, GL/facility code, IFSC, DD/PO/TDS/GST/cheque ref, or UTR/RRN/UMRN for RTGS/NEFT/UPI/ATM/NACH) instead of a plain description. Branch 2's view derives its own valid-format account numbers and IFSC codes by shifting the numeric segment, rather than tagging a "BR2-" prefix onto Branch 1's values, which looked fake for standardized formats. Voucher/reference numbers' baked-in "2607" (Jul 2026) tag is now derived from the real current date at render time, so it won't go stale next month. feat(clients): auto-calculate Monthly/Annual Income and Turnover Typing either the monthly or annual figure now fills in the other at a 12x ratio (rounded to 2 decimals, no trailing ".00" on whole numbers). Guarded against firing during prefillForEdit()'s initial load of an existing client's independently-saved values, so editing doesn't silently overwrite historical data that wasn't an exact 12x match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+7
-8
@@ -219,7 +219,8 @@
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Voucher / Ref No</th>
|
||||
<th>Account / Reference</th>
|
||||
<th>Account No</th>
|
||||
<th>Account Name / Reference</th>
|
||||
<th>Particulars</th>
|
||||
<th class="num col-out">Debit</th>
|
||||
<th class="num col-in">Credit</th>
|
||||
@@ -230,12 +231,10 @@
|
||||
<tr>
|
||||
<td>{{ asOnDate }}</td>
|
||||
<td>
|
||||
<span class="pg-chip">{{ t.voucherNo }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div>{{ t.accountName }}</div>
|
||||
<div class="cctr-subtext">{{ t.accountNo }}</div>
|
||||
<span class="pg-chip">{{ display(t.voucherNo) }}</span>
|
||||
</td>
|
||||
<td>{{ display(t.accountNo) }}</td>
|
||||
<td>{{ t.accountName }}</td>
|
||||
<td>{{ t.particulars }}</td>
|
||||
<td class="num col-out">
|
||||
@if (t.debit > 0) {
|
||||
@@ -250,13 +249,13 @@
|
||||
</tr>
|
||||
} @empty {
|
||||
<tr>
|
||||
<td colspan="6" class="pg-empty">No transactions for this filter.</td>
|
||||
<td colspan="7" class="pg-empty">No transactions for this filter.</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="cctr-total-row">
|
||||
<td colspan="4">Total</td>
|
||||
<td colspan="5">Total</td>
|
||||
<td class="num">₹{{ txnTotal(filteredTxns, 'debit') | number: '1.2-2' }}</td>
|
||||
<td class="num">₹{{ txnTotal(filteredTxns, 'credit') | number: '1.2-2' }}</td>
|
||||
</tr>
|
||||
|
||||
+66
-32
@@ -34,6 +34,9 @@ interface Branch {
|
||||
name: string;
|
||||
/** Relative size vs the base dataset below (which represents the Head Office main branch, scale 1). */
|
||||
scale: number;
|
||||
/** Numeric offset used to derive this branch's own account numbers / IFSC serials — keeps the
|
||||
* standard 12-digit / IFSC format intact instead of just tagging a prefix onto Branch 1's values. */
|
||||
acctShift: number;
|
||||
}
|
||||
|
||||
type TabKey = 'cash' | 'transfer' | 'clearing' | 'digital';
|
||||
@@ -84,8 +87,8 @@ export class CashClearingTransferSummaryComponent {
|
||||
* of its own Transaction Details).
|
||||
*/
|
||||
branches: Branch[] = [
|
||||
{ code: 'BR1', name: 'Branch 1', scale: 1 },
|
||||
{ code: 'BR2', name: 'Branch 2', scale: 0.7 }
|
||||
{ code: 'BR1', name: 'Branch 1', scale: 1, acctShift: 0 },
|
||||
{ code: 'BR2', name: 'Branch 2', scale: 0.7, acctShift: 400 }
|
||||
];
|
||||
|
||||
/** 'ALL' = consolidated across both branches; otherwise a Branch.code. Only meaningful for Head Office users. */
|
||||
@@ -131,7 +134,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0141',
|
||||
accountNo: 'Teller-01',
|
||||
accountNo: 'TIL-0001',
|
||||
accountName: 'Teller Counter 1 Cash Deposits (Aggregated)',
|
||||
particulars: 'Cash Deposit - Savings/Current Accounts',
|
||||
debit: 0,
|
||||
@@ -140,7 +143,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0142',
|
||||
accountNo: 'Teller-02',
|
||||
accountNo: 'TIL-0002',
|
||||
accountName: 'Teller Counter 2 Cash Deposits (Aggregated)',
|
||||
particulars: 'Cash Deposit - Savings/Current Accounts',
|
||||
debit: 0,
|
||||
@@ -176,7 +179,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0146',
|
||||
accountNo: 'Branch ATM',
|
||||
accountNo: 'ATM-0001',
|
||||
accountName: 'ATM Excess Cash Retraction',
|
||||
particulars: 'Excess Cash Surrendered by ATM to Vault',
|
||||
debit: 0,
|
||||
@@ -203,7 +206,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0149',
|
||||
accountNo: 'Branch ATM',
|
||||
accountNo: 'ATM-0001',
|
||||
accountName: 'ATM 1 Cash Loading',
|
||||
particulars: 'Vault to ATM Cash Transfer',
|
||||
debit: 700000,
|
||||
@@ -212,7 +215,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0150',
|
||||
accountNo: 'Extension Counter ATM',
|
||||
accountNo: 'ATM-0002',
|
||||
accountName: 'ATM 2 Cash Loading',
|
||||
particulars: 'Vault to ATM Cash Transfer',
|
||||
debit: 500000,
|
||||
@@ -239,7 +242,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0153',
|
||||
accountNo: 'Currency Chest',
|
||||
accountNo: 'CCH-0001',
|
||||
accountName: 'Currency Chest Remittance',
|
||||
particulars: 'Surplus Cash Remitted to Currency Chest',
|
||||
debit: 400000,
|
||||
@@ -266,7 +269,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: '100001',
|
||||
voucherNo: 'CSH/2607/0156',
|
||||
accountNo: 'Vault',
|
||||
accountNo: 'VLT-0001',
|
||||
accountName: 'Vault Denomination Exchange Adjustment',
|
||||
particulars: 'Shortage Adjustment - Denomination Exchange',
|
||||
debit: 205000,
|
||||
@@ -1171,7 +1174,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'UPI',
|
||||
voucherNo: 'UPI/2607/44521',
|
||||
accountNo: 'NPCI-UPI-SETL-IN-01',
|
||||
accountNo: 'RRN-UPI26073100145',
|
||||
accountName: 'UPI Inward Settlement - Morning Batch (00:00-12:00)',
|
||||
particulars: 'UPI Collect - Merchant/P2P Inward (Aggregated)',
|
||||
debit: 0,
|
||||
@@ -1180,7 +1183,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'UPI',
|
||||
voucherNo: 'UPI/2607/44522',
|
||||
accountNo: 'NPCI-UPI-SETL-IN-02',
|
||||
accountNo: 'RRN-UPI26073100289',
|
||||
accountName: 'UPI Inward Settlement - Afternoon Batch (12:00-18:00)',
|
||||
particulars: 'UPI Collect - Merchant/P2P Inward (Aggregated)',
|
||||
debit: 0,
|
||||
@@ -1189,7 +1192,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'UPI',
|
||||
voucherNo: 'UPI/2607/44523',
|
||||
accountNo: 'NPCI-UPI-SETL-IN-03',
|
||||
accountNo: 'RRN-UPI26073100356',
|
||||
accountName: 'UPI Inward Settlement - Evening Batch (18:00-24:00)',
|
||||
particulars: 'UPI Collect - Merchant/P2P Inward (Aggregated)',
|
||||
debit: 0,
|
||||
@@ -1198,7 +1201,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'UPI',
|
||||
voucherNo: 'UPI/2607/44524',
|
||||
accountNo: 'NPCI-UPI-SETL-OUT-01',
|
||||
accountNo: 'RRN-UPI26073100478',
|
||||
accountName: 'UPI Outward Settlement - Morning Batch (00:00-12:00)',
|
||||
particulars: 'UPI Pay - Merchant/P2P Outward (Aggregated)',
|
||||
debit: 1850000,
|
||||
@@ -1207,7 +1210,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'UPI',
|
||||
voucherNo: 'UPI/2607/44525',
|
||||
accountNo: 'NPCI-UPI-SETL-OUT-02',
|
||||
accountNo: 'RRN-UPI26073100512',
|
||||
accountName: 'UPI Outward Settlement - Afternoon Batch (12:00-18:00)',
|
||||
particulars: 'UPI Pay - Merchant/P2P Outward (Aggregated)',
|
||||
debit: 2050000,
|
||||
@@ -1216,7 +1219,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'UPI',
|
||||
voucherNo: 'UPI/2607/44526',
|
||||
accountNo: 'NPCI-UPI-SETL-OUT-03',
|
||||
accountNo: 'RRN-UPI26073100634',
|
||||
accountName: 'UPI Outward Settlement - Evening Batch (18:00-24:00)',
|
||||
particulars: 'UPI Pay - Merchant/P2P Outward (Aggregated)',
|
||||
debit: 1490000,
|
||||
@@ -1226,7 +1229,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'ATM',
|
||||
voucherNo: 'ATM/2607/9081',
|
||||
accountNo: 'ATM-SETL-CR-01',
|
||||
accountNo: 'RRN-ATM26073100118',
|
||||
accountName: 'ATM Cash Deposits - Own Branch ATM (Aggregated)',
|
||||
particulars: 'ATM Cash Deposit - Own Branch ATM',
|
||||
debit: 0,
|
||||
@@ -1235,7 +1238,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'ATM',
|
||||
voucherNo: 'ATM/2607/9082',
|
||||
accountNo: 'ATM-SETL-CR-02',
|
||||
accountNo: 'RRN-ATM26073100224',
|
||||
accountName: 'ATM Cash Deposits - Extension Counter ATM (Aggregated)',
|
||||
particulars: 'ATM Cash Deposit - Extension Counter ATM',
|
||||
debit: 0,
|
||||
@@ -1244,7 +1247,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'ATM',
|
||||
voucherNo: 'ATM/2607/9083',
|
||||
accountNo: 'ATM-SETL-DR-01',
|
||||
accountNo: 'RRN-ATM26073100337',
|
||||
accountName: 'ATM Cash Withdrawals - Own Branch ATM (Aggregated)',
|
||||
particulars: 'ATM Cash Withdrawal - Own Branch ATM',
|
||||
debit: 420000,
|
||||
@@ -1253,7 +1256,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'ATM',
|
||||
voucherNo: 'ATM/2607/9084',
|
||||
accountNo: 'ATM-SETL-DR-02',
|
||||
accountNo: 'RRN-ATM26073100449',
|
||||
accountName: 'ATM Cash Withdrawals - Other Bank ATM, NFS Switch (Aggregated)',
|
||||
particulars: 'ATM Cash Withdrawal - Other Bank ATM (NFS)',
|
||||
debit: 265000,
|
||||
@@ -1263,7 +1266,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'NACH',
|
||||
voucherNo: 'NACH/2607/3304',
|
||||
accountNo: 'NACH-SETL-CR-01',
|
||||
accountNo: 'UMRN-NACH26073100112',
|
||||
accountName: 'NACH Credits - Corporate Payroll Disbursement (Aggregated)',
|
||||
particulars: 'NACH Credit - Salary Disbursement Batch',
|
||||
debit: 0,
|
||||
@@ -1272,7 +1275,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'NACH',
|
||||
voucherNo: 'NACH/2607/3305',
|
||||
accountNo: 'NACH-SETL-CR-02',
|
||||
accountNo: 'UMRN-NACH26073100156',
|
||||
accountName: 'NACH Credits - Government Subsidy (DBT) Disbursement (Aggregated)',
|
||||
particulars: 'NACH Credit - Subsidy Disbursement Batch',
|
||||
debit: 0,
|
||||
@@ -1281,7 +1284,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'NACH',
|
||||
voucherNo: 'NACH/2607/3306',
|
||||
accountNo: 'NACH-SETL-DR-01',
|
||||
accountNo: 'UMRN-NACH26073100198',
|
||||
accountName: 'NACH Debits - Retail Loan EMI Collection (Aggregated)',
|
||||
particulars: 'NACH Debit - Loan EMI Collection Batch',
|
||||
debit: 560000,
|
||||
@@ -1290,7 +1293,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
{
|
||||
glCode: 'NACH',
|
||||
voucherNo: 'NACH/2607/3307',
|
||||
accountNo: 'NACH-SETL-DR-02',
|
||||
accountNo: 'UMRN-NACH26073100233',
|
||||
accountName: 'NACH Debits - Gold Loan EMI Collection (Aggregated)',
|
||||
particulars: 'NACH Debit - Gold Loan EMI Collection Batch',
|
||||
debit: 305000,
|
||||
@@ -1298,9 +1301,14 @@ export class CashClearingTransferSummaryComponent {
|
||||
}
|
||||
];
|
||||
|
||||
/** YYMM tag baked into every dummy voucher/reference number (e.g. "2607" for Jul 2026) — kept
|
||||
* in sync with the real current date so it never goes stale in a future month. */
|
||||
private dateTag = '2607';
|
||||
|
||||
constructor() {
|
||||
const d = new Date();
|
||||
this.asOnDate = `${String(d.getDate()).padStart(2, '0')}-${String(d.getMonth() + 1).padStart(2, '0')}-${d.getFullYear()}`;
|
||||
this.dateTag = `${String(d.getFullYear()).slice(-2)}${String(d.getMonth() + 1).padStart(2, '0')}`;
|
||||
|
||||
const creds = this.auth.getCredentials();
|
||||
this.isHeadOffice = this.auth.isHeadOfficeUser();
|
||||
@@ -1318,6 +1326,11 @@ export class CashClearingTransferSummaryComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/** Renders a voucher/reference number with the baked-in "2607" swapped for today's real YYMM tag. */
|
||||
display(value: string): string {
|
||||
return (value || '').replace(/2607/g, this.dateTag);
|
||||
}
|
||||
|
||||
private baseRowsFor(tab: TabKey): SummaryRow[] {
|
||||
switch (tab) {
|
||||
case 'cash':
|
||||
@@ -1355,15 +1368,36 @@ export class CashClearingTransferSummaryComponent {
|
||||
return rows.map((r) => ({ ...r, opening: this.roundAmt(r.opening * factor) }));
|
||||
}
|
||||
|
||||
private scaleTxns(txns: TxnRow[], factor: number, branchTag?: string): TxnRow[] {
|
||||
if (factor === 1) {
|
||||
/**
|
||||
* Re-derives a customer account number or bank IFSC code for a different branch by shifting
|
||||
* its numeric segment — NOT by tagging a prefix onto Branch 1's value, since real account
|
||||
* numbers and IFSC codes have a fixed, standard shape and a "BR2-" prefix would look fake.
|
||||
* Everything else (UTR/RRN/UMRN/DD/PO/TDS/GST/cheque/branch/settlement references) keeps the
|
||||
* simpler branch-tag prefix, since those are already free-form internal reference formats.
|
||||
*/
|
||||
private scaleAccountNo(accountNo: string, branch: Branch): string {
|
||||
if (/^\d{12}$/.test(accountNo)) {
|
||||
const branchSeg = (parseInt(accountNo.slice(0, 3), 10) + branch.acctShift) % 1000;
|
||||
return String(branchSeg).padStart(3, '0') + accountNo.slice(3);
|
||||
}
|
||||
const ifsc = accountNo.match(/^([A-Z]{4}0)(\d{6})$/);
|
||||
if (ifsc) {
|
||||
const serial = (parseInt(ifsc[2], 10) + branch.acctShift) % 1000000;
|
||||
return ifsc[1] + String(serial).padStart(6, '0');
|
||||
}
|
||||
return `${branch.code}-${accountNo}`;
|
||||
}
|
||||
|
||||
private scaleTxns(txns: TxnRow[], branch: Branch | null): TxnRow[] {
|
||||
if (!branch || branch.scale === 1) {
|
||||
return txns;
|
||||
}
|
||||
return txns.map((t) => ({
|
||||
...t,
|
||||
voucherNo: branchTag ? `${branchTag}-${t.voucherNo}` : t.voucherNo,
|
||||
debit: this.roundAmt(t.debit * factor),
|
||||
credit: this.roundAmt(t.credit * factor)
|
||||
voucherNo: `${branch.code}-${t.voucherNo}`,
|
||||
accountNo: this.scaleAccountNo(t.accountNo, branch),
|
||||
debit: this.roundAmt(t.debit * branch.scale),
|
||||
credit: this.roundAmt(t.credit * branch.scale)
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1387,13 +1421,13 @@ export class CashClearingTransferSummaryComponent {
|
||||
private effectiveTxns(tab: TabKey): TxnRow[] {
|
||||
const base = this.baseTxnsFor(tab);
|
||||
if (!this.isHeadOffice) {
|
||||
return this.ownBranch ? this.scaleTxns(base, this.ownBranch.scale, this.ownBranch.code) : base;
|
||||
return this.scaleTxns(base, this.ownBranch);
|
||||
}
|
||||
if (this.selectedBranchCode === 'ALL') {
|
||||
return this.branches.flatMap((b) => this.scaleTxns(base, b.scale, b.code));
|
||||
return this.branches.flatMap((b) => this.scaleTxns(base, b));
|
||||
}
|
||||
const branch = this.branches.find((b) => b.code === this.selectedBranchCode);
|
||||
return this.scaleTxns(base, branch ? branch.scale : 1, branch?.code);
|
||||
return this.scaleTxns(base, branch ?? null);
|
||||
}
|
||||
|
||||
get rowsForActiveTab(): SummaryRow[] {
|
||||
@@ -1524,7 +1558,7 @@ export class CashClearingTransferSummaryComponent {
|
||||
return this.branches.map((b) => {
|
||||
const pairs = this.allTabs.map((tab) => ({
|
||||
rows: this.scaleRows(this.baseRowsFor(tab), b.scale),
|
||||
txns: this.scaleTxns(this.baseTxnsFor(tab), b.scale, b.code)
|
||||
txns: this.scaleTxns(this.baseTxnsFor(tab), b)
|
||||
}));
|
||||
const opening = pairs.reduce((sum, c) => sum + this.total(c.rows, c.txns, 'opening'), 0);
|
||||
const credit = pairs.reduce((sum, c) => sum + this.total(c.rows, c.txns, 'credit'), 0);
|
||||
|
||||
@@ -533,6 +533,8 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges
|
||||
screeningLogId: number | null = null;
|
||||
/** Snapshot of the name that was last verified — used to invalidate verification when name changes */
|
||||
private verifiedName: string = '';
|
||||
/** True while prefillForEdit() is patching historical monthly/annual values — see linkMonthlyAnnual(). */
|
||||
private suppressMonthlyAnnualLink = false;
|
||||
|
||||
/**
|
||||
* @param {FormBuilder} formBuilder Form Builder
|
||||
@@ -709,6 +711,12 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges
|
||||
const data = this.clientData;
|
||||
this.loadExistingSeniorPwdDocuments();
|
||||
|
||||
// Loading an existing client's independently-saved monthly/annual values must not run
|
||||
// through the auto-calc in linkMonthlyAnnual() — patching monthlyIncome then annualIncome
|
||||
// (or vice versa) would otherwise have each overwrite the other via its valueChanges,
|
||||
// instead of keeping the exact historical values as saved.
|
||||
this.suppressMonthlyAnnualLink = true;
|
||||
|
||||
// Patch all base controls that exist on the form
|
||||
this.createClientForm.patchValue({
|
||||
officeId: data.officeId,
|
||||
@@ -743,6 +751,7 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges
|
||||
? new Date(data.timeline.submittedOnDate)
|
||||
: this.settingsService.businessDate
|
||||
});
|
||||
this.suppressMonthlyAnnualLink = false;
|
||||
|
||||
// Patch name fields (already created by buildDependencies via legalFormId subscription)
|
||||
const legalFormId = data.legalForm?.id || LegalFormId.PERSON;
|
||||
@@ -954,6 +963,43 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
|
||||
this.linkMonthlyAnnual('monthlyIncome', 'annualIncome');
|
||||
this.linkMonthlyAnnual('monthlyTurnover', 'annualTurnover');
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps a Monthly/Annual pair of amount fields in sync at a 12x ratio — typing into either
|
||||
* one auto-fills the other. Uses { emitEvent: false } on the write side so the two
|
||||
* subscriptions don't trigger each other back and forth.
|
||||
*/
|
||||
/** Rounds to at most 2 decimals without padding whole numbers with a trailing ".00". */
|
||||
private round2(n: number): string {
|
||||
return (Math.round(n * 100) / 100).toString();
|
||||
}
|
||||
|
||||
private linkMonthlyAnnual(monthlyControlName: string, annualControlName: string): void {
|
||||
const monthly = this.createClientForm.get(monthlyControlName);
|
||||
const annual = this.createClientForm.get(annualControlName);
|
||||
if (!monthly || !annual) {
|
||||
return;
|
||||
}
|
||||
|
||||
monthly.valueChanges.subscribe((value) => {
|
||||
if (this.suppressMonthlyAnnualLink) {
|
||||
return;
|
||||
}
|
||||
const num = parseFloat(value);
|
||||
annual.setValue(!isNaN(num) && num >= 0 ? this.round2(num * 12) : '', { emitEvent: false });
|
||||
});
|
||||
|
||||
annual.valueChanges.subscribe((value) => {
|
||||
if (this.suppressMonthlyAnnualLink) {
|
||||
return;
|
||||
}
|
||||
const num = parseFloat(value);
|
||||
monthly.setValue(!isNaN(num) && num >= 0 ? this.round2(num / 12) : '', { emitEvent: false });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user