318 lines
10 KiB
TypeScript
318 lines
10 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/.
|
|
*/
|
|
|
|
/** Angular Imports */
|
|
import { Component, OnInit, ViewChild, AfterViewInit, inject } from '@angular/core';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
|
|
import { MatPaginator } from '@angular/material/paginator';
|
|
import { MatSort, MatSortHeader } from '@angular/material/sort';
|
|
import {
|
|
MatTableDataSource,
|
|
MatTable,
|
|
MatColumnDef,
|
|
MatHeaderCellDef,
|
|
MatHeaderCell,
|
|
MatCellDef,
|
|
MatCell,
|
|
MatHeaderRowDef,
|
|
MatHeaderRow,
|
|
MatRowDef,
|
|
MatRow
|
|
} from '@angular/material/table';
|
|
|
|
/** rxjs Imports */
|
|
import { startWith, map, debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
|
|
|
|
/** Custom Services */
|
|
import { AccountingService } from '../../accounting.service';
|
|
import { AsyncPipe } from '@angular/common';
|
|
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
|
import { MatAutocompleteTrigger, MatAutocomplete, MatOption } from '@angular/material/autocomplete';
|
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
|
|
|
/**
|
|
* View provisioning entry component.
|
|
*/
|
|
@Component({
|
|
selector: 'mifosx-view-provisioning-entry',
|
|
templateUrl: './view-provisioning-entry.component.html',
|
|
styleUrls: ['./view-provisioning-entry.component.scss'],
|
|
imports: [
|
|
...STANDALONE_SHARED_IMPORTS,
|
|
FaIconComponent,
|
|
MatAutocompleteTrigger,
|
|
MatAutocomplete,
|
|
MatTable,
|
|
MatSort,
|
|
MatColumnDef,
|
|
MatHeaderCellDef,
|
|
MatHeaderCell,
|
|
MatSortHeader,
|
|
MatCellDef,
|
|
MatCell,
|
|
MatHeaderRowDef,
|
|
MatHeaderRow,
|
|
MatRowDef,
|
|
MatRow,
|
|
MatPaginator,
|
|
AsyncPipe
|
|
]
|
|
})
|
|
export class ViewProvisioningEntryComponent implements OnInit, AfterViewInit {
|
|
private accountingService = inject(AccountingService);
|
|
private route = inject(ActivatedRoute);
|
|
private router = inject(Router);
|
|
|
|
/** Provisioning entry id. */
|
|
provisioningEntryId: string;
|
|
/** Provisioning entry. */
|
|
provisioningEntry: any;
|
|
/** Provisioning entry entries. */
|
|
provisioningEntryEntries: any;
|
|
/** Office name filter form control. */
|
|
officeName = new UntypedFormControl();
|
|
/** Office data. */
|
|
officeData: any;
|
|
/** Filtered office data for autocomplete. */
|
|
filteredOfficeData: any;
|
|
/** Loan product filter form control. */
|
|
loanProduct = new UntypedFormControl();
|
|
/** Loan product data. */
|
|
loanProductData: any;
|
|
/** Filtered loan product data for autocomplete. */
|
|
filteredLoanProductData: any;
|
|
/** Provisioning category filter form control. */
|
|
provisioningCategory = new UntypedFormControl();
|
|
/** Provisioning category data. */
|
|
provisioningCategoryData: any;
|
|
/** Filtered provisioning category data for autocomplete. */
|
|
filteredProvisioningCategoryData: any;
|
|
/** Columns to be displayed in provisioning entry entries table. */
|
|
displayedColumns: string[] = [
|
|
'officeName',
|
|
'productName',
|
|
'currencyCode',
|
|
'categoryName',
|
|
'amountreserved',
|
|
'liabilityAccountName',
|
|
'expenseAccountName'
|
|
];
|
|
/** Data source for provisioning entry entries table. */
|
|
dataSource: MatTableDataSource<any>;
|
|
/** Provisioning entry entries filter. */
|
|
filterValue: any = {
|
|
officeName: '',
|
|
productName: '',
|
|
categoryName: ''
|
|
};
|
|
|
|
/** Paginator for provisioning entry entries table. */
|
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
|
/** Sorter for provisioning entry entries table. */
|
|
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
|
|
|
/**
|
|
* Retrieves the provisioning entry, provisioning entry entries, offices,
|
|
* loan products, provisioning categories data from `resolve`.
|
|
* @param {AccountingService} accountingService Accounting Service.
|
|
* @param {ActivatedRoute} route Activated Route.
|
|
* @param {Router} router Router for navigation.
|
|
*/
|
|
constructor() {
|
|
this.route.data.subscribe(
|
|
(data: {
|
|
provisioningEntry: any;
|
|
provisioningEntryEntries: any;
|
|
offices: any;
|
|
loanProducts: any;
|
|
provisiningCategories: any;
|
|
}) => {
|
|
this.provisioningEntryId = data.provisioningEntry.id;
|
|
this.provisioningEntry = data.provisioningEntry;
|
|
this.provisioningEntryEntries = data.provisioningEntryEntries;
|
|
this.officeData = data.offices;
|
|
this.loanProductData = data.loanProducts;
|
|
this.provisioningCategoryData = data.provisiningCategories;
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Sets filtered offices, loan products and provisioning categories for autocomplete
|
|
* and provisioning entry entries table.
|
|
*/
|
|
ngOnInit() {
|
|
this.setProvisioningEntryEntries();
|
|
this.setFilteredOffices();
|
|
this.setFilteredLoanProducts();
|
|
this.setFilteredProvisioningCategories();
|
|
}
|
|
|
|
/**
|
|
* Subscribes to all search filters:
|
|
* Office Name, Loan Product, Provisioning categories.
|
|
*/
|
|
ngAfterViewInit() {
|
|
this.officeName.valueChanges
|
|
.pipe(
|
|
map((value) => value.toLowerCase()),
|
|
debounceTime(500),
|
|
distinctUntilChanged(),
|
|
tap((filterValue) => {
|
|
this.applyFilter(filterValue, 'officeName');
|
|
})
|
|
)
|
|
.subscribe();
|
|
|
|
this.loanProduct.valueChanges
|
|
.pipe(
|
|
map((value) => value.toLowerCase()),
|
|
debounceTime(500),
|
|
distinctUntilChanged(),
|
|
tap((filterValue) => {
|
|
this.applyFilter(filterValue, 'productName');
|
|
})
|
|
)
|
|
.subscribe();
|
|
|
|
this.provisioningCategory.valueChanges
|
|
.pipe(
|
|
map((value) => value.toLowerCase()),
|
|
debounceTime(500),
|
|
distinctUntilChanged(),
|
|
tap((filterValue) => {
|
|
this.applyFilter(filterValue, 'categoryName');
|
|
})
|
|
)
|
|
.subscribe();
|
|
}
|
|
|
|
/**
|
|
* Filter predicate for provisioning entry entries table data.
|
|
* @param {any} data Table data.
|
|
* @param {any} filterValue Values to filter data by.
|
|
*/
|
|
filterPredicate(data: any, filterValue: any) {
|
|
return (
|
|
data.officeName.toLowerCase().indexOf(filterValue['officeName']) !== -1 &&
|
|
data.productName.toLowerCase().indexOf(filterValue['productName']) !== -1 &&
|
|
data.categoryName.toLowerCase().indexOf(filterValue['categoryName']) !== -1
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Initializes the data source, paginator, sorter and filter predicate for
|
|
* provisioning entry entries table.
|
|
*/
|
|
setProvisioningEntryEntries() {
|
|
this.dataSource = new MatTableDataSource(this.provisioningEntryEntries.pageItems);
|
|
this.dataSource.paginator = this.paginator;
|
|
this.dataSource.sort = this.sort;
|
|
this.dataSource.filterPredicate = this.filterPredicate;
|
|
}
|
|
|
|
/**
|
|
* Filters data in provisioning entry entries table based on passed value.
|
|
* @param {string} filterValue Value to filter data.
|
|
* @param {string} property Property to filter data.
|
|
*/
|
|
applyFilter(filterValue: string, property: string) {
|
|
this.filterValue[property] = filterValue;
|
|
this.dataSource.filter = this.filterValue;
|
|
}
|
|
|
|
/**
|
|
* Sets filtered offices for autocomplete.
|
|
*/
|
|
setFilteredOffices() {
|
|
this.filteredOfficeData = this.officeName.valueChanges.pipe(
|
|
startWith(''),
|
|
map((office: any) => (typeof office === 'string' ? office : office.name)),
|
|
map((officeName: string) => (officeName ? this.filterOfficeAutocompleteData(officeName) : this.officeData))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Sets filtered loan products for autocomplete.
|
|
*/
|
|
setFilteredLoanProducts() {
|
|
this.filteredLoanProductData = this.loanProduct.valueChanges.pipe(
|
|
startWith(''),
|
|
map((loanProduct: any) => (typeof loanProduct === 'string' ? loanProduct : loanProduct.name)),
|
|
map((loanProductName: string) =>
|
|
loanProductName ? this.filterLoanProductAutocompleteData(loanProductName) : this.loanProductData
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Sets filtered provisioning categories for autocomplete.
|
|
*/
|
|
setFilteredProvisioningCategories() {
|
|
this.filteredProvisioningCategoryData = this.provisioningCategory.valueChanges.pipe(
|
|
startWith(''),
|
|
map((provisioningCategory: any) =>
|
|
typeof provisioningCategory === 'string' ? provisioningCategory : provisioningCategory.categoryName
|
|
),
|
|
map((provisioningCategoryName: string) =>
|
|
provisioningCategoryName
|
|
? this.filterProvisioningCategoryAutocompleteData(provisioningCategoryName)
|
|
: this.provisioningCategoryData
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Filters offices.
|
|
* @param {string} officeName Office name to filter office by.
|
|
* @returns {any} Filtered offices.
|
|
*/
|
|
private filterOfficeAutocompleteData(officeName: string): any {
|
|
return this.officeData.filter((office: any) => office.name.toLowerCase().includes(officeName.toLowerCase()));
|
|
}
|
|
|
|
/**
|
|
* Filters loan products.
|
|
* @param {string} loanProductName Loan product name to filter loan products by.
|
|
* @returns {any} Filtered loan products.
|
|
*/
|
|
private filterLoanProductAutocompleteData(loanProductName: string): any {
|
|
return this.loanProductData.filter((loanProduct: any) =>
|
|
loanProduct.name.toLowerCase().includes(loanProductName.toLocaleLowerCase())
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Filters provisioning categories.
|
|
* @param {string} provisioningCategoryName Provisioning category name to filter provisioning categories by.
|
|
* @returns {any} Filtered provisioning categories.
|
|
*/
|
|
private filterProvisioningCategoryAutocompleteData(provisioningCategoryName: string): any {
|
|
return this.provisioningCategoryData.filter((provisioningCategory: any) =>
|
|
provisioningCategory.categoryName.toLowerCase().includes(provisioningCategoryName.toLocaleLowerCase())
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Creates provisioning journal entries
|
|
* and redirects to created entries.
|
|
*/
|
|
createProvisioningJournalEntries() {
|
|
this.accountingService.createProvisioningJournalEntries(this.provisioningEntryId).subscribe((response: any) => {
|
|
this.router.navigate(
|
|
[
|
|
'../../journal-entries/view',
|
|
response.resourceId
|
|
],
|
|
{ relativeTo: this.route }
|
|
);
|
|
});
|
|
}
|
|
}
|