/** * 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/. */ /** Angular Imports */ import { Component, OnInit, inject } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { RouterLink } from '@angular/router'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { MatTableModule } from '@angular/material/table'; import { MatPaginatorModule, PageEvent } from '@angular/material/paginator'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { MatDialog } from '@angular/material/dialog'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; /** Custom Services */ import { ChequeBookService } from '../chequebook.service'; import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; /** Cheque-leaf stationery master — leaves per book, CTS-2010 compliance, low-stock reorder threshold. */ @Component({ selector: 'mifosx-cheque-series', templateUrl: './cheque-series.component.html', styleUrls: ['./cheque-series.component.scss'], imports: [ ...STANDALONE_SHARED_IMPORTS, RouterLink, MatIconModule, MatButtonModule, MatTableModule, MatPaginatorModule, MatSnackBarModule, FaIconComponent ] }) export class ChequeSeriesComponent implements OnInit { private formBuilder = inject(UntypedFormBuilder); private chequeBookService = inject(ChequeBookService); private dialog = inject(MatDialog); private snackBar = inject(MatSnackBar); private notify(message: string, isError = false): void { this.snackBar.open(message, 'Dismiss', { duration: isError ? 6000 : 3000 }); } seriesList: any[] = []; showForm = false; busy = false; statusFilter = ''; pageSize = 10; pageIndex = 0; totalRecords = 0; pageSizeOptions = [ 10, 25, 50, 100 ]; seriesForm: UntypedFormGroup; columns = [ 'seriesCode', 'name', 'leavesPerBook', 'applicableAccountType', 'ctsCompliant', 'reorderLevel', 'active', 'actions' ]; constructor() { this.seriesForm = this.formBuilder.group({ seriesCode: [ '', Validators.required ], name: [ '', Validators.required ], leavesPerBook: [ 25, Validators.required ], applicableAccountType: [ '', Validators.required ], ctsCompliant: [true], reorderLevel: [10] }); } ngOnInit(): void { this.loadSeries(); } loadSeries(): void { this.chequeBookService .getSeries(this.statusFilter || undefined, this.pageIndex * this.pageSize, this.pageSize) .subscribe((res: any) => { this.seriesList = res?.pageItems ?? []; this.totalRecords = Number(res?.totalFilteredRecords ?? 0); }); } filterByStatus(status: string): void { this.statusFilter = this.statusFilter === status ? '' : status; this.pageIndex = 0; this.loadSeries(); } onPageChange(event: PageEvent): void { this.pageSize = event.pageSize; this.pageIndex = event.pageIndex; this.loadSeries(); } submit(): void { if (this.seriesForm.invalid || this.busy) { return; } this.busy = true; const raw = this.seriesForm.value; const payload: any = { seriesCode: raw.seriesCode, name: raw.name, leavesPerBook: raw.leavesPerBook, applicableAccountType: raw.applicableAccountType, ctsCompliant: !!raw.ctsCompliant, locale: 'en' }; if (raw.reorderLevel !== '' && raw.reorderLevel != null) payload.reorderLevel = raw.reorderLevel; this.chequeBookService.createSeries(payload).subscribe({ next: () => { this.busy = false; this.showForm = false; this.seriesForm.reset({ leavesPerBook: 25, applicableAccountType: '', ctsCompliant: true, reorderLevel: 10 }); this.notify('Submitted for approval — see Approvals > Cheque Book Requests'); this.loadSeries(); }, error: () => { this.busy = false; this.notify('Failed to add cheque series', true); } }); } deactivate(series: any): void { const dialogRef = this.dialog.open(DeleteDialogComponent, { data: { deleteContext: `cheque series ${series.seriesCode}` } }); dialogRef.afterClosed().subscribe((response: any) => { if (!response?.delete) { return; } this.chequeBookService.deactivateSeries(series.id).subscribe({ next: () => { this.notify('Submitted for approval — see Approvals > Cheque Book Requests'); this.loadSeries(); }, error: () => this.notify('Failed to submit for approval', true) }); }); } }