Add customer search dialog and sponsor DD/reconciliation modules
Adds sponsor-dd and sponsor-dd-reconciliation feature modules, a shared customer search dialog, and wires them into routing/shell/ organization screens alongside cashier and deposit-request updates.
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<!--
|
||||
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="leaflet-container">
|
||||
<div class="header-row">
|
||||
<div class="title-area">
|
||||
<button mat-button routerLink="/sponsor-dd/inventory" style="margin-bottom: 8px; color: #64748b; padding-left: 0">
|
||||
← Back to Inventories
|
||||
</button>
|
||||
<h2>DD Leaflet Registry</h2>
|
||||
<p *ngIf="inventoryDetails">
|
||||
Sponsor Bank: <strong>{{ inventoryDetails.sponsorBankName }}</strong> | Series Range:
|
||||
<strong>{{ inventoryDetails.seriesStart }} - {{ inventoryDetails.seriesEnd }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline" class="search-field">
|
||||
<mat-label>Search by DD Leaflet No.</mat-label>
|
||||
<input matInput [value]="searchText" (input)="onSearchChange($event.target.value)" placeholder="e.g. 3005" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="status-filter-row">
|
||||
<button mat-stroked-button color="accent" [class.filter-active]="todayOnly" (click)="toggleTodayOnly()">
|
||||
{{ todayOnly ? "Today's Issued DDs Only" : 'Showing All Dates' }}
|
||||
</button>
|
||||
<button
|
||||
mat-stroked-button
|
||||
*ngFor="let status of statusOptions"
|
||||
[color]="selectedStatus === status ? 'primary' : undefined"
|
||||
[class.filter-active]="selectedStatus === status"
|
||||
(click)="filterByStatus(status)"
|
||||
>
|
||||
{{ status === 'ALL' ? 'All' : status }}
|
||||
<span class="filter-count">({{ statusCount(status) }})</span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="hint-text" *ngIf="todayOnly">
|
||||
Only DDs actually ISSUED today are shown - AVAILABLE, CANCELLED, STOPPED and CLEARED are hidden. Click "Showing All
|
||||
Dates" above to see everything.
|
||||
</p>
|
||||
|
||||
<mat-card>
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
<!-- DD Number Column -->
|
||||
<ng-container matColumnDef="ddNumber">
|
||||
<th mat-header-cell *matHeaderCellDef>DD Leaflet No.</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<strong>{{ element.ddNumber }}</strong>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Status Column -->
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>Status</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span class="status-badge" [ngClass]="element.status.toLowerCase()">
|
||||
{{ element.status }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Face Value Column -->
|
||||
<ng-container matColumnDef="faceValue">
|
||||
<th mat-header-cell *matHeaderCellDef>Face Value</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.faceValue > 0 ? (element.faceValue | number: '1.2-2') : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Client Name Column -->
|
||||
<ng-container matColumnDef="issuedToClientName">
|
||||
<th mat-header-cell *matHeaderCellDef>Purchaser / Client</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.issuedToClientName || '-' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Beneficiary Column -->
|
||||
<ng-container matColumnDef="beneficiaryName">
|
||||
<th mat-header-cell *matHeaderCellDef>Beneficiary</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.beneficiaryName || '-' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Issued Date Column -->
|
||||
<ng-container matColumnDef="issuedDate">
|
||||
<th mat-header-cell *matHeaderCellDef>Issued Date</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.issuedDate || '-' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Advice Status Column -->
|
||||
<ng-container matColumnDef="adviceStatus">
|
||||
<th mat-header-cell *matHeaderCellDef>Advice Status</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.status === 'ISSUED' ? element.adviceStatus : '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Actions Column -->
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>Actions</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<div class="action-btn-group">
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
size="small"
|
||||
*ngIf="element.status === 'AVAILABLE' && !element.pendingIssueRequestId"
|
||||
(click)="openIssueDialog(element)"
|
||||
>
|
||||
Issue Draft
|
||||
</button>
|
||||
<span class="pending-badge" *ngIf="element.status === 'AVAILABLE' && element.pendingIssueRequestId">
|
||||
Pending Approval (Req #{{ element.pendingIssueRequestId }})
|
||||
</span>
|
||||
<button
|
||||
mat-stroked-button
|
||||
color="warn"
|
||||
size="small"
|
||||
*ngIf="element.status === 'ISSUED'"
|
||||
(click)="openCancelDialog(element)"
|
||||
>
|
||||
Cancel Draft
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
color="warn"
|
||||
size="small"
|
||||
*ngIf="element.status === 'ISSUED'"
|
||||
(click)="onStopPayment(element)"
|
||||
>
|
||||
Stop Payment
|
||||
</button>
|
||||
<button
|
||||
mat-stroked-button
|
||||
size="small"
|
||||
*ngIf="element.status === 'ISSUED' && !element.printCount"
|
||||
(click)="openPrintDialog(element)"
|
||||
>
|
||||
Print
|
||||
</button>
|
||||
<button
|
||||
mat-stroked-button
|
||||
color="primary"
|
||||
size="small"
|
||||
*ngIf="
|
||||
element.status === 'ISSUED' && element.printCount > 0 && element.approvedUnconsumedReprintRequestId
|
||||
"
|
||||
(click)="openPrintDialog(element)"
|
||||
>
|
||||
Print (Reprint Approved)
|
||||
</button>
|
||||
<button
|
||||
mat-stroked-button
|
||||
size="small"
|
||||
*ngIf="
|
||||
element.status === 'ISSUED' &&
|
||||
element.printCount > 0 &&
|
||||
!element.approvedUnconsumedReprintRequestId &&
|
||||
!element.pendingReprintRequestId
|
||||
"
|
||||
(click)="openRequestReprintDialog(element)"
|
||||
>
|
||||
Request Reprint
|
||||
</button>
|
||||
<span class="pending-badge" *ngIf="element.status === 'ISSUED' && element.pendingReprintRequestId">
|
||||
Reprint Pending Approval (Req #{{ element.pendingReprintRequestId }})
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<div
|
||||
*ngIf="dataSource.filteredData.length === 0"
|
||||
class="no-records-row"
|
||||
style="text-align: center; padding: 32px; color: #64748b"
|
||||
>
|
||||
{{ dataSource.data.length === 0 ? 'Loading leaflets...' : 'No leaflets match the selected filter.' }}
|
||||
</div>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[25, 50, 100, 250]" [pageSize]="25" showFirstLastButtons></mat-paginator>
|
||||
</mat-card>
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user