WEB-654 fix: show only product-specific datatables in loan account view (#3105)

improvr

improve
This commit is contained in:
Shubham Kumar
2026-02-07 11:03:34 -06:00
committed by GitHub
parent adecbc27b8
commit a3a2f8471e
3 changed files with 99 additions and 11 deletions
@@ -414,17 +414,19 @@
{{ 'labels.inputs.External Asset Owner' | translate }}
</a>
}
@for (loanDatatable of loanDatatables; track loanDatatable) {
<a
mat-tab-link
*mifosxHasPermission="'READ_' + loanDatatable.registeredTableName"
[routerLink]="['./datatables', loanDatatable.registeredTableName]"
routerLinkActive
#datatable="routerLinkActive"
[active]="datatable.isActive"
>
{{ loanDatatable.registeredTableName }}
</a>
@if (datatablesReady) {
@for (loanDatatable of loanDatatables; track loanDatatable) {
<a
mat-tab-link
*mifosxHasPermission="'READ_' + loanDatatable.registeredTableName"
[routerLink]="['./datatables', loanDatatable.registeredTableName]"
routerLinkActive
#datatable="routerLinkActive"
[active]="datatable.isActive"
>
{{ loanDatatable.registeredTableName }}
</a>
}
}
</nav>
<mat-tab-nav-panel #tabPanel>
@@ -85,6 +85,8 @@ export class LoansViewComponent implements OnInit {
loanDetailsData: any;
/** Loan Datatables */
loanDatatables: any;
/** Whether datatable filtering has completed */
datatablesReady = false;
/** Recalculate Interest */
recalculateInterest: any;
/** loan Arrears Delinquency config value */
@@ -132,6 +134,8 @@ export class LoansViewComponent implements OnInit {
});
}
this.setConditionalButtons();
// Filter datatables based on entity datatable checks
this.filterDatatablesByProduct();
}
);
this.loanId = this.route.snapshot.params['loanId'];
@@ -169,6 +173,76 @@ export class LoansViewComponent implements OnInit {
this.loanDelinquencyClassification();
}
/**
* Filter datatables based on entity datatable checks configuration.
* Only shows datatables that are linked to the current loan's product.
*
* Logic:
* - If a datatable has product-specific entity checks for ANY loan product,
* it is only shown for products where it is explicitly configured.
* - If a datatable has NO product-specific entity checks at all,
* it is shown for all products (backward compatibility).
*/
filterDatatablesByProduct(): void {
this.datatablesReady = false;
if (!this.loanDatatables || this.loanDatatables.length === 0) {
this.datatablesReady = true;
return;
}
const loanProductId = this.loanDetailsData?.loanProductId;
if (!loanProductId || loanProductId <= 0) {
this.datatablesReady = true;
return; // Keep all datatables if product ID is not available or invalid
}
this.loansService.getEntityDataTableChecks().subscribe({
next: (response: any) => {
const entityChecks = response?.pageItems || [];
// Get all entity checks for the m_loan entity
const loanEntityChecks = entityChecks.filter((check: any) => check.entity === 'm_loan');
if (loanEntityChecks.length === 0) {
this.datatablesReady = true;
return; // No entity datatable checks configured at all, keep all datatables
}
// Collect datatable names that have product-specific configurations (for ANY product)
const productSpecificDatatables = new Set<string>(
loanEntityChecks
.filter((check: any) => check.productId && check.productId > 0)
.map((check: any) => check.datatableName)
);
// Collect datatable names allowed for the current product
const allowedForCurrentProduct = new Set<string>(
loanEntityChecks
.filter((check: any) => check.productId === loanProductId)
.map((check: any) => check.datatableName)
);
// Filter: keep a datatable if:
// 1. It has no product-specific configuration anywhere → show for all products
// 2. It is explicitly configured for the current product
this.loanDatatables = this.loanDatatables.filter((datatable: any) => {
const tableName = datatable.registeredTableName;
if (!productSpecificDatatables.has(tableName)) {
return true;
}
return allowedForCurrentProduct.has(tableName);
});
this.datatablesReady = true;
},
error: () => {
// If API fails, keep all datatables (fallback to current behavior)
this.datatablesReady = true;
}
});
}
// Defines the buttons based on the status of the loan account
setConditionalButtons() {
this.buttonConfig = new LoansAccountButtonConfiguration(this.status, this.loanSubStatus);
+12
View File
@@ -788,4 +788,16 @@ export class LoansService {
getLoanOriginators(loanId: any) {
return this.http.get(`/loans/${loanId}/originators`);
}
/**
* Get Entity Datatable Checks
* Used to filter datatables based on product configuration
* @param {number} offset Page offset
* @param {number} limit Number of entries
* @returns {Observable<any>} Entity Datatable Checks data
*/
getEntityDataTableChecks(offset: number = 0, limit: number = -1): Observable<any> {
const httpParams = new HttpParams().set('offset', offset.toString()).set('limit', limit.toString());
return this.http.get('/entityDatatableChecks', { params: httpParams });
}
}