Loan account Contract Termination transaction
This commit is contained in:
@@ -75,6 +75,8 @@ export class LoanActionButtonResolver {
|
||||
return this.loansService.getLoanActionTemplate(loanId, 'charge-off');
|
||||
} else if (loanActionButton === 'Capitalized Income') {
|
||||
return this.loansService.getLoanActionTemplate(loanId, 'capitalizedIncome');
|
||||
} else if (loanActionButton === 'Contract Termination') {
|
||||
return this.loansService.getLoanActionTemplate(loanId, 'contractTermination');
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
[dataObject]="actionButtonData"
|
||||
></mifosx-assign-loan-officer>
|
||||
<mifosx-foreclosure [dataObject]="actionButtonData" *ngIf="actions['Foreclosure']"></mifosx-foreclosure>
|
||||
<mifosx-prepay-loan [dataObject]="actionButtonData" *ngIf="actions['Prepay Loan']"></mifosx-prepay-loan>
|
||||
<mifosx-prepay-loan
|
||||
[dataObject]="actionButtonData"
|
||||
*ngIf="actions['Prepay Loan'] || actions['Contract Termination']"
|
||||
></mifosx-prepay-loan>
|
||||
<mifosx-make-repayment [dataObject]="actionButtonData" *ngIf="actions['Make Repayment']"></mifosx-make-repayment>
|
||||
<mifosx-make-repayment [dataObject]="actionButtonData" *ngIf="actions['Capitalized Income']"></mifosx-make-repayment>
|
||||
<mifosx-make-repayment [dataObject]="actionButtonData" *ngIf="actions['Goodwill Credit']"></mifosx-make-repayment>
|
||||
|
||||
@@ -52,6 +52,7 @@ export class LoanAccountActionsComponent {
|
||||
'Interest Payment Waiver': boolean;
|
||||
'Add Interest Pause': boolean;
|
||||
'Capitalized Income': boolean;
|
||||
'Contract Termination': boolean;
|
||||
} = {
|
||||
Close: false,
|
||||
'Undo Approval': false,
|
||||
@@ -88,7 +89,8 @@ export class LoanAccountActionsComponent {
|
||||
'Re-Amortize': false,
|
||||
'Interest Payment Waiver': false,
|
||||
'Add Interest Pause': false,
|
||||
'Capitalized Income': false
|
||||
'Capitalized Income': false,
|
||||
'Contract Termination': false
|
||||
};
|
||||
|
||||
actionButtonData: any;
|
||||
@@ -119,5 +121,7 @@ export class LoanAccountActionsComponent {
|
||||
}
|
||||
this.actions[this.actionName as keyof typeof this.actions] = true;
|
||||
});
|
||||
|
||||
this.actionButtonData['actionName'] = this.actionName;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -3,7 +3,7 @@
|
||||
<form [formGroup]="prepayLoanForm" (ngSubmit)="submit()">
|
||||
<mat-card-content>
|
||||
<div class="layout-column">
|
||||
<mat-form-field (click)="transactionDatePicker.open()">
|
||||
<mat-form-field (click)="transactionDatePicker.open()" *ngIf="!contractTermination">
|
||||
<mat-label>{{ 'labels.inputs.Transaction Date' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -56,6 +56,7 @@
|
||||
</div>
|
||||
|
||||
<mifosx-input-amount
|
||||
*ngIf="!contractTermination"
|
||||
[currency]="currency"
|
||||
[isRequired]="true"
|
||||
[inputFormControl]="prepayLoanForm.controls.transactionAmount"
|
||||
@@ -68,7 +69,7 @@
|
||||
<input matInput formControlName="externalId" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field *ngIf="!contractTermination">
|
||||
<mat-label>{{ 'labels.inputs.Payment Type' | translate }}</mat-label>
|
||||
<mat-select formControlName="paymentTypeId">
|
||||
<mat-option *ngFor="let paymentType of paymentTypes" [value]="paymentType.id">
|
||||
@@ -77,7 +78,7 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex-fill">
|
||||
<div class="flex-fill" *ngIf="!contractTermination">
|
||||
<span class="expandcollapsebutton m-l-10 m-t-40 flex-75" (click)="addPaymentDetails()">
|
||||
<mat-slide-toggle>
|
||||
<div [className]="showPaymentDetails ? 'enabled' : 'disabled'">
|
||||
|
||||
+44
-16
@@ -38,6 +38,7 @@ export class PrepayLoanComponent implements OnInit {
|
||||
|
||||
prepayData: any;
|
||||
currency: Currency | null = null;
|
||||
contractTermination: boolean;
|
||||
|
||||
/**
|
||||
* @param {FormBuilder} formBuilder Form Builder.
|
||||
@@ -62,10 +63,13 @@ export class PrepayLoanComponent implements OnInit {
|
||||
* and initialize with the required values
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.prepayData = this.dataObject;
|
||||
this.contractTermination = this.dataObject['actionName'] == 'Contract Termination';
|
||||
this.maxDate = this.settingsService.businessDate;
|
||||
this.createprepayLoanForm();
|
||||
this.setPrepayLoanDetails();
|
||||
this.prepayData = this.dataObject;
|
||||
if (!this.contractTermination) {
|
||||
this.setPrepayLoanDetails();
|
||||
}
|
||||
if (this.dataObject.currency) {
|
||||
this.currency = this.dataObject.currency;
|
||||
}
|
||||
@@ -75,19 +79,26 @@ export class PrepayLoanComponent implements OnInit {
|
||||
* Creates the prepay loan form.
|
||||
*/
|
||||
createprepayLoanForm() {
|
||||
this.prepayLoanForm = this.formBuilder.group({
|
||||
transactionDate: [
|
||||
new Date(),
|
||||
Validators.required
|
||||
],
|
||||
transactionAmount: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
externalId: [''],
|
||||
paymentTypeId: [''],
|
||||
note: ['']
|
||||
});
|
||||
if (this.contractTermination) {
|
||||
this.prepayLoanForm = this.formBuilder.group({
|
||||
externalId: [''],
|
||||
note: ['']
|
||||
});
|
||||
} else {
|
||||
this.prepayLoanForm = this.formBuilder.group({
|
||||
transactionDate: [
|
||||
new Date(),
|
||||
Validators.required
|
||||
],
|
||||
transactionAmount: [
|
||||
'',
|
||||
Validators.required
|
||||
],
|
||||
externalId: [''],
|
||||
paymentTypeId: [''],
|
||||
note: ['']
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +144,7 @@ export class PrepayLoanComponent implements OnInit {
|
||||
/**
|
||||
* Submits the prepay loan form
|
||||
*/
|
||||
submit() {
|
||||
submitRepayment() {
|
||||
const prepayLoanFormData = this.prepayLoanForm.value;
|
||||
const locale = this.settingsService.language.code;
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
@@ -151,4 +162,21 @@ export class PrepayLoanComponent implements OnInit {
|
||||
this.router.navigate(['../../general'], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
|
||||
submitContractTermination() {
|
||||
const data = {
|
||||
...this.prepayLoanForm.value
|
||||
};
|
||||
this.loanService.loanActionButtons(this.loanId, 'contractTermination', data).subscribe((response: any) => {
|
||||
this.router.navigate(['../../general'], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.contractTermination) {
|
||||
this.submitContractTermination();
|
||||
} else {
|
||||
this.submitRepayment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { OptionData } from 'app/shared/models/option-data.model';
|
||||
|
||||
/** Recurring Deposits Account Buttons Configuration */
|
||||
export class LoansAccountButtonConfiguration {
|
||||
optionArray: {
|
||||
@@ -16,8 +18,8 @@ export class LoansAccountButtonConfiguration {
|
||||
taskPermissionName?: string;
|
||||
}[];
|
||||
|
||||
constructor(status: string) {
|
||||
this.setOptions(status);
|
||||
constructor(status: string, substatus: OptionData) {
|
||||
this.setOptions(status, substatus);
|
||||
this.setButtons(status);
|
||||
}
|
||||
|
||||
@@ -154,7 +156,7 @@ export class LoansAccountButtonConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(status: string) {
|
||||
setOptions(status: string, substatus: OptionData) {
|
||||
switch (status) {
|
||||
case 'Active':
|
||||
this.optionArray = [
|
||||
@@ -199,6 +201,12 @@ export class LoansAccountButtonConfiguration {
|
||||
taskPermissionName: 'SALE_LOAN'
|
||||
}
|
||||
];
|
||||
if (!this.isContractTermination(substatus)) {
|
||||
this.optionArray.push({
|
||||
name: 'Contract Termination',
|
||||
taskPermissionName: 'CONTRACT_TERMINATION_LOAN'
|
||||
});
|
||||
}
|
||||
this.optionPaymentArray = [
|
||||
{
|
||||
name: 'Goodwill Credit',
|
||||
@@ -281,4 +289,11 @@ export class LoansAccountButtonConfiguration {
|
||||
addButton(option: { name: string; icon: string; taskPermissionName?: string }) {
|
||||
this.buttonsArray.push(option);
|
||||
}
|
||||
|
||||
private isContractTermination(substatus: OptionData): boolean {
|
||||
if (substatus == null) {
|
||||
return false;
|
||||
}
|
||||
return substatus.code === 'loanSubStatus.loanSubStatusType.contractTermination';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
<i
|
||||
class="fa fa-stop"
|
||||
matTooltip="{{ 'labels.status.' + loanDetailsData.status.value | translate }}"
|
||||
[ngClass]="
|
||||
loanDetailsData.inArrears ? 'status-active-overdue' : (iconLoanStatusColor() | statusLookup)
|
||||
"
|
||||
[ngClass]="iconLoanStatusColor() | statusLookup"
|
||||
></i>
|
||||
<span class="m-r-5">{{ 'labels.heading.Loan Product' | translate }} :</span>
|
||||
<span class="m-r-5"
|
||||
|
||||
@@ -17,6 +17,7 @@ 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';
|
||||
import { OptionData } from 'app/shared/models/option-data.model';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-loans-view',
|
||||
@@ -46,6 +47,7 @@ export class LoansViewComponent implements OnInit {
|
||||
|
||||
loanDelinquencyClassificationStyle = '';
|
||||
loanStatus: LoanStatus;
|
||||
loanSubStatus: OptionData | null = null;
|
||||
currency: Currency;
|
||||
loanReAged = false;
|
||||
loanReAmortized = false;
|
||||
@@ -63,6 +65,7 @@ export class LoansViewComponent implements OnInit {
|
||||
this.loanDatatables = data.loanDatatables;
|
||||
this.loanDisplayArrearsDelinquency = data.loanArrearsDelinquencyConfig.value || 0;
|
||||
this.loanStatus = this.loanDetailsData.status;
|
||||
this.loanSubStatus = this.loanDetailsData.subStatus === undefined ? null : this.loanDetailsData.subStatus;
|
||||
this.currency = this.loanDetailsData.currency;
|
||||
if (this.loanStatus.active) {
|
||||
this.loanDetailsData.transactions.forEach((lt: LoanTransaction) => {
|
||||
@@ -75,6 +78,7 @@ export class LoansViewComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
this.setConditionalButtons();
|
||||
}
|
||||
);
|
||||
this.loanId = this.route.snapshot.params['loanId'];
|
||||
@@ -90,6 +94,8 @@ export class LoansViewComponent implements OnInit {
|
||||
});
|
||||
this.recalculateInterest = this.loanDetailsData.recalculateInterest || true;
|
||||
this.status = this.loanDetailsData.status.value;
|
||||
this.loanStatus = this.loanDetailsData.status;
|
||||
this.loanSubStatus = this.loanDetailsData.subStatus === undefined ? null : this.loanDetailsData.subStatus;
|
||||
if (this.loanStatus.active && this.loanDetailsData.multiDisburseLoan) {
|
||||
if (this.loanDetailsData && this.loanDetailsData.transactions) {
|
||||
this.loanDetailsData.transactions.forEach((transaction: any) => {
|
||||
@@ -112,7 +118,7 @@ export class LoansViewComponent implements OnInit {
|
||||
|
||||
// Defines the buttons based on the status of the loan account
|
||||
setConditionalButtons() {
|
||||
this.buttonConfig = new LoansAccountButtonConfiguration(this.status);
|
||||
this.buttonConfig = new LoansAccountButtonConfiguration(this.status, this.loanSubStatus);
|
||||
|
||||
if (this.status === 'Submitted and pending approval') {
|
||||
this.buttonConfig.addOption({
|
||||
@@ -345,9 +351,32 @@ export class LoansViewComponent implements OnInit {
|
||||
if (this.loanDetailsData.chargedOff) {
|
||||
return 'loanStatusType.chargeoff';
|
||||
}
|
||||
if (this.isContractTermination(this.loanSubStatus)) {
|
||||
return 'loanSubStatusType.contractTermination';
|
||||
}
|
||||
if (this.loanDetailsData.inArrears) {
|
||||
return 'loanStatusType.activeOverdue';
|
||||
}
|
||||
return this.loanDetailsData.status.code;
|
||||
}
|
||||
|
||||
loanStatusTooltip() {
|
||||
if (this.loanDetailsData.chargedOff) {
|
||||
return 'Chargeoff';
|
||||
}
|
||||
if (this.loanDetailsData.inArrears) {
|
||||
return 'activeOverdue';
|
||||
}
|
||||
return this.loanDetailsData.status.code;
|
||||
}
|
||||
|
||||
loanSubStatusTooltip() {
|
||||
if (this.isContractTermination(this.loanSubStatus)) {
|
||||
return 'contractTermination';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete loan Account
|
||||
*/
|
||||
@@ -375,4 +404,11 @@ export class LoansViewComponent implements OnInit {
|
||||
.navigateByUrl(`/clients/${clientId}/loans-accounts`, { skipLocationChange: true })
|
||||
.then(() => this.router.navigate([url]));
|
||||
}
|
||||
|
||||
private isContractTermination(substatus: OptionData): boolean {
|
||||
if (substatus == null) {
|
||||
return false;
|
||||
}
|
||||
return substatus.code === 'loanSubStatus.loanSubStatusType.contractTermination';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ export class TransactionsTabComponent implements OnInit {
|
||||
* REAGE:29
|
||||
* REAMORTIZE:30
|
||||
* INTEREST REFUND:33
|
||||
* CONTRACT_TERMINATION:90
|
||||
*/
|
||||
showTransactions(transactionsData: LoanTransaction) {
|
||||
if ([
|
||||
@@ -195,7 +196,8 @@ export class TransactionsTabComponent implements OnInit {
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
33
|
||||
33,
|
||||
90
|
||||
].includes(transactionsData.type.id)) {
|
||||
this.router.navigate([transactionsData.id], { relativeTo: this.route });
|
||||
}
|
||||
|
||||
+8
-8
@@ -22,7 +22,7 @@
|
||||
<div class="flex-100" [ngClass]="loanTransactionColor()"></div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Transaction Id' | translate }}
|
||||
{{ 'Transaction Id' | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong" *ngIf="transactionData.toLoanTransactionRelation">
|
||||
{{ 'Repayment Transaction' | translate }}
|
||||
{{ 'Repayment Transaction' | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50" *ngIf="transactionData.toLoanTransactionRelation">
|
||||
@@ -40,15 +40,15 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Type' | translate }}
|
||||
{{ 'Type' | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
{{ transactionData.type.value }}
|
||||
{{ transactionData.type.value | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Transaction Date' | translate }}
|
||||
{{ 'Transaction Date' | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Currency' | translate }}
|
||||
{{ 'Currency' | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
@@ -64,7 +64,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-50 mat-body-strong">
|
||||
{{ 'Amount' | translate }}
|
||||
{{ 'Amount' | translateKey: 'catalogs' }}
|
||||
</div>
|
||||
|
||||
<div class="flex-50">
|
||||
@@ -108,7 +108,7 @@
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let transactionRel">
|
||||
{{ transactionRel.amount | currency }} {{ transactionData.currency.code }}
|
||||
{{ transactionRel.amount | currency: transactionData.currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
|
||||
@@ -16,6 +16,8 @@ export class StatusLookupPipe implements PipeTransform {
|
||||
'loanStatusType.active': 'status-active',
|
||||
'loanStatusType.overpaid': 'status-overpaid',
|
||||
'loanStatusType.chargeoff': 'status-chargeoff',
|
||||
'loanStatusType.activeOverdue': 'status-active-overdue',
|
||||
'loanSubStatusType.contractTermination': 'subStatus-contract-termination',
|
||||
'savingsAccountStatusType.submitted.and.pending.approval': 'status-pending',
|
||||
'savingsAccountStatusType.approved': 'status-approved',
|
||||
'savingsAccountStatusType.active': 'status-active',
|
||||
|
||||
@@ -199,8 +199,8 @@
|
||||
<mat-label>{{ 'labels.inputs.Minimum Charge Cap' | translate }}</mat-label>
|
||||
<input matInput autofocus formControlName="minCap" mifosxValidateOnFocus />
|
||||
<mat-error *ngIf="chargeForm.controls.minCap.hasError('maxValue')">
|
||||
{{ 'errors.validation.msg.loanproduct.maximumGap.not.greater.than.specified.number' | translate }} ({{
|
||||
chargeForm.controls.minCap.value
|
||||
{{ 'errors.validation.msg.loanproduct.minimumGap.not.greater.than.specified.number' | translate }} ({{
|
||||
chargeForm.controls.maxCap.value
|
||||
}})
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
<mat-label>{{ 'labels.inputs.Minimum Charge Cap' | translate }}</mat-label>
|
||||
<input matInput autofocus formControlName="minCap" mifosxValidateOnFocus />
|
||||
<mat-error *ngIf="chargeForm.controls.minCap.hasError('maxValue')">
|
||||
{{ 'errors.validation.msg.loanproduct.maximumGap.not.greater.than.specified.number' | translate }} ({{
|
||||
chargeForm.controls.minCap.value
|
||||
{{ 'errors.validation.msg.loanproduct.minimumGap.not.greater.than.specified.number' | translate }} ({{
|
||||
chargeForm.controls.maxCap.value
|
||||
}})
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
Reference in New Issue
Block a user