Support for Charge-off and Undo charge-off to Loan account (#1748)

Co-authored-by: Jose Alberto Hernandez <alberto@blue-daemon.local>
This commit is contained in:
José Alberto Hernández
2023-05-09 22:09:45 -06:00
committed by GitHub
co-authored by Jose Alberto Hernandez
parent d294885f00
commit b2aa39cb67
94 changed files with 863 additions and 481 deletions
@@ -43,8 +43,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -59,8 +59,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -217,8 +217,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -104,7 +104,7 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!fixedDepositAccountFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -25,8 +25,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -42,8 +42,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -143,7 +143,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -139,8 +139,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -94,8 +94,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -105,7 +105,7 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!recurringDepositAccountFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -21,8 +21,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -42,8 +42,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -148,7 +148,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -202,8 +202,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -62,8 +62,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -70,6 +70,8 @@ export class LoanActionButtonResolver implements Resolve<Object> {
return this.loansService.getLoanChargeTemplateResource(loanId);
} else if (loanActionButton === 'Foreclosure') {
return this.loansService.getLoanForeclosureActionTemplate(loanId);
} else if (loanActionButton === 'Charge-Off') {
return this.loansService.getLoanActionTemplate(loanId, 'charge-off');
} else {
return undefined;
}
@@ -163,7 +163,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -80,8 +80,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -121,8 +121,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -124,8 +124,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!loansAccountFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
Cancel
@@ -43,8 +43,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -95,8 +95,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
Cancel
@@ -2,8 +2,6 @@
<h3 class="mat-h3" fxFlexFill>Details</h3>
<mat-divider fxFlexFill></mat-divider>
<div fxFlexFill>
<span fxFlex="40%">Product:</span>
<span fxFlex="60%">{{ loansAccount.productId | find:loansAccountTemplate.productOptions:'id':'name' }}</span>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
/**
* Create Loans Account Preview Step
@@ -9,10 +9,10 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
templateUrl: './loans-account-preview-step.component.html',
styleUrls: ['./loans-account-preview-step.component.scss']
})
export class LoansAccountPreviewStepComponent implements OnInit {
export class LoansAccountPreviewStepComponent implements OnInit, OnDestroy {
/** Loans Account Template */
@Input() loansAccountTemplate: any;
@Input() loansAccountTemplate: any = [];
/** Loans Account Product Template */
@Input() loansAccountProductTemplate: any;
/** Loans Account Data */
@@ -29,4 +29,6 @@ export class LoansAccountPreviewStepComponent implements OnInit {
ngOnInit() { }
ngOnDestroy(): void { }
}
@@ -4,8 +4,7 @@
Repayment Info
</a>
<mifosx-repayment-schedule-tab fxFlex="100%"
[repaymentScheduleDetails]="repaymentScheduleDetails"
<mifosx-repayment-schedule-tab fxFlex="100%" [repaymentScheduleDetails]="repaymentScheduleDetails"
[currencyCode]="currencyCode">
</mifosx-repayment-schedule-tab>
@@ -17,8 +16,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
Cancel
@@ -426,8 +426,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
Cancel
@@ -0,0 +1,58 @@
<div class="container mat-elevation-z8">
<mat-card>
<form [formGroup]="chargeoffLoanForm" (ngSubmit)="submit()">
<mat-card-content>
<div fxLayout="column">
<mat-form-field (click)="transactionDatePicker.open()">
<mat-label>Transaction Date</mat-label>
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="transactionDatePicker" required
formControlName="transactionDate">
<mat-datepicker-toggle matSuffix [for]="transactionDatePicker"></mat-datepicker-toggle>
<mat-datepicker #transactionDatePicker></mat-datepicker>
<mat-error *ngIf="chargeoffLoanForm.controls.transactionDate.hasError('required')">
Transaction Date <strong>is required</strong>
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Reason for Charge-Off</mat-label>
<mat-select formControlName="chargeOffReasonId">
<mat-option *ngFor="let chargeOffReason of chargeOffReasonOptions" [value]="chargeOffReason.id">
{{ chargeOffReason.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="chargeoffLoanForm.controls.chargeOffReasonId.hasError('required')">
Reason for Charge-Off <strong>is required</strong>
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>External Id</mat-label>
<input matInput formControlName="externalId">
</mat-form-field>
<mat-form-field>
<mat-label>Note</mat-label>
<textarea matInput formControlName="note" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
</mat-form-field>
</div>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['../../general']">Cancel</button>
<button mat-raised-button color="primary" [disabled]="!chargeoffLoanForm.valid"
*mifosxHasPermission="'CHARGEOFF_LOAN'">Submit</button>
</mat-card-actions>
</mat-card-content>
</form>
</mat-card>
</div>
@@ -0,0 +1,4 @@
.container {
max-width: 37rem;
}
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ChargeOffComponent } from './charge-off.component';
describe('ChargeOffComponent', () => {
let component: ChargeOffComponent;
let fixture: ComponentFixture<ChargeOffComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChargeOffComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChargeOffComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,89 @@
import { Component, Input, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { Dates } from 'app/core/utils/dates';
import { LoansService } from 'app/loans/loans.service';
import { SettingsService } from 'app/settings/settings.service';
@Component({
selector: 'mifosx-charge-off',
templateUrl: './charge-off.component.html',
styleUrls: ['./charge-off.component.scss']
})
export class ChargeOffComponent implements OnInit {
@Input() dataObject: any;
/** Loan Id */
loanId: string;
/** Payment Type Options */
paymentTypes: any;
/** Show payment details */
showPaymentDetails = false;
/** Minimum Date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum Date allowed. */
maxDate = new Date();
/** Repayment Loan Form */
chargeoffLoanForm: FormGroup;
chargeOffReasonOptions: any = [];
/**
* @param {FormBuilder} formBuilder Form Builder.
* @param {LoansService} loanService Loan Service.
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
* @param {SettingsService} settingsService Settings Service
*/
constructor(private formBuilder: FormBuilder,
private loanService: LoansService,
private route: ActivatedRoute,
private router: Router,
private dateUtils: Dates,
private settingsService: SettingsService) {
this.loanId = this.route.snapshot.params['loanId'];
}
/**
* Creates the repayment loan form
* and initialize with the required values
*/
ngOnInit() {
this.maxDate = this.settingsService.businessDate;
this.chargeOffReasonOptions = this.dataObject.chargeOffReasonOptions;
this.createChargeoffLoanForm();
}
/**
* Creates the create close form.
*/
createChargeoffLoanForm() {
this.chargeoffLoanForm = this.formBuilder.group({
'transactionDate': [this.settingsService.businessDate, Validators.required],
'externalId': '',
'chargeOffReasonId': '',
'note': ''
});
}
submit() {
const chargeoffLoanFormData = this.chargeoffLoanForm.value;
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
const prevTransactionDate: Date = this.chargeoffLoanForm.value.transactionDate;
if (chargeoffLoanFormData.transactionDate instanceof Date) {
chargeoffLoanFormData.transactionDate = this.dateUtils.formatDate(prevTransactionDate, dateFormat);
}
const data = {
...chargeoffLoanFormData,
dateFormat,
locale
};
const command = 'charge-off';
this.loanService.submitLoanActionButton(this.loanId, data, command)
.subscribe((response: any) => {
this.router.navigate(['../../transactions'], { relativeTo: this.route });
});
}
}
@@ -25,3 +25,5 @@
<mifosx-approve-loan *ngIf="actions['Approve']" ></mifosx-approve-loan>
<mifosx-add-loan-charge *ngIf="actions['Add Loan Charge']"></mifosx-add-loan-charge>
<mifosx-edit-repayment-schedule *ngIf="actions['Edit Repayment Schedule']"></mifosx-edit-repayment-schedule>
<mifosx-charge-off [dataObject]="actionButtonData" *ngIf="actions['Charge-Off']"></mifosx-charge-off>
<mifosx-undo-command [actionName]="actionName" *ngIf="actions['Undo Charge-Off']"></mifosx-undo-command>
@@ -40,7 +40,9 @@ export class LoanAccountActionsComponent {
'Merchant Issued Refund': boolean,
'Payout Refund': boolean,
'Credit Balance Refund': boolean,
'Edit Repayment Schedule': boolean
'Edit Repayment Schedule': boolean,
'Charge-Off': boolean,
'Undo Charge-Off': boolean
} = {
'Close': false,
'Undo Approval': false,
@@ -69,7 +71,9 @@ export class LoanAccountActionsComponent {
'Merchant Issued Refund': false,
'Payout Refund': false,
'Credit Balance Refund': false,
'Edit Repayment Schedule': false
'Edit Repayment Schedule': false,
'Charge-Off': false,
'Undo Charge-Off': false
};
actionButtonData: any;
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, Input } from '@angular/core';
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
@@ -16,7 +16,7 @@ import { Dates } from 'app/core/utils/dates';
templateUrl: './make-repayment.component.html',
styleUrls: ['./make-repayment.component.scss']
})
export class MakeRepaymentComponent implements OnInit {
export class MakeRepaymentComponent implements OnInit, OnDestroy {
@Input() dataObject: any;
/** Loan Id */
@@ -58,6 +58,10 @@ export class MakeRepaymentComponent implements OnInit {
this.setRepaymentLoanDetails();
}
ngOnDestroy(): void {
}
/**
* Creates the create close form.
*/
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, Input } from '@angular/core';
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
@@ -17,7 +17,7 @@ import { Dates } from 'app/core/utils/dates';
templateUrl: './prepay-loan.component.html',
styleUrls: ['./prepay-loan.component.scss']
})
export class PrepayLoanComponent implements OnInit {
export class PrepayLoanComponent implements OnInit, OnDestroy {
@Input() dataObject: any;
/** Loan Id */
@@ -66,6 +66,9 @@ export class PrepayLoanComponent implements OnInit {
this.prepayData = this.dataObject;
}
ngOnDestroy(): void {
}
/**
* Creates the prepay loan form.
*/
@@ -1,273 +1,273 @@
/** Recurring Deposits Account Buttons Configuration */
export class LoansAccountButtonConfiguration {
optionArray: {
name: string,
taskPermissionName?: string,
}[];
optionArray: {
name: string,
taskPermissionName?: string,
}[];
optionPaymentArray: {
name: string,
taskPermissionName?: string,
}[];
optionPaymentArray: {
name: string,
taskPermissionName?: string,
}[];
buttonsArray: {
name: string,
icon: string,
taskPermissionName?: string,
}[];
buttonsArray: {
name: string,
icon: string,
taskPermissionName?: string,
}[];
constructor(status: string) {
this.setOptions(status);
this.setButtons(status);
}
get singleButtons() {
return this.buttonsArray;
}
get options() {
return this.optionArray;
}
get optionsPayment() {
return this.optionPaymentArray;
constructor(status: string) {
this.setOptions(status);
this.setButtons(status);
}
setButtons(status: string) {
switch (status) {
case 'Active':
this.buttonsArray = [
{
name: 'Add Loan Charge',
icon: 'plus',
taskPermissionName: 'CREATE_LOANCHARGE',
},
{
name: 'Foreclosure',
icon: 'heart-broken',
taskPermissionName: 'FORECLOSURE_LOAN',
},
{
name: 'Make Repayment',
icon: 'coins',
taskPermissionName: 'REPAYMENT_LOAN',
},
{
name: 'Undo Disbursal',
icon: 'undo',
taskPermissionName: 'DISBURSALUNDO_LOAN',
}
];
break;
case 'Submitted and pending approval':
this.buttonsArray = [
{
name: 'Add Loan Charge',
icon: 'plus',
taskPermissionName: 'CREATE_LOANCHARGE',
},
{
name: 'Approve',
icon: 'check',
taskPermissionName: 'APPROVE_LOAN',
},
{
name: 'Modify Application',
icon: 'edit',
taskPermissionName: 'UPDATE_LOAN',
},
{
name: 'Reject',
icon: 'times',
taskPermissionName: 'REJECT_LOAN',
},
];
break;
case 'Approved':
this.buttonsArray = [
{
name: 'Disburse',
icon: 'hand-holding-usd',
taskPermissionName: 'DISBURSE_LOAN',
},
{
name: 'Disburse to Savings',
icon: 'piggy-bank',
taskPermissionName: 'DISBURSETOSAVINGS_LOAN',
},
{
name: 'Undo Approval',
icon: 'undo',
taskPermissionName: 'APPROVALUNDO_LOAN',
},
];
break;
case 'Overpaid':
this.buttonsArray = [
{
name: 'Transfer Funds',
icon: 'exchange',
taskPermissionName: 'CREATE_ACCOUNTTRANSFER',
},
{
name: 'Credit Balance Refund',
icon: 'coins',
taskPermissionName: 'CREATE_CREDIT_BALANCE_REFUND',
}
];
break;
case 'Closed (written off)':
this.buttonsArray = [
{
name: 'Recovery Payment',
icon: 'briefcase',
taskPermissionName: 'RECOVERYPAYMENT_LOAN',
},
];
break;
case 'Closed (obligations met)':
this.buttonsArray = [
{
name: 'Goodwill Credit',
icon: 'coins',
taskPermissionName: 'CREATE_GOODWILL_TRANSACTION',
},
{
name: 'Payout Refund',
icon: 'coins',
taskPermissionName: 'CREATE_PAYOUT_REFUND',
},
{
name: 'Merchant Issued Refund',
icon: 'coins',
taskPermissionName: 'CREATE_MERCHANT_ISSUED_REFUND',
}
];
break;
default:
this.buttonsArray = [];
}
}
get singleButtons() {
return this.buttonsArray;
}
setOptions(status: string) {
switch (status) {
case 'Active':
this.optionArray = [
{
name: 'Waive Interest',
taskPermissionName: 'WAIVEINTERESTPORTION_LOAN',
},
{
name: 'Reschedule',
taskPermissionName: 'CREATE_RESCHEDULELOAN',
},
{
name: 'Write Off',
taskPermissionName: 'WRITEOFF_LOAN',
},
{
name: 'Close (as Rescheduled)',
taskPermissionName: 'CLOSEASRESCHEDULED_LOAN',
},
{
name: 'Close',
taskPermissionName: 'CLOSE_LOAN',
},
{
name: 'Loan Screen Report',
taskPermissionName: 'READ_LOAN',
},
{
name: 'View Guarantors',
taskPermissionName: 'READ_GUARANTOR',
},
{
name: 'Create Guarantor',
taskPermissionName: 'CREATE_GUARANTOR',
},
{
name: 'Recover From Guarantor',
taskPermissionName: 'RECOVERGUARANTEES_LOAN',
},
];
this.optionPaymentArray = [
{
name: 'Goodwill Credit',
taskPermissionName: 'CREATE_GOODWILL_TRANSACTION',
},
{
name: 'Payout Refund',
taskPermissionName: 'CREATE_PAYOUT_REFUND',
},
{
name: 'Merchant Issued Refund',
taskPermissionName: 'CREATE_MERCHANT_ISSUED_REFUND',
}
];
break;
case 'Submitted and pending approval':
this.optionArray = [
{
name: 'Withdrawn by client',
taskPermissionName: 'WITHDRAW_LOAN',
},
{
name: 'Delete',
taskPermissionName: 'DELETE_LOAN',
},
{
name: 'Add Collateral',
taskPermissionName: 'CREATE_COLLATERAL',
},
{
name: 'View Guarantors',
taskPermissionName: 'READ_GUARANTOR',
},
{
name: 'Create Guarantor',
taskPermissionName: 'CREATE_GUARANTOR',
},
{
name: 'Loan Screen Reports',
taskPermissionName: 'READ_LOAN',
},
];
this.optionPaymentArray = [];
break;
case 'Approved':
this.optionArray = [
{
name: 'Add Loan Charge',
taskPermissionName: 'CREATE_LOANCHARGE',
},
{
name: 'View Guarantors',
taskPermissionName: 'READ_GUARANTOR',
},
{
name: 'Create Guarantor',
taskPermissionName: 'CREATE_GUARANTOR',
},
{
name: 'Loan Screen Report',
taskPermissionName: 'READ_LOAN',
},
];
this.optionPaymentArray = [];
break;
default:
this.optionArray = [];
this.optionPaymentArray = [];
}
}
get options() {
return this.optionArray;
}
addOption(option: { name: string, icon?: string, taskPermissionName?: string }) {
this.optionArray.push(option);
}
get optionsPayment() {
return this.optionPaymentArray;
}
addButton(option: { name: string, icon: string, taskPermissionName?: string }) {
this.buttonsArray.push(option);
setButtons(status: string) {
switch (status) {
case 'Active':
this.buttonsArray = [
{
name: 'Add Loan Charge',
icon: 'plus',
taskPermissionName: 'CREATE_LOANCHARGE',
},
{
name: 'Foreclosure',
icon: 'heart-broken',
taskPermissionName: 'FORECLOSURE_LOAN',
},
{
name: 'Make Repayment',
icon: 'coins',
taskPermissionName: 'REPAYMENT_LOAN',
},
{
name: 'Undo Disbursal',
icon: 'undo',
taskPermissionName: 'DISBURSALUNDO_LOAN',
}
];
break;
case 'Submitted and pending approval':
this.buttonsArray = [
{
name: 'Add Loan Charge',
icon: 'plus',
taskPermissionName: 'CREATE_LOANCHARGE',
},
{
name: 'Approve',
icon: 'check',
taskPermissionName: 'APPROVE_LOAN',
},
{
name: 'Modify Application',
icon: 'edit',
taskPermissionName: 'UPDATE_LOAN',
},
{
name: 'Reject',
icon: 'times',
taskPermissionName: 'REJECT_LOAN',
},
];
break;
case 'Approved':
this.buttonsArray = [
{
name: 'Disburse',
icon: 'hand-holding-usd',
taskPermissionName: 'DISBURSE_LOAN',
},
{
name: 'Disburse to Savings',
icon: 'piggy-bank',
taskPermissionName: 'DISBURSETOSAVINGS_LOAN',
},
{
name: 'Undo Approval',
icon: 'undo',
taskPermissionName: 'APPROVALUNDO_LOAN',
},
];
break;
case 'Overpaid':
this.buttonsArray = [
{
name: 'Transfer Funds',
icon: 'exchange',
taskPermissionName: 'CREATE_ACCOUNTTRANSFER',
},
{
name: 'Credit Balance Refund',
icon: 'coins',
taskPermissionName: 'CREATE_CREDIT_BALANCE_REFUND',
}
];
break;
case 'Closed (written off)':
this.buttonsArray = [
{
name: 'Recovery Payment',
icon: 'briefcase',
taskPermissionName: 'RECOVERYPAYMENT_LOAN',
},
];
break;
case 'Closed (obligations met)':
this.buttonsArray = [
{
name: 'Goodwill Credit',
icon: 'coins',
taskPermissionName: 'CREATE_GOODWILL_TRANSACTION',
},
{
name: 'Payout Refund',
icon: 'coins',
taskPermissionName: 'CREATE_PAYOUT_REFUND',
},
{
name: 'Merchant Issued Refund',
icon: 'coins',
taskPermissionName: 'CREATE_MERCHANT_ISSUED_REFUND',
}
];
break;
default:
this.buttonsArray = [];
}
}
setOptions(status: string) {
switch (status) {
case 'Active':
this.optionArray = [
{
name: 'Waive Interest',
taskPermissionName: 'WAIVEINTERESTPORTION_LOAN',
},
{
name: 'Reschedule',
taskPermissionName: 'CREATE_RESCHEDULELOAN',
},
{
name: 'Write Off',
taskPermissionName: 'WRITEOFF_LOAN',
},
{
name: 'Close (as Rescheduled)',
taskPermissionName: 'CLOSEASRESCHEDULED_LOAN',
},
{
name: 'Close',
taskPermissionName: 'CLOSE_LOAN',
},
{
name: 'Loan Screen Report',
taskPermissionName: 'READ_LOAN',
},
{
name: 'View Guarantors',
taskPermissionName: 'READ_GUARANTOR',
},
{
name: 'Create Guarantor',
taskPermissionName: 'CREATE_GUARANTOR',
},
{
name: 'Recover From Guarantor',
taskPermissionName: 'RECOVERGUARANTEES_LOAN',
}
];
this.optionPaymentArray = [
{
name: 'Goodwill Credit',
taskPermissionName: 'CREATE_GOODWILL_TRANSACTION',
},
{
name: 'Payout Refund',
taskPermissionName: 'CREATE_PAYOUT_REFUND',
},
{
name: 'Merchant Issued Refund',
taskPermissionName: 'CREATE_MERCHANT_ISSUED_REFUND',
}
];
break;
case 'Submitted and pending approval':
this.optionArray = [
{
name: 'Withdrawn by client',
taskPermissionName: 'WITHDRAW_LOAN',
},
{
name: 'Delete',
taskPermissionName: 'DELETE_LOAN',
},
{
name: 'Add Collateral',
taskPermissionName: 'CREATE_COLLATERAL',
},
{
name: 'View Guarantors',
taskPermissionName: 'READ_GUARANTOR',
},
{
name: 'Create Guarantor',
taskPermissionName: 'CREATE_GUARANTOR',
},
{
name: 'Loan Screen Reports',
taskPermissionName: 'READ_LOAN',
},
];
this.optionPaymentArray = [];
break;
case 'Approved':
this.optionArray = [
{
name: 'Add Loan Charge',
taskPermissionName: 'CREATE_LOANCHARGE',
},
{
name: 'View Guarantors',
taskPermissionName: 'READ_GUARANTOR',
},
{
name: 'Create Guarantor',
taskPermissionName: 'CREATE_GUARANTOR',
},
{
name: 'Loan Screen Report',
taskPermissionName: 'READ_LOAN',
},
];
this.optionPaymentArray = [];
break;
default:
this.optionArray = [];
this.optionPaymentArray = [];
}
}
addOption(option: { name: string, icon?: string, taskPermissionName?: string }) {
this.optionArray.push(option);
}
addButton(option: { name: string, icon: string, taskPermissionName?: string }) {
this.buttonsArray.push(option);
}
}
@@ -6,8 +6,9 @@
<div class="profile-image-container">
<div>
<img mat-card-md-image class="profile-image" matTooltip="Loans Account"
[src]="'assets/images/loans_account_placeholder.png'">
<mifosx-svg-icon [iconClass]="" iconFile="account_placeholder"
iconName="LOAN_ACCOUNT" iconWidth="210" matTooltip="Loan Account">
</mifosx-svg-icon>
</div>
</div>
@@ -18,7 +19,7 @@
<div fxFlex="60%">
<h3>
<i class="fa fa-stop" matTooltip="{{ loanDetailsData.status.value }}"
[ngClass]="loanDetailsData.inArrears?'status-active-overdue':(loanDetailsData.status.code|statusLookup)"></i>
[ngClass]="loanDetailsData.inArrears?'status-active-overdue':( iconLoanStatusColor() | statusLookup)"></i>
Loan Product: {{loanDetailsData.loanProductName}}<span
class="m-l-10">({{loanDetailsData.accountNo}})</span>
</h3>
@@ -147,6 +147,17 @@ export class LoansViewComponent implements OnInit {
});
}
if (!this.loanDetailsData.chargedOff) {
// Charge-Off only when there is not Interest Recalculation and the Interest Rate is zero
if (!this.loanDetailsData.chargedOff && !this.loanDetailsData.isInterestRecalculationEnabled && this.loanDetailsData.interestRatePerPeriod === 0) {
this.buttonConfig.addButton({
name: 'Charge-Off',
icon: 'coins',
taskPermissionName: 'CHARGEOFF_LOAN'
});
}
}
}
}
@@ -187,6 +198,13 @@ export class LoansViewComponent implements OnInit {
});
}
iconLoanStatusColor() {
if (this.loanDetailsData.chargedOff) {
return 'loanStatusType.chargeoff';
}
return this.loanDetailsData.status.code;
}
/**
* Delete loan Account
*/
@@ -1,7 +1,8 @@
<div class="container">
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="20px" class="transaction-buttons" *ngIf="checkStatus()">
<mat-checkbox [formControl]="hideAccrualsParam" (click)="hideAccruals()" class="accruals">Hide Accruals</mat-checkbox>
<mat-checkbox [formControl]="hideAccrualsParam" (click)="hideAccruals()" class="accruals">Hide
Accruals</mat-checkbox>
<button mat-raised-button color="primary" class="transaction-button" [routerLink]="['export']">
Export
</button>
@@ -12,76 +13,90 @@
<table mat-table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Id </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.id }} </td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Id </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.id }}
</td>
</ng-container>
<ng-container matColumnDef="office">
<th mat-header-cell *matHeaderCellDef> Office </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.officeName }} </td>
</ng-container>
<ng-container matColumnDef="office">
<th mat-header-cell *matHeaderCellDef> Office </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{
transaction.officeName }} </td>
</ng-container>
<ng-container matColumnDef="externalId">
<th mat-header-cell *matHeaderCellDef> External Id </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)">
<mifosx-external-identifier externalId="{{transaction.externalId}}"></mifosx-external-identifier>
</td>
</ng-container>
<ng-container matColumnDef="externalId">
<th mat-header-cell *matHeaderCellDef> External Id </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)">
<mifosx-external-identifier externalId="{{transaction.externalId}}"></mifosx-external-identifier>
</td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Transaction Date </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.date | dateFormat }} </td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Transaction Date </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.date | dateFormat }} </td>
</ng-container>
<ng-container matColumnDef="transactionType">
<th mat-header-cell *matHeaderCellDef> Transaction Type </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.type.value }} </td>
</ng-container>
<ng-container matColumnDef="transactionType">
<th mat-header-cell *matHeaderCellDef> Transaction Type </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{
transaction.type.value }} </td>
</ng-container>
<ng-container matColumnDef="amount">
<th mat-header-cell class="center" *matHeaderCellDef> Amount </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.amount | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="amount">
<th mat-header-cell class="center" *matHeaderCellDef> Amount </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction"
[ngClass]="loanTransactionColor(transaction)"> {{ transaction.amount | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="principal">
<th mat-header-cell class="center" *matHeaderCellDef> Breakdown </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.principalPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="principal">
<th mat-header-cell class="center" *matHeaderCellDef> Breakdown </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction"
[ngClass]="loanTransactionColor(transaction)"> {{ transaction.principalPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="interest">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.interestPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="interest">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction"
[ngClass]="loanTransactionColor(transaction)"> {{ transaction.interestPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="fee">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.feeChargesPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="fee">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction"
[ngClass]="loanTransactionColor(transaction)"> {{ transaction.feeChargesPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="penalties">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.penaltyChargesPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="penalties">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction"
[ngClass]="loanTransactionColor(transaction)"> {{ transaction.penaltyChargesPortion | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="loanBalance">
<th mat-header-cell class="r-amount" *matHeaderCellDef> Loan Balance </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction" [ngClass]="loanTransactionColor(transaction)"> {{ transaction.outstandingLoanBalance | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="loanBalance">
<th mat-header-cell class="r-amount" *matHeaderCellDef> Loan Balance </th>
<td mat-cell class="r-amount td-min-space" *matCellDef="let transaction"
[ngClass]="loanTransactionColor(transaction)"> {{ transaction.outstandingLoanBalance | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell class="center" *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let transaction" class="center td-min-space">
<button class="account-action-button" *ngIf="!transaction.manuallyReversed" mat-raised-button color="primary" (click)="routeEdit($event)"
[routerLink]="[transaction.id, 'reciept']" matTooltip="View Receipts">
<i class="fa fa-file-text"></i>
</button>
<button class="account-action-button" mat-raised-button color="primary" matTooltip="View Journal Entries" matTooltipPosition="left"
(click)="routeEdit($event)" [routerLink]="['/','journal-entry', 'view', 'L'+transaction.id ]">
<i class="fa fa-arrow-circle-right"></i>
</button>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell class="center" *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let transaction" class="center td-min-space">
<button class="account-action-button" *ngIf="allowUndoTransaction(transaction)" mat-raised-button color="primary" matTooltip="Undo Transaction"
matTooltipPosition="left" (click)="undoTransaction(transaction, $event)">
<i class="fa fa-undo"></i>
</button>
<button class="account-action-button" *ngIf="!transaction.manuallyReversed" mat-raised-button color="primary"
(click)="routeEdit($event)" [routerLink]="[transaction.id, 'reciept']" matTooltip="View Receipts">
<i class="fa fa-file-text"></i>
</button>
<button class="account-action-button" mat-raised-button color="primary" matTooltip="View Journal Entries"
matTooltipPosition="left" (click)="routeEdit($event)"
[routerLink]="['/','journal-entry', 'view', 'L'+transaction.id ]">
<i class="fa fa-arrow-circle-right"></i>
</button>
</td>
</ng-container>
<!-- Sub header -->
<ng-container matColumnDef="header">
@@ -105,15 +120,18 @@
</ng-container>
<ng-container matColumnDef="header-action">
<th mat-header-cell *matHeaderCellDef [attr.colspan]="1"> </th>
<th mat-header-cell *matHeaderCellDef [attr.colspan]="1"> </th>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-header-row *matHeaderRowDef="['header', 'header-principal', 'header-interest', 'header-fees', 'header-penalties', 'header-action']"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row" (click)="showTransactions(row)"></tr>
<tr mat-header-row
*matHeaderRowDef="['header', 'header-principal', 'header-interest', 'header-fees', 'header-penalties', 'header-action']">
</tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row" (click)="showTransactions(row)">
</tr>
</table>
<mat-paginator [pageSize]="50" [pageSizeOptions]="[50, 100, 200]" showFirstLastButtons></mat-paginator>
<mat-paginator [pageSize]="100" [pageSizeOptions]="[50, 100, 200]" showFirstLastButtons></mat-paginator>
</div>
@@ -32,6 +32,9 @@
.accrual {
color: $msg-default;
}
.chargeoff {
color: $status-chargeoff;
}
}
}
@@ -4,6 +4,11 @@ import { FormControl } from '@angular/forms';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Dates } from 'app/core/utils/dates';
import { LoansService } from 'app/loans/loans.service';
import { MatDialog } from '@angular/material/dialog';
import { SettingsService } from 'app/settings/settings.service';
import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component';
@Component({
selector: 'mifosx-transactions-tab',
@@ -32,7 +37,11 @@ export class TransactionsTabComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
*/
constructor(private route: ActivatedRoute,
private router: Router) {
private dateUtils: Dates,
private router: Router,
private dialog: MatDialog,
private loansService: LoansService,
private settingsService: SettingsService) {
this.route.parent.parent.data.subscribe((data: { loanDetailsData: any }) => {
this.transactions = data.loanDetailsData.transactions;
this.tempTransaction = data.loanDetailsData.transactions;
@@ -42,6 +51,14 @@ export class TransactionsTabComponent implements OnInit {
ngOnInit() {
this.hideAccrualsParam = new FormControl(false);
this.setLoanTransactions(this.transactions);
}
setLoanTransactions(transactions: any) {
this.transactions = transactions;
this.transactions.forEach((element: any) => {
element.date = this.dateUtils.parseDate(element.date);
});
this.dataSource = new MatTableDataSource(this.transactions);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
@@ -99,16 +116,26 @@ export class TransactionsTabComponent implements OnInit {
}
}
loanTransactionColor(loanTransaction: any): string {
if (loanTransaction.manuallyReversed) {
allowUndoTransaction(transaction: any) {
if (transaction.manuallyReversed) {
return false;
}
return ([27].includes(transaction.type.id));
}
loanTransactionColor(transaction: any): string {
if (transaction.manuallyReversed) {
return 'strike';
}
if (loanTransaction.transactionRelations && loanTransaction.transactionRelations.length > 0) {
if (transaction.transactionRelations && transaction.transactionRelations.length > 0) {
return 'linked';
}
if (this.isAccrual(loanTransaction.type)) {
if (this.isAccrual(transaction.type)) {
return 'accrual';
}
if (this.isChargeOff(transaction.type)) {
return 'chargeoff';
}
return '';
}
@@ -120,8 +147,59 @@ export class TransactionsTabComponent implements OnInit {
$event.stopPropagation();
}
/**
* Stops the propagation to view pages.
* @param $event Mouse Event
*/
undoTransaction(transaction: any, $event: MouseEvent) {
$event.stopPropagation();
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
const loanId = this.route.parent.parent.snapshot.params['loanId'];
let command = 'undo';
let operationDate = transaction.date;
let payload = {};
if (this.isChargeOff(transaction.type)) {
command = 'undo-charge-off';
operationDate = this.settingsService.businessDate;
}
payload = {
transactionDate: this.dateUtils.formatDate(operationDate && new Date(operationDate), dateFormat),
transactionAmount: 0,
dateFormat,
locale
};
const undoTransactionAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, {
data: { heading: 'Undo Transaction', dialogContext: `Are you sure you want undo the transaction type ${transaction.type.value} with id ${transaction.id}` }
});
undoTransactionAccountDialogRef.afterClosed().subscribe((response: { confirm: any }) => {
if (response.confirm) {
let transactionId = transaction.id;
if (this.isChargeOff(transaction.type)) {
transactionId = null;
}
this.loansService.executeLoansAccountTransactionsCommand(loanId, command, payload, transactionId).subscribe((responseCmd: any) => {
transaction.manuallyReversed = true;
this.reload();
});
}
});
}
private isAccrual(transactionType: any): boolean {
return (transactionType.accrual || transactionType.code === 'loanTransactionType.overdueCharge');
}
private isChargeOff(transactionType: any): boolean {
return (transactionType.chargeoff || transactionType.code === 'loanTransactionType.chargeOff');
}
private reload() {
const clientId = this.route.parent.parent.snapshot.params['clientId'];
const loanId = this.route.parent.parent.snapshot.params['loanId'];
const url: string = this.router.url;
this.router.navigateByUrl(`/clients/${clientId}/loans-accounts`, { skipLocationChange: true })
.then(() => this.router.navigate([url]));
}
}
+3 -1
View File
@@ -74,6 +74,7 @@ import { DisburseToSavingsAccountComponent } from './loans-view/loan-account-act
import { LoansAccountDatatableStepComponent } from './loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component';
import { RescheduleLoanTabComponent } from './loans-view/reschedule-loan-tab/reschedule-loan-tab.component';
import { AdjustLoanChargeComponent } from './loans-view/loan-account-actions/adjust-loan-charge/adjust-loan-charge.component';
import { ChargeOffComponent } from './loans-view/loan-account-actions/charge-off/charge-off.component';
/**
* Loans Module
@@ -146,7 +147,8 @@ import { AdjustLoanChargeComponent } from './loans-view/loan-account-actions/adj
DisburseToSavingsAccountComponent,
LoansAccountDatatableStepComponent,
RescheduleLoanTabComponent,
AdjustLoanChargeComponent
AdjustLoanChargeComponent,
ChargeOffComponent
],
providers: [ ],
})
-1
View File
@@ -589,7 +589,6 @@ export class LoansService {
delete loansAccountData.principalAmount;
return loansAccountData;
}
}
@@ -20,8 +20,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!smsCampaignFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -59,7 +59,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -113,8 +113,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
+1
View File
@@ -16,6 +16,7 @@ export class StatusLookupPipe implements PipeTransform {
'loanStatusType.approved': 'status-approved',
'loanStatusType.active': 'status-active',
'loanStatusType.overpaid': 'status-overpaid',
'loanStatusType.chargeoff': 'status-chargeoff',
'savingsAccountStatusType.submitted.and.pending.approval': 'status-pending',
'savingsAccountStatusType.approved': 'status-approved',
'savingsAccountStatusType.active': 'status-active',
@@ -245,8 +245,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!fixedDepositProductFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -68,7 +68,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -38,8 +38,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -34,8 +34,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -221,8 +221,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -97,7 +97,7 @@
<mat-divider fxFlex="98%"></mat-divider>
<mat-checkbox fxFlex="48%" labelPosition="before" formControlName="withHoldTax" class="margin-v" matTooltip="An boolean flag to attach taxes to interest posting">
Is Withhold Tax Applicable?
Is Withhold Tax Applicable?
</mat-checkbox>
<mat-form-field fxFlex="48%" *ngIf="fixedDepositProductSettingsForm.value.withHoldTax">
@@ -120,8 +120,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -19,7 +19,7 @@
<mat-form-field fxFlex="31%">
<mat-label>Maximum</mat-label>
<input type="number" matInput formControlName="maxDepositAmount" matTooltip="The maximum deposit amount allowed when a fixed deposit account based on this fixed deposit product is opened.">
</mat-form-field>
@@ -81,8 +81,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -429,8 +429,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!loanProductFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -134,7 +134,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -46,8 +46,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -58,8 +58,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -466,8 +466,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -396,8 +396,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -256,8 +256,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!recurringDepositProductFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -70,7 +70,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -38,8 +38,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -34,8 +34,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -61,7 +61,7 @@
</div>
<div fxFlex="100%" *ngIf="chart.value.chartSlabs.length === 0">
<h3 class="mat-h3">It's required to add at least one Slab</h3>
<h3 class="mat-h3">It's required to add at least one Slab</h3>
</div>
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chart.value.chartSlabs" *ngIf="chart.value.chartSlabs.length !== 0" multiTemplateDataRows>
@@ -221,8 +221,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -134,8 +134,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -80,8 +80,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -293,8 +293,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!savingProductFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -68,7 +68,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -38,8 +38,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -31,8 +31,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -127,8 +127,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -68,8 +68,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -84,8 +84,8 @@
Previous
</button>
<button mat-raised-button matStepperNext [disabled]="!shareProductFormValid">
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -68,7 +68,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -38,8 +38,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -31,8 +31,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -50,7 +50,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -66,8 +66,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -42,8 +42,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -138,7 +138,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -47,8 +47,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -144,8 +144,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
+5 -2
View File
@@ -35,6 +35,7 @@ import { DirectivesModule } from 'app/directives/directives.module';
import { EntityDatatableTabComponent } from './tabs/entity-datatable-tab/entity-datatable-tab.component';
import { DatatableSingleRowComponent } from './tabs/entity-datatable-tab/datatable-single-row/datatable-single-row.component';
import { DatatableMultiRowComponent } from './tabs/entity-datatable-tab/datatable-multi-row/datatable-multi-row.component';
import { SvgIconComponent } from './svg-icon/svg-icon.component';
/**
* Shared Module
@@ -75,7 +76,8 @@ import { DatatableMultiRowComponent } from './tabs/entity-datatable-tab/datatabl
EntityDocumentsTabComponent,
EntityDatatableTabComponent,
DatatableSingleRowComponent,
DatatableMultiRowComponent
DatatableMultiRowComponent,
SvgIconComponent
],
exports: [
FileUploadComponent,
@@ -96,7 +98,8 @@ import { DatatableMultiRowComponent } from './tabs/entity-datatable-tab/datatabl
ExternalIdentifierComponent,
EntityNotesTabComponent,
EntityDocumentsTabComponent,
EntityDatatableTabComponent
EntityDatatableTabComponent,
SvgIconComponent
]
})
export class SharedModule { }
@@ -0,0 +1,3 @@
<svg preserveAspectRatio="xMidYMid meet" class="icon" [ngClass]="iconClass" [style.width.px]="iconWidth">
<use [attr.xlink:href]="'assets/images/icons_' + iconFile + '.svg#' + iconName"></use>
</svg>

After

Width:  |  Height:  |  Size: 202 B

@@ -0,0 +1,9 @@
@import "assets/styles/helper";
.icon {
flex: 1;
}
.chargeoff {
color: #ffa726;
}
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SvgIconComponent } from './svg-icon.component';
describe('SvgIconComponent', () => {
let component: SvgIconComponent;
let fixture: ComponentFixture<SvgIconComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SvgIconComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SvgIconComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,19 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'mifosx-svg-icon',
templateUrl: './svg-icon.component.html',
styleUrls: ['./svg-icon.component.scss']
})
export class SvgIconComponent implements OnInit {
@Input() iconFile: string;
@Input() iconName: string;
@Input() iconClass: string;
@Input() iconWidth: string;
constructor() { }
ngOnInit(): void {
}
}
@@ -71,7 +71,7 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -38,8 +38,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
@@ -97,8 +97,8 @@
Previous
</button>
<button mat-raised-button matStepperNext>
Next&nbsp;&nbsp;
<fa-icon icon="arrow-right"></fa-icon>
Next
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>