292 lines
9.8 KiB
TypeScript
292 lines
9.8 KiB
TypeScript
/** Angular Imports */
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
|
|
/** Custom Services */
|
|
import { LoansService } from '../loans.service';
|
|
|
|
/** Custom Buttons Configuration */
|
|
import { LoansAccountButtonConfiguration } from './loan-accounts-button-config';
|
|
|
|
/** Dialog Components */
|
|
import { ConfirmationDialogComponent } from '../../shared/confirmation-dialog/confirmation-dialog.component';
|
|
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
|
import { LoanStatus } from '../models/loan-status.model';
|
|
import { Currency } from 'app/shared/models/general.model';
|
|
import { DelinquencyPausePeriod } from '../models/loan-account.model';
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
import { LoanTransaction } from 'app/products/loan-products/models/loan-account.model';
|
|
|
|
@Component({
|
|
selector: 'mifosx-loans-view',
|
|
templateUrl: './loans-view.component.html',
|
|
styleUrls: ['./loans-view.component.scss']
|
|
})
|
|
export class LoansViewComponent implements OnInit {
|
|
|
|
/** Loan Details Data */
|
|
loanDetailsData: any;
|
|
/** Loan Datatables */
|
|
loanDatatables: any;
|
|
/** Recalculate Interest */
|
|
recalculateInterest: any;
|
|
/** loan Arrears Delinquency config value */
|
|
loanDisplayArrearsDelinquency: number;
|
|
/** Status */
|
|
status: string;
|
|
entityType: string;
|
|
/** Loan Id */
|
|
loanId: number;
|
|
/** Client Id */
|
|
clientId: number;
|
|
/** Button Configuration */
|
|
buttonConfig: LoansAccountButtonConfiguration;
|
|
/** Disburse Transaction number */
|
|
disburseTransactionNo = 0;
|
|
|
|
loanDelinquencyClassificationStyle = '';
|
|
loanStatus: LoanStatus;
|
|
currency: Currency;
|
|
loanReAged = false;
|
|
|
|
constructor(private route: ActivatedRoute,
|
|
private router: Router,
|
|
public loansService: LoansService,
|
|
private translateService: TranslateService,
|
|
public dialog: MatDialog) {
|
|
this.route.data.subscribe((data: { loanDetailsData: any, loanDatatables: any, loanArrearsDelinquencyConfig: any }) => {
|
|
this.loanDetailsData = data.loanDetailsData;
|
|
this.loanDatatables = data.loanDatatables;
|
|
this.loanDisplayArrearsDelinquency = data.loanArrearsDelinquencyConfig.value || 0;
|
|
this.loanStatus = this.loanDetailsData.status;
|
|
this.currency = this.loanDetailsData.currency;
|
|
this.loanDetailsData.transactions.some((lt: LoanTransaction) => {
|
|
if (lt.type.reAge) {
|
|
this.loanReAged = true;
|
|
}
|
|
});
|
|
});
|
|
this.loanId = this.route.snapshot.params['loanId'];
|
|
this.clientId = this.loanDetailsData.clientId;
|
|
}
|
|
|
|
ngOnInit() {
|
|
this.recalculateInterest = this.loanDetailsData.recalculateInterest || true;
|
|
this.status = this.loanDetailsData.status.value;
|
|
if (this.loanDetailsData.status.active && this.loanDetailsData.multiDisburseLoan) {
|
|
if (this.loanDetailsData && this.loanDetailsData.transactions) {
|
|
this.loanDetailsData.transactions.forEach((transaction: any) => {
|
|
if (transaction.type.disbursement) {
|
|
this.disburseTransactionNo++;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
this.setConditionalButtons();
|
|
if (this.router.url.includes('clients')) {
|
|
this.entityType = 'Client';
|
|
} else if (this.router.url.includes('groups')) {
|
|
this.entityType = 'Group';
|
|
} else if (this.router.url.includes('centers')) {
|
|
this.entityType = 'Center';
|
|
}
|
|
this.loanDelinquencyClassification();
|
|
}
|
|
|
|
// Defines the buttons based on the status of the loan account
|
|
setConditionalButtons() {
|
|
this.buttonConfig = new LoansAccountButtonConfiguration(this.status);
|
|
|
|
if (this.status === 'Submitted and pending approval') {
|
|
|
|
this.buttonConfig.addOption({
|
|
name: (this.loanDetailsData.loanOfficerName ? 'Change Loan Officer' : 'Assign Loan Officer'),
|
|
icon: 'user-tie',
|
|
taskPermissionName: 'DISBURSE_LOAN'
|
|
});
|
|
|
|
if (this.loanDetailsData.isVariableInstallmentsAllowed) {
|
|
this.buttonConfig.addOption({
|
|
name: 'Edit Repayment Schedule',
|
|
icon: 'edit',
|
|
taskPermissionName: 'ADJUST_REPAYMENT_SCHEDULE'
|
|
});
|
|
}
|
|
|
|
} else if (this.status === 'Approved') {
|
|
|
|
this.buttonConfig.addButton({
|
|
name: (this.loanDetailsData.loanOfficerName ? 'Change Loan Officer' : 'Assign Loan Officer'),
|
|
icon: 'user-tie',
|
|
taskPermissionName: 'DISBURSE_LOAN'
|
|
});
|
|
|
|
} else if (this.status === 'Active') {
|
|
if (this.loanDetailsData.canDisburse || this.loanDetailsData.multiDisburseLoan) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Disburse',
|
|
icon: 'hand-holding-usd',
|
|
taskPermissionName: 'DISBURSE_LOAN'
|
|
});
|
|
}
|
|
if (this.loanDetailsData.canDisburse) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Disburse to Savings',
|
|
icon: 'piggy-bank',
|
|
taskPermissionName: 'DISBURSETOSAVINGS_LOAN'
|
|
});
|
|
}
|
|
if (this.loanDetailsData.multiDisburseLoan && this.disburseTransactionNo > 1) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Undo Last Disbursal',
|
|
icon: 'undo',
|
|
taskPermissionName: 'DISBURSALLASTUNDO_LOAN'
|
|
});
|
|
}
|
|
// loan officer not assigned to loan, below logic
|
|
// helps to display otherwise not
|
|
if (!this.loanDetailsData.loanOfficerName) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Assign Loan Officer',
|
|
icon: 'user-tie',
|
|
taskPermissionName: 'UPDATELOANOFFICER_LOAN'
|
|
});
|
|
}
|
|
|
|
if (this.recalculateInterest) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Prepay Loan',
|
|
icon: 'coins',
|
|
taskPermissionName: 'REPAYMENT_LOAN'
|
|
});
|
|
}
|
|
|
|
// Allow ChargeOff only If there loan is not already ChargeOff
|
|
if (!this.loanDetailsData.chargedOff) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Charge-Off',
|
|
icon: 'coins',
|
|
taskPermissionName: 'CHARGEOFF_LOAN'
|
|
});
|
|
}
|
|
|
|
// Allow Re-Ageing only when there is not any Re-Age transaction
|
|
if (!this.loanReAged) {
|
|
this.buttonConfig.addButton({
|
|
name: 'Re-Age',
|
|
icon: 'calendar',
|
|
taskPermissionName: 'REAGE_LOAN',
|
|
});
|
|
} else {
|
|
this.buttonConfig.addButton({
|
|
name: 'Undo Re-Age',
|
|
icon: 'undo',
|
|
taskPermissionName: 'UNDO_REAGE_LOAN',
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
loanAction(button: string) {
|
|
switch (button) {
|
|
case 'Recover From Guarantor':
|
|
this.recoverFromGuarantor();
|
|
break;
|
|
case 'Delete':
|
|
this.deleteLoanAccount();
|
|
break;
|
|
case 'Modify Application':
|
|
this.router.navigate(['edit-loans-account'], { relativeTo: this.route });
|
|
break;
|
|
case 'Transfer Funds':
|
|
const queryParams: any = { loanId: this.loanId, accountType: 'fromloans' };
|
|
this.router.navigate(['transfer-funds/make-account-transfer'], { relativeTo: this.route, queryParams: queryParams });
|
|
break;
|
|
case 'Undo Re-Age':
|
|
this.undoReAge();
|
|
break;
|
|
default:
|
|
this.router.navigate(['actions', button], { relativeTo: this.route });
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Recover from guarantor action
|
|
*/
|
|
private recoverFromGuarantor() {
|
|
const recoverFromGuarantorDialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
data: { heading: this.translateService.instant('labels.heading.Recover from Guarantor'), dialogContext: this.translateService.instant('labels.dialogContext.Are you sure you want recover from Guarantor'), type: 'Mild' }
|
|
});
|
|
recoverFromGuarantorDialogRef.afterClosed().subscribe((response: any) => {
|
|
if (response.confirm) {
|
|
this.loansService.loanActionButtons(this.loanId, 'recoverGuarantees').subscribe(() => {
|
|
this.reload();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
loanDelinquencyClassification(): void {
|
|
this.loanDelinquencyClassificationStyle = '';
|
|
if (this.loanDetailsData.delinquent && this.loanDetailsData.delinquent.delinquencyPausePeriods) {
|
|
this.loanDetailsData.delinquent.delinquencyPausePeriods.some((period: DelinquencyPausePeriod) => {
|
|
if (period.active) {
|
|
this.loanDelinquencyClassificationStyle = 'fa fa-stop status-pending';
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
undoReAge(): void {
|
|
const undoTransactionAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
data: { heading: this.translateService.instant('labels.heading.Undo Transaction'),
|
|
dialogContext: this.translateService.instant('labels.dialogContext.Are you sure you want undo the transaction type') + ' ReAge'
|
|
}
|
|
});
|
|
undoTransactionAccountDialogRef.afterClosed().subscribe((response: any) => {
|
|
if (response.confirm) {
|
|
this.loansService.executeLoansAccountTransactionsCommand(String(this.loanId), 'undoReAge', {}).subscribe(() => {
|
|
this.reload();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
iconLoanStatusColor() {
|
|
if (this.loanDetailsData.chargedOff) {
|
|
return 'loanStatusType.chargeoff';
|
|
}
|
|
return this.loanDetailsData.status.code;
|
|
}
|
|
|
|
/**
|
|
* Delete loan Account
|
|
*/
|
|
private deleteLoanAccount() {
|
|
const deleteGuarantorDialogRef = this.dialog.open(DeleteDialogComponent, {
|
|
data: { deleteContext: `with loan id: ${this.loanId}` }
|
|
});
|
|
deleteGuarantorDialogRef.afterClosed().subscribe((response: any) => {
|
|
if (response.delete) {
|
|
this.loansService.deleteLoanAccount(this.loanId).subscribe(() => {
|
|
this.router.navigate(['../../'], { relativeTo: this.route });
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Refetches data for the component
|
|
* TODO: Replace by a custom reload component instead of hard-coded back-routing.
|
|
*/
|
|
private reload() {
|
|
const clientId = this.clientId;
|
|
const url: string = this.router.url;
|
|
this.router.navigateByUrl(`/clients/${clientId}/loans-accounts`, { skipLocationChange: true })
|
|
.then(() => this.router.navigate([url]));
|
|
}
|
|
|
|
}
|