Files
cbsnexora/src/app/sponsor-dd-reconciliation/reco-batch-upload/reco-batch-upload.component.ts
T
keshav 3cf01e2733 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.
2026-07-22 11:59:31 +05:30

177 lines
4.7 KiB
TypeScript

/**
* 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 } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router, RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { SponsorDDReconciliationService } from '../sponsor-dd-reconciliation.service';
@Component({
selector: 'mifosx-reco-batch-upload',
standalone: true,
imports: [
CommonModule,
RouterModule,
FormsModule,
MatCardModule,
MatButtonModule,
MatSnackBarModule,
MatProgressBarModule,
FaIconComponent
],
templateUrl: './reco-batch-upload.component.html',
styles: [
`
.upload-container {
padding: 24px;
max-width: 600px;
margin: 0 auto;
}
.header-row {
margin-bottom: 24px;
}
.header-row h2 {
margin: 0 0 4px 0;
font-size: 24px;
font-weight: 600;
color: #1e293b;
}
.header-row p {
margin: 0;
color: #64748b;
font-size: 14px;
}
.mat-mdc-card {
border-radius: 12px;
border: 1px solid #e2e8f0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
padding: 32px;
}
.dropzone {
border: 2px dashed #cbd5e1;
border-radius: 8px;
padding: 40px 20px;
text-align: center;
background-color: #f8fafc;
cursor: pointer;
transition:
border-color 0.2s,
background-color 0.2s;
}
.dropzone:hover {
border-color: #7c3aed;
background-color: #f1f5f9;
}
.dropzone-icon {
font-size: 48px;
color: #94a3b8;
margin-bottom: 16px;
}
.file-details {
margin-top: 24px;
padding: 16px;
background-color: #f1f5f9;
border-radius: 6px;
display: flex;
justify-content: space-between;
align-items: center;
}
.file-name {
font-weight: 500;
color: #334155;
}
.file-size {
font-size: 12px;
color: #64748b;
}
.actions {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 24px;
}
.progress-section {
margin-top: 24px;
text-align: center;
}
.progress-text {
font-size: 12px;
color: #64748b;
margin-top: 8px;
}
`
]
})
export class RecoBatchUploadComponent {
private recoService = inject(SponsorDDReconciliationService);
private router = inject(Router);
private snackBar = inject(MatSnackBar);
selectedFile: File | null = null;
loading = false;
progressMessage = '';
onFileSelected(event: any): void {
const file = event.target.files[0];
if (file) {
this.selectedFile = file;
}
}
triggerFileSelect(fileInput: HTMLInputElement): void {
fileInput.click();
}
onSubmit(): void {
if (!this.selectedFile) return;
this.loading = true;
this.progressMessage = 'Reading file and preparing upload payload...';
const reader = new FileReader();
reader.onload = () => {
const fileContent = reader.result as string;
this.progressMessage = 'Uploading clearing scroll for processing...';
this.recoService
.uploadClearingScroll({
fileName: this.selectedFile!.name,
fileContent: fileContent
})
.subscribe({
next: (res) => {
this.snackBar.open(
`Reconciliation batch processed successfully. ${res.successCount} matched, ${res.mismatchCount} exceptions.`,
'Close',
{ duration: 7000 }
);
this.router.navigate([
'/sponsor-dd-reconciliation/batches',
res.id
]);
},
error: (err) => {
this.loading = false;
this.progressMessage = '';
this.snackBar.open('Reconciliation failed: ' + (err.error?.message || err.message), 'Close', {
duration: 6000
});
}
});
};
reader.readAsDataURL(this.selectedFile); // Reads as Base64 Data URL, which our backend decodes safely.
}
}