WEB-654 fix: show only product-specific datatables in loan account view (#3105)
improvr improve
This commit is contained in:
@@ -414,17 +414,19 @@
|
|||||||
{{ 'labels.inputs.External Asset Owner' | translate }}
|
{{ 'labels.inputs.External Asset Owner' | translate }}
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@for (loanDatatable of loanDatatables; track loanDatatable) {
|
@if (datatablesReady) {
|
||||||
<a
|
@for (loanDatatable of loanDatatables; track loanDatatable) {
|
||||||
mat-tab-link
|
<a
|
||||||
*mifosxHasPermission="'READ_' + loanDatatable.registeredTableName"
|
mat-tab-link
|
||||||
[routerLink]="['./datatables', loanDatatable.registeredTableName]"
|
*mifosxHasPermission="'READ_' + loanDatatable.registeredTableName"
|
||||||
routerLinkActive
|
[routerLink]="['./datatables', loanDatatable.registeredTableName]"
|
||||||
#datatable="routerLinkActive"
|
routerLinkActive
|
||||||
[active]="datatable.isActive"
|
#datatable="routerLinkActive"
|
||||||
>
|
[active]="datatable.isActive"
|
||||||
{{ loanDatatable.registeredTableName }}
|
>
|
||||||
</a>
|
{{ loanDatatable.registeredTableName }}
|
||||||
|
</a>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</nav>
|
</nav>
|
||||||
<mat-tab-nav-panel #tabPanel>
|
<mat-tab-nav-panel #tabPanel>
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ export class LoansViewComponent implements OnInit {
|
|||||||
loanDetailsData: any;
|
loanDetailsData: any;
|
||||||
/** Loan Datatables */
|
/** Loan Datatables */
|
||||||
loanDatatables: any;
|
loanDatatables: any;
|
||||||
|
/** Whether datatable filtering has completed */
|
||||||
|
datatablesReady = false;
|
||||||
/** Recalculate Interest */
|
/** Recalculate Interest */
|
||||||
recalculateInterest: any;
|
recalculateInterest: any;
|
||||||
/** loan Arrears Delinquency config value */
|
/** loan Arrears Delinquency config value */
|
||||||
@@ -132,6 +134,8 @@ export class LoansViewComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.setConditionalButtons();
|
this.setConditionalButtons();
|
||||||
|
// Filter datatables based on entity datatable checks
|
||||||
|
this.filterDatatablesByProduct();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.loanId = this.route.snapshot.params['loanId'];
|
this.loanId = this.route.snapshot.params['loanId'];
|
||||||
@@ -169,6 +173,76 @@ export class LoansViewComponent implements OnInit {
|
|||||||
this.loanDelinquencyClassification();
|
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
|
// Defines the buttons based on the status of the loan account
|
||||||
setConditionalButtons() {
|
setConditionalButtons() {
|
||||||
this.buttonConfig = new LoansAccountButtonConfiguration(this.status, this.loanSubStatus);
|
this.buttonConfig = new LoansAccountButtonConfiguration(this.status, this.loanSubStatus);
|
||||||
|
|||||||
@@ -788,4 +788,16 @@ export class LoansService {
|
|||||||
getLoanOriginators(loanId: any) {
|
getLoanOriginators(loanId: any) {
|
||||||
return this.http.get(`/loans/${loanId}/originators`);
|
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 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user