feat: add KYC document renewal alerts, Aadhaar/PAN exceptions, and AML recurring alerts UI; remove old journal AML marking
build-run / Run Lint, Build and Deploy (push) Canceled after 0s
Publish Image in Docker Hub / build (push) Canceled after 0s
Playwright E2E Tests / Run Playwright Tests (push) Canceled after 0s
Tests / testRigor (push) Canceled after 0s

This commit is contained in:
2026-08-11 11:11:18 +05:30
parent 01e86173c1
commit 7b895a0e2b
77 changed files with 10046 additions and 1130 deletions
@@ -80,7 +80,7 @@
<div class="tdsr__filters">
<label class="tdsr__filter">
<span>Financial year</span>
<select [(ngModel)]="filter.fy">
<select [(ngModel)]="filter.fy" (ngModelChange)="onFilterChanged()">
@for (year of financialYears; track year) {
<option [value]="year">FY {{ year }}</option>
}
@@ -90,7 +90,7 @@
@if (canSelectBranch) {
<label class="tdsr__filter">
<span>Branch</span>
<select [(ngModel)]="filter.branchCode">
<select [(ngModel)]="filter.branchCode" (ngModelChange)="onFilterChanged()">
<option value="">All branches</option>
@for (b of branches; track b.code) {
<option [value]="b.code">{{ b.name }}</option>
@@ -101,7 +101,7 @@
<label class="tdsr__filter">
<span>Quarter</span>
<select [(ngModel)]="filter.quarter">
<select [(ngModel)]="filter.quarter" (ngModelChange)="onFilterChanged()">
<option [ngValue]="0">Whole year</option>
@for (q of quarters; track q) {
<option [ngValue]="q">{{ quarterLabel[q] }}</option>
@@ -111,7 +111,7 @@
<label class="tdsr__filter">
<span>Threshold band</span>
<select [(ngModel)]="filter.band">
<select [(ngModel)]="filter.band" (ngModelChange)="onFilterChanged()">
<option value="">Both bands</option>
<option value="GENERAL">General (below 60)</option>
<option value="SENIOR">Senior citizen (60+)</option>
@@ -120,16 +120,21 @@
<label class="tdsr__filter tdsr__filter--wide">
<span>Customer / CIF / PAN</span>
<input type="text" [(ngModel)]="filter.search" placeholder="name, CIF or PAN" />
<input
type="text"
[(ngModel)]="filter.search"
(ngModelChange)="onFilterChanged()"
placeholder="name, CIF or PAN"
/>
</label>
<label class="tdsr__check">
<input type="checkbox" [(ngModel)]="filter.crossedOnly" />
<input type="checkbox" [(ngModel)]="filter.crossedOnly" (ngModelChange)="onFilterChanged()" />
<span>Threshold crossed only</span>
</label>
<label class="tdsr__check">
<input type="checkbox" [(ngModel)]="filter.nearThresholdOnly" />
<input type="checkbox" [(ngModel)]="filter.nearThresholdOnly" (ngModelChange)="onFilterChanged()" />
<span>Near threshold only</span>
</label>
@@ -138,6 +143,26 @@
}
</div>
<!-- Tabs Selector -->
<div class="tdsr__tabs">
<button
type="button"
class="tdsr__tab"
[class.tdsr__tab--active]="selectedTab === 'paying'"
(click)="selectTab('paying')"
>
Paying TDS ({{ payingRows.length }})
</button>
<button
type="button"
class="tdsr__tab"
[class.tdsr__tab--active]="selectedTab === 'not-paying'"
(click)="selectTab('not-paying')"
>
Not Paying TDS ({{ notPayingRows.length }})
</button>
</div>
<!-- Table -->
<div class="tdsr__card">
<div class="tdsr__table-wrap">
@@ -160,7 +185,7 @@
</tr>
</thead>
<tbody>
@for (row of rows; track trackRow($index, row)) {
@for (row of pagedRows; track trackRow($index, row)) {
<tr [class.tdsr__row--warn]="!row.panOnRecord" [class.tdsr__row--near]="row.nearThreshold">
<td>
<div class="tdsr__name">{{ row.deductee.name }}</div>
@@ -311,15 +336,70 @@
</tr>
}
}
@if (rows.length === 0) {
@if (visibleRows.length === 0) {
<tr>
<td colspan="13" class="tdsr__empty">
<fa-icon icon="info-circle"></fa-icon> No deductees match the current filters.
<fa-icon icon="info-circle"></fa-icon> No customers in this section match the filters.
</td>
</tr>
}
</tbody>
</table>
</div>
@if (visibleRows.length > 0) {
<div class="tdsr__pager">
<div class="tdsr__pager-l">
<span>
Showing <strong>{{ rangeStart | number }}–{{ rangeEnd | number }}</strong> of
<strong>{{ visibleRows.length | number }}</strong>
{{ selectedTab === 'paying' ? 'deductees paying TDS' : 'deductees not paying TDS' }}
</span>
<label class="tdsr__pager-sizel">
Rows
<select class="tdsr__pager-size" [ngModel]="pageSize" (ngModelChange)="onPageSizeChange($event)">
@for (size of pageSizeOptions; track size) {
<option [ngValue]="size">{{ size || 'All' }}</option>
}
</select>
</label>
</div>
@if (pageCount > 1) {
<div class="tdsr__pager-r">
<button type="button" class="tdsr__pager-btn" (click)="goToPage(0)" [disabled]="currentPage === 0">
First
</button>
<button
type="button"
class="tdsr__pager-btn"
(click)="goToPage(currentPage - 1)"
[disabled]="currentPage === 0"
aria-label="Previous page"
>
<fa-icon icon="chevron-left"></fa-icon>
</button>
<span class="tdsr__pager-cur">Page {{ currentPage + 1 | number }} of {{ pageCount | number }}</span>
<button
type="button"
class="tdsr__pager-btn"
(click)="goToPage(currentPage + 1)"
[disabled]="currentPage >= pageCount - 1"
aria-label="Next page"
>
<fa-icon icon="chevron-right"></fa-icon>
</button>
<button
type="button"
class="tdsr__pager-btn"
(click)="goToPage(pageCount - 1)"
[disabled]="currentPage >= pageCount - 1"
>
Last
</button>
</div>
}
</div>
}
</div>
</div>