357 lines
13 KiB
HTML
357 lines
13 KiB
HTML
<!--
|
|
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/.
|
|
-->
|
|
|
|
<div class="oss-root">
|
|
<!-- HEADER -->
|
|
<div class="oss-head">
|
|
<div class="oss-head-left">
|
|
<fa-icon icon="university" class="oss-head-ic"></fa-icon>
|
|
<div>
|
|
<h2 class="oss-head-t">OSS 2 — {{ returnName }}</h2>
|
|
<div class="oss-head-s">
|
|
{{ bankName }} · Bank Code <strong>{{ bankCode }}</strong> · Return Code
|
|
<strong>{{ returnCode }}</strong> · Quarter ending <strong>{{ quarterEndDate }}</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="oss-head-right">
|
|
<span class="oss-audit-pill">{{ auditFlag }}</span>
|
|
<button class="oss-btn oss-btn-xls" [disabled]="generating" (click)="generateExcel()">
|
|
<fa-icon icon="file-csv"></fa-icon>
|
|
{{ generating ? 'Generating…' : 'Generate Excel' }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- HEADLINE RESULT -->
|
|
<div class="oss-balance">
|
|
<fa-icon icon="check-circle"></fa-icon>
|
|
<span>
|
|
Operating Profit <strong>₹{{ operatingProfit | number: '1.2-2' }}</strong> · Net Profit after tax
|
|
<strong>₹{{ netProfitAfterTax | number: '1.2-2' }}</strong> (Rs in Thousands)
|
|
</span>
|
|
</div>
|
|
|
|
<!-- TABS -->
|
|
<div class="oss-tabs">
|
|
<button class="oss-tab" [class.active]="activeTab === 'general'" (click)="showTab('general')">
|
|
<fa-icon icon="info-circle"></fa-icon> General Information
|
|
</button>
|
|
<button class="oss-tab" [class.active]="activeTab === 'earnings'" (click)="showTab('earnings')">
|
|
<fa-icon icon="university"></fa-icon> Earnings
|
|
</button>
|
|
<button class="oss-tab" [class.active]="activeTab === 'interest'" (click)="showTab('interest')">
|
|
<fa-icon icon="exclamation-triangle"></fa-icon> Interest Not Recognized
|
|
</button>
|
|
<button class="oss-tab" [class.active]="activeTab === 'other-expenses'" (click)="showTab('other-expenses')">
|
|
<fa-icon icon="file-alt"></fa-icon> Other Operating Expenses
|
|
</button>
|
|
<button class="oss-tab" [class.active]="activeTab === 'signatory'" (click)="showTab('signatory')">
|
|
<fa-icon icon="check-circle"></fa-icon> Signatory
|
|
</button>
|
|
</div>
|
|
|
|
<!-- GENERAL INFORMATION -->
|
|
@if (activeTab === 'general') {
|
|
<div class="oss-section">
|
|
<div class="oss-sheet-banner">General Information</div>
|
|
<div class="oss-tbl-wrap">
|
|
<table class="oss-tbl oss-tbl--kv">
|
|
<tbody>
|
|
@for (item of generalInfo; track item.label) {
|
|
<tr>
|
|
<th>{{ item.label }}</th>
|
|
<td [class.filled]="item.value" [class.audit]="item.label === 'Audit Flag'">{{ item.value }}</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- EARNINGS -->
|
|
@if (activeTab === 'earnings') {
|
|
<div class="oss-section">
|
|
<div class="oss-sheet-banner">Earnings</div>
|
|
|
|
<!-- Cross-return tie-ups the footnotes demand -->
|
|
<div class="oss-balance" [class.oss-balance--bad]="!allTieUpsMatch">
|
|
<fa-icon [icon]="allTieUpsMatch ? 'check-circle' : 'exclamation-triangle'"></fa-icon>
|
|
<span>
|
|
{{
|
|
allTieUpsMatch
|
|
? 'Item 17 tallies with OSS-1 liabilities as the footnotes require.'
|
|
: 'Item 17 does not tally with OSS-1 liabilities — see the tie-up check below.'
|
|
}}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="oss-tbl-wrap">
|
|
<div class="oss-tbl-h">OSS-1 tie-up check</div>
|
|
<table class="oss-tbl">
|
|
<thead>
|
|
<tr>
|
|
<th>OSS-2 item</th>
|
|
<th class="ta-r">OSS-2 value</th>
|
|
<th>Must tally with</th>
|
|
<th class="ta-r">OSS-1 value</th>
|
|
<th class="ta-c">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (t of oss1TieUps; track t.label) {
|
|
<tr>
|
|
<td>{{ t.label }}</td>
|
|
<td class="ta-r mono">{{ t.oss2Value === null ? '—' : (t.oss2Value | number: '1.2-2') }}</td>
|
|
<td>{{ t.oss1Label }}</td>
|
|
<td class="ta-r mono">{{ t.oss1Value === null ? '—' : (t.oss1Value | number: '1.2-2') }}</td>
|
|
<td class="ta-c">
|
|
<span [class]="t.tallies ? 'report-pill report-ok' : 'report-pill report-bad'">
|
|
{{ t.tallies ? 'Tallies' : 'Mismatch' }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- GL mapping toolbar -->
|
|
<div class="oss-gl-bar" [class.on]="glMapMode">
|
|
<div class="oss-gl-bar-l">
|
|
<fa-icon icon="project-diagram"></fa-icon>
|
|
<span>
|
|
<strong>General Ledger mapping</strong>
|
|
@if (glMappedCount) {
|
|
<span class="oss-gl-count">{{ glMappedCount }} line(s) mapped</span>
|
|
} @else {
|
|
<span class="muted"> — pin GL accounts to a line and its figure comes from the ledger</span>
|
|
}
|
|
</span>
|
|
</div>
|
|
<div class="oss-gl-bar-r">
|
|
@if (glMapMode) {
|
|
@if (canSelectGlBranch) {
|
|
<select class="oss-gl-inp" [(ngModel)]="glBranchCode">
|
|
<option value="">All branches</option>
|
|
@for (b of glBranches; track b.code) {
|
|
<option [value]="b.code">{{ b.name }}</option>
|
|
}
|
|
</select>
|
|
} @else {
|
|
<span class="oss-gl-scope" title="Your login is restricted to this branch">
|
|
<fa-icon icon="university"></fa-icon> {{ glScopeName }}
|
|
</span>
|
|
}
|
|
@if (glMappedCount) {
|
|
<button class="oss-btn oss-btn-clear" (click)="clearAllGlMappings()">Clear all</button>
|
|
}
|
|
}
|
|
<button class="oss-btn" [class.oss-btn-xls]="!glMapMode" (click)="toggleGlMapMode()">
|
|
<fa-icon [icon]="glMapMode ? 'times' : 'plus'"></fa-icon>
|
|
{{ glMapMode ? 'Done' : 'Add / Remove GLs' }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="oss-tbl-wrap">
|
|
<table class="oss-tbl">
|
|
<thead>
|
|
<tr>
|
|
<th>Particulars</th>
|
|
@if (glMapMode) {
|
|
<th class="oss-gl-col">Mapped GL accounts</th>
|
|
}
|
|
<th class="ta-r">Rs in Thousand</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (line of earnings; track $index) {
|
|
<tr [class.total-row]="line.total">
|
|
<td [class]="'lvl-' + line.level">{{ line.label }}</td>
|
|
@if (glMapMode) {
|
|
<td>
|
|
<div class="oss-gl-cell">
|
|
@for (code of glCodesFor(line.label); track code) {
|
|
<span class="oss-gl-chip">
|
|
<span class="mono">{{ code }}</span>
|
|
<button
|
|
class="oss-gl-chip-x"
|
|
(click)="removeGlFromLine(line.label, code)"
|
|
[attr.aria-label]="'Remove ' + code"
|
|
>
|
|
<fa-icon icon="times"></fa-icon>
|
|
</button>
|
|
</span>
|
|
}
|
|
<button class="oss-gl-add" (click)="openGlPicker(line.label, line.value)">
|
|
<fa-icon icon="plus"></fa-icon>
|
|
{{ glCodesFor(line.label).length ? 'Edit' : 'Add GL' }}
|
|
</button>
|
|
@if (glDiffers(line.label, line.value)) {
|
|
<span class="oss-gl-warn" title="Ledger figure differs from the value filed on the return">
|
|
<fa-icon icon="exclamation-triangle"></fa-icon> differs from filed
|
|
</span>
|
|
}
|
|
</div>
|
|
</td>
|
|
}
|
|
<td
|
|
class="ta-r mono"
|
|
[class.derived]="line.total"
|
|
[class.gl-sourced]="isGlMapped(line.label)"
|
|
[class.gl-diff]="glDiffers(line.label, line.value)"
|
|
>
|
|
{{
|
|
effectiveValue(line.label, line.value) === null
|
|
? ''
|
|
: (effectiveValue(line.label, line.value) | number: (line.count ? '1.0-0' : '1.2-2'))
|
|
}}
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="oss-notes">
|
|
@for (note of earningsNotes; track note) {
|
|
<div class="oss-note-line">{{ note }}</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- INTEREST RECEIVABLE NOT RECOGNIZED -->
|
|
@if (activeTab === 'interest') {
|
|
<div class="oss-section">
|
|
<div class="oss-sheet-banner">Interest Receivable Not Recognized</div>
|
|
<div class="oss-tbl-wrap">
|
|
<table class="oss-tbl">
|
|
<thead>
|
|
<tr>
|
|
<th>Interest receivable on NPAs not recognized as income</th>
|
|
<th class="ta-r">{{ quarterEndDate }} (Rs in Thousand)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (r of interestNotRecognized; track r.label) {
|
|
<tr [class.total-row]="r.total">
|
|
<td>{{ r.label }}</td>
|
|
<td class="ta-r mono" [class.derived]="r.total">
|
|
{{ r.value === null ? '' : (r.value | number: '1.2-2') }}
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- OTHER OPERATING EXPENSES -->
|
|
@if (activeTab === 'other-expenses') {
|
|
<div class="oss-section">
|
|
<div class="oss-sheet-banner">Other Operating Expenses</div>
|
|
|
|
<div class="oss-balance" [class.oss-balance--bad]="!otherExpensesTally">
|
|
<fa-icon [icon]="otherExpensesTally ? 'check-circle' : 'exclamation-triangle'"></fa-icon>
|
|
<span>
|
|
Detail total <strong>₹{{ otherExpensesTotal | number: '1.2-2' }}</strong> vs Earnings line 12 ix) Others
|
|
<strong
|
|
>₹{{ otherExpensesLineValue === null ? '—' : (otherExpensesLineValue | number: '1.2-2') }}</strong
|
|
>
|
|
— {{ otherExpensesTally ? 'tallies' : 'MISMATCH — resolve before filing' }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="oss-tbl-wrap">
|
|
<div class="oss-tbl-h">Details of Other Operating Expenses — Rs in Thousand</div>
|
|
<table class="oss-tbl">
|
|
<thead>
|
|
<tr>
|
|
<th class="ta-c">Sr No</th>
|
|
<th>Particulars</th>
|
|
<th class="ta-r">Amount</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (e of otherExpenses; track e.srNo) {
|
|
<tr>
|
|
<td class="ta-c">{{ e.srNo }}</td>
|
|
<td>{{ e.particulars }}</td>
|
|
<td class="ta-r mono">{{ e.amount === null ? '' : (e.amount | number: '1.2-2') }}</td>
|
|
</tr>
|
|
}
|
|
<tr class="total-row">
|
|
<td class="ta-c"></td>
|
|
<td>Total</td>
|
|
<td class="ta-r mono derived">{{ otherExpensesTotal | number: '1.2-2' }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p class="oss-foot-note">Feeds Earnings sheet line 12 ix) Others.</p>
|
|
</div>
|
|
}
|
|
|
|
<!-- SIGNATORY -->
|
|
@if (activeTab === 'signatory') {
|
|
<div class="oss-section">
|
|
<div class="oss-sheet-banner">Signatory Information</div>
|
|
<div class="oss-sign-grid">
|
|
@for (p of signatories; track p.heading) {
|
|
<div class="oss-tbl-wrap">
|
|
<div class="oss-tbl-h">{{ p.heading }}</div>
|
|
<table class="oss-tbl oss-tbl--kv">
|
|
<tbody>
|
|
<tr>
|
|
<td>{{ p.signature }}</td>
|
|
<th>Signature</th>
|
|
</tr>
|
|
<tr>
|
|
<td>{{ p.name }}</td>
|
|
<th>Name</th>
|
|
</tr>
|
|
<tr>
|
|
<td>{{ p.designation }}</td>
|
|
<th>Designation</th>
|
|
</tr>
|
|
<tr>
|
|
<td>{{ p.email }}</td>
|
|
<th>e-mail ID</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="mono">{{ p.telephoneOffice }}</td>
|
|
<th>Tel. No. (O)</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="mono">{{ p.telephoneResidence }}</td>
|
|
<th>Tel. No. (R)</th>
|
|
</tr>
|
|
<tr>
|
|
<td>{{ p.place }}</td>
|
|
<th>Place</th>
|
|
</tr>
|
|
<tr>
|
|
<td>{{ p.date }}</td>
|
|
<th>Date</th>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- TOAST -->
|
|
<div class="oss-toast" [class.show]="toastVisible">{{ toastMsg }}</div>
|
|
</div>
|