Loan Repayment Schedule edition to have variations (#1608)
Co-authored-by: Jose Alberto Hernandez <alberto@MacBook-Pro.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
25ca2b7bb0
commit
6431ede355
@@ -16,7 +16,7 @@ export class ApiPrefixInterceptor implements HttpInterceptor {
|
||||
/**
|
||||
* @param {SettingsService} settingsService Settings Service
|
||||
*/
|
||||
constructor(private settingsService: SettingsService) {}
|
||||
constructor(private settingsService: SettingsService) { }
|
||||
|
||||
/**
|
||||
* Intercepts a Http request and prefixes it with `serverUrl`.
|
||||
@@ -25,7 +25,7 @@ export class ApiPrefixInterceptor implements HttpInterceptor {
|
||||
/**
|
||||
* Ignore URLs that are complete for i18n
|
||||
*/
|
||||
if (!request.url.includes('http:') && !request.url.includes('https:')) {
|
||||
if (!request.url.includes('http:') && !request.url.includes('https:')) {
|
||||
request = request.clone({ url: this.settingsService.serverUrl + request.url });
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -2,9 +2,20 @@
|
||||
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<mifosx-loans-account-schedule-step></mifosx-loans-account-schedule-step>
|
||||
|
||||
<div fxLayout="column">
|
||||
<mifosx-repayment-schedule-tab fxFlex="100%"
|
||||
[repaymentScheduleDetails]="repaymentScheduleDetails"
|
||||
[forEditing]="true">
|
||||
</mifosx-repayment-schedule-tab>
|
||||
</div>
|
||||
|
||||
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../../general']">Cancel</button>
|
||||
<button type="button" (click)="reset()">Reset</button>
|
||||
<button type="button" color="primary" mat-raised-button (click)="applyPattern()">Pattern</button>
|
||||
<button type="button" color="primary" mat-raised-button [disabled]="!wasChanged" (click)="validate()">Validate</button>
|
||||
<button type="button" color="primary" mat-raised-button [disabled]="!wasValidated" (click)="submit()">Submit</button>
|
||||
</mat-card-actions>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
+152
-1
@@ -1,4 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
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';
|
||||
import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component';
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
import { DatepickerBase } from 'app/shared/form-dialog/formfield/model/datepicker-base';
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-edit-repayment-schedule',
|
||||
@@ -7,9 +18,149 @@ import { Component, OnInit } from '@angular/core';
|
||||
})
|
||||
export class EditRepaymentScheduleComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
/** Loan ID. */
|
||||
loanId: string;
|
||||
/** Indicates If the Schedule has been changed */
|
||||
wasChanged = false;
|
||||
/** Indicates If the Schedule has been validated */
|
||||
wasValidated = false;
|
||||
/** Stores the Repayment Schedule data */
|
||||
repaymentScheduleDetails: any[] = [];
|
||||
/** Stores the Installments changed */
|
||||
repaymentScheduleChanges: any = {};
|
||||
|
||||
/**
|
||||
* @param {LoansService} systemService Loan Service.
|
||||
* @param {Router} router Router for navigation.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
* @param {MatDialog} dialog Confirmation Dialogs.
|
||||
* @param {Dates} dateUtils Dates Utils.
|
||||
* @param {SettingsService} settingsService Settings Service
|
||||
*/
|
||||
constructor(private loansService: LoansService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private dialog: MatDialog,
|
||||
private dateUtils: Dates,
|
||||
private settingsService: SettingsService) {
|
||||
this.loanId = this.route.parent.snapshot.params['loanId'];
|
||||
this.getRepaymentSchedule();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.repaymentScheduleChanges = {};
|
||||
}
|
||||
|
||||
getRepaymentSchedule(): void {
|
||||
this.loansService.getLoanAccountResource(this.loanId, 'repaymentSchedule').subscribe((response: any) => {
|
||||
this.repaymentScheduleDetails = response.repaymentSchedule;
|
||||
});
|
||||
}
|
||||
|
||||
applyPattern(): void {
|
||||
const periods: any = [];
|
||||
this.repaymentScheduleDetails['periods'].forEach((period: any) => {
|
||||
if (period.period) {
|
||||
periods.push({idx: period.period, dueDate: this.dateUtils.formatDate(period.dueDate, this.settingsService.dateFormat) });
|
||||
}
|
||||
});
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'fromPeriod',
|
||||
label: 'From Date',
|
||||
value: '',
|
||||
options: { label: 'dueDate', value: 'idx', data: periods },
|
||||
required: true
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'toPeriod',
|
||||
label: 'To Date',
|
||||
value: '',
|
||||
options: { label: 'dueDate', value: 'idx', data: periods },
|
||||
required: true
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'amount',
|
||||
label: 'Installment Amount',
|
||||
value: '',
|
||||
type: 'number',
|
||||
required: true
|
||||
}),
|
||||
];
|
||||
const data = {
|
||||
title: 'Pattern Update',
|
||||
formfields: formfields
|
||||
};
|
||||
const addDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
addDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
const fromPeriod = response.data.value.fromPeriod;
|
||||
const toPeriod = response.data.value.toPeriod;
|
||||
const amount = response.data.value.amount;
|
||||
const periodsVariation: any = [];
|
||||
this.repaymentScheduleDetails['periods'].forEach((period: any) => {
|
||||
const dueDate = this.dateUtils.formatDate(period.dueDate, this.settingsService.dateFormat);
|
||||
if (period.period && fromPeriod <= period.period && toPeriod >= period.period) {
|
||||
if (period.totalDueForPeriod !== amount) {
|
||||
period.totalDueForPeriod = amount;
|
||||
this.repaymentScheduleChanges[dueDate] = {dueDate: dueDate, installmentAmount: amount};
|
||||
this.wasChanged = true;
|
||||
period['changed'] = true;
|
||||
}
|
||||
}
|
||||
periodsVariation.push(period);
|
||||
});
|
||||
this.repaymentScheduleDetails['periods'] = periodsVariation;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
const recoverScheduleDialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
data: { heading: 'Recover Original Schedule', dialogContext: 'Are you sure you want recover the Original Schedule'}
|
||||
});
|
||||
recoverScheduleDialogRef.afterClosed().subscribe((responseConfirmation: any) => {
|
||||
if (responseConfirmation.confirm) {
|
||||
this.loansService.applyCommandLoanScheduleVariations(this.loanId, 'deleteVariations', {}).subscribe((response: any) => {
|
||||
this.getRepaymentSchedule();
|
||||
this.wasChanged = false;
|
||||
this.wasValidated = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
validate(): void {
|
||||
this.loansService.applyCommandLoanScheduleVariations(this.loanId, 'calculateLoanSchedule', this.getPayload()).subscribe((response: any) => {
|
||||
this.repaymentScheduleDetails['periods'] = [];
|
||||
response['periods'].forEach((period: any) => {
|
||||
period['changed'] = true;
|
||||
this.repaymentScheduleDetails['periods'].push(period);
|
||||
this.wasValidated = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
submit(): void {
|
||||
this.loansService.applyCommandLoanScheduleVariations(this.loanId, 'addVariations', this.getPayload()).subscribe((response: any) => {
|
||||
this.router.navigate(['../../repayment-schedule'], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
|
||||
private getPayload(): any {
|
||||
const modifiedinstallments: any = [];
|
||||
Object.keys(this.repaymentScheduleChanges).forEach((key: string) => {
|
||||
modifiedinstallments.push(this.repaymentScheduleChanges[key]);
|
||||
});
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const locale = this.settingsService.language.code;
|
||||
return {
|
||||
exceptions: {
|
||||
modifiedinstallments
|
||||
},
|
||||
dateFormat,
|
||||
locale
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ export class LoanAccountActionsComponent {
|
||||
'Goodwill Credit': boolean,
|
||||
'Merchant Issued Refund': boolean,
|
||||
'Payout Refund': boolean,
|
||||
'Credit Balance Refund': boolean
|
||||
'Credit Balance Refund': boolean,
|
||||
'Edit Repayment Schedule': boolean
|
||||
} = {
|
||||
'Close': false,
|
||||
'Undo Approval': false,
|
||||
@@ -67,7 +68,8 @@ export class LoanAccountActionsComponent {
|
||||
'Goodwill Credit': false,
|
||||
'Merchant Issued Refund': false,
|
||||
'Payout Refund': false,
|
||||
'Credit Balance Refund': false
|
||||
'Credit Balance Refund': false,
|
||||
'Edit Repayment Schedule': false
|
||||
};
|
||||
|
||||
actionButtonData: any;
|
||||
|
||||
+8
-4
@@ -4,10 +4,14 @@
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Note</mat-label>
|
||||
<textarea matInput [formControl]="note" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||
</mat-form-field>
|
||||
<div fxLayout="column">
|
||||
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Note</mat-label>
|
||||
<textarea matInput required [formControl]="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>
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/** Angular Imports */
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormControl, FormBuilder } from '@angular/forms';
|
||||
import { FormControl, FormBuilder, Validators } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
|
||||
/** Custom Services */
|
||||
@@ -40,7 +40,7 @@ export class UndoDisbursalComponent implements OnInit {
|
||||
* Creates the undo disbursal form.
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.note = this.formBuilder.control('');
|
||||
this.note = this.formBuilder.control('', Validators.required);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,15 +53,16 @@ export class LoansViewComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
this.recalculateInterest = this.loanDetailsData.recalculateInterest || true;
|
||||
this.status = this.loanDetailsData.status.value;
|
||||
this.setConditionalButtons();
|
||||
|
||||
if (this.loanDetailsData.multiDisburseLoan) {
|
||||
this.loanDetailsData.transactions.forEach((tranaction: any) => {
|
||||
if (tranaction.type.disbursement) {
|
||||
this.disburseTransactionNo++;
|
||||
}
|
||||
});
|
||||
if (this.loanDetailsData.status.active && this.loanDetailsData.multiDisburseLoan) {
|
||||
if (this.loanDetailsData) {
|
||||
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')) {
|
||||
|
||||
+75
-5
@@ -1,6 +1,6 @@
|
||||
<div class="container">
|
||||
|
||||
<table mat-table [dataSource]="repaymentScheduleDetails.periods">
|
||||
<table mat-table [dataSource]="repaymentScheduleDetails.periods" *ngIf="!forEditing">
|
||||
|
||||
<ng-container matColumnDef="number">
|
||||
<th mat-header-cell class="center" *matHeaderCellDef> # </th>
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell class="center" *matHeaderCellDef> Date </th>
|
||||
<td mat-cell class="center" *matCellDef="let ele"> {{ ele.dueDate | dateFormat}} </td>
|
||||
<td mat-cell class="m-r-5" *matCellDef="let ele"> {{ ele.dueDate | dateFormat}} </td>
|
||||
<td mat-footer-cell *matFooterCellDef> </td>
|
||||
</ng-container>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<ng-container matColumnDef="check">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell class="center" *matCellDef="let ele">
|
||||
<span *ngIf="ele.obligationsMetOnDate"> <i class='fa fa-check'></i> </span>
|
||||
<span *ngIf="ele.obligationsMetOnDate"> <i class="fa fa-check"></i> </span>
|
||||
</td>
|
||||
<td mat-footer-cell *matFooterCellDef> </td>
|
||||
</ng-container>
|
||||
@@ -133,6 +133,76 @@
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<!-- Repayment Schedule to be Edited -->
|
||||
<div *ngIf="forEditing" fxLayout="column" fxFlex="100%" >
|
||||
|
||||
<!-- <p>It works</p> -->
|
||||
<table mat-table [dataSource]="repaymentScheduleDetails.periods">
|
||||
|
||||
<ng-container matColumnDef="number">
|
||||
<th mat-header-cell class="center" *matHeaderCellDef> # </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.period }} </td>
|
||||
<td mat-footer-cell *matFooterCellDef> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell class="center" *matHeaderCellDef> Date </th>
|
||||
<td mat-cell class="m-r-10" *matCellDef="let ele"> {{ ele.dueDate | dateFormat}} </td>
|
||||
<td mat-footer-cell *matFooterCellDef> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="balanceOfLoan">
|
||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Balance Of Loan </th>
|
||||
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.principalLoanBalanceOutstanding | number }} </td>
|
||||
<td mat-footer-cell class="r-amount" *matFooterCellDef> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="principalDue">
|
||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Principal Due </th>
|
||||
<td mat-cell class="check r-amount" *matCellDef="let ele"> {{ ele.principalDue | number }} </td>
|
||||
<td mat-footer-cell class="check r-amount" *matFooterCellDef> <b> {{ repaymentScheduleDetails.totalPrincipalExpected | currency }}</b> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="interest">
|
||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Interest </th>
|
||||
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.interestOriginalDue | number}} </td>
|
||||
<td mat-footer-cell class="r-amount" *matFooterCellDef> <b> {{ repaymentScheduleDetails.totalInterestCharged | currency }} </b> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fees">
|
||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.feeChargesDue | number}} </td>
|
||||
<td mat-footer-cell class="r-amount" *matFooterCellDef> <b> {{ repaymentScheduleDetails.totalFeeChargesCharged | currency }} </b> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="due">
|
||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Installment Amount </th>
|
||||
<td mat-cell class="r-amount" *matCellDef="let ele">
|
||||
<span *ngIf="!ele.changed">
|
||||
{{ ele.totalDueForPeriod | number}}
|
||||
</span>
|
||||
<span *ngIf="ele.changed" class="amount-changed">
|
||||
<b>{{ ele.totalDueForPeriod | number}}</b>
|
||||
</span>
|
||||
</td>
|
||||
<td mat-footer-cell class="r-amount" *matFooterCellDef> <b> {{ repaymentScheduleDetails.totalRepaymentExpected | currency }} </b> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell class="center" *matCellDef="let ele">
|
||||
<button *ngIf="ele.period" type="button" color="primary" mat-icon-button matTooltip="Edit" matTooltipPosition="above" (click)="editPeriod(ele)">
|
||||
<fa-icon icon="edit" size="lg"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
<td mat-footer-cell *matFooterCellDef> </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumnsEdit"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumnsEdit;"></tr>
|
||||
<tr mat-footer-row *matFooterRowDef="displayedColumnsEdit"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
@import "assets/styles/helper";
|
||||
@import "assets/styles/helper";
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin: 3% 0%;
|
||||
@@ -10,3 +13,7 @@ table {
|
||||
.check {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.amount-changed {
|
||||
color: $status-approved;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
@@ -8,6 +8,8 @@ import { ActivatedRoute } from '@angular/router';
|
||||
})
|
||||
export class RepaymentScheduleTabComponent implements OnInit {
|
||||
|
||||
/** Loan Repayment Schedule to be Edited */
|
||||
@Input() forEditing = false;
|
||||
/** Loan Repayment Schedule Details Data */
|
||||
@Input() repaymentScheduleDetails: any = null;
|
||||
loanDetailsDataRepaymentSchedule: any = [];
|
||||
@@ -16,6 +18,11 @@ export class RepaymentScheduleTabComponent implements OnInit {
|
||||
isWaived: boolean;
|
||||
/** Columns to be displayed in original schedule table. */
|
||||
displayedColumns: string[] = ['number', 'days', 'date', 'paiddate', 'check', 'balanceOfLoan', 'principalDue', 'interest', 'fees', 'penalties', 'due', 'paid', 'inadvance', 'late', 'waived', 'outstanding'];
|
||||
/** Columns to be displayed in editable schedule table. */
|
||||
displayedColumnsEdit: string[] = ['number', 'date', 'balanceOfLoan', 'principalDue', 'interest', 'fees', 'due'];
|
||||
|
||||
/** Form functions event */
|
||||
@Output() editPeriod = new EventEmitter();
|
||||
|
||||
/**
|
||||
* Retrieves the loans with associations data from `resolve`.
|
||||
|
||||
@@ -401,7 +401,7 @@ export class LoansService {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} accountId Loans Account Id
|
||||
* @param {string} accountId Loans Account Id
|
||||
* @param {any} data Charge Data
|
||||
* @param {any} chargeId Charge Id
|
||||
* @returns {Observable<any>}
|
||||
@@ -411,7 +411,7 @@ export class LoansService {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} accountId Loans Account Id
|
||||
* @param {string} accountId Loans Account Id
|
||||
* @param {any} chargeId Charge Id
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
@@ -419,6 +419,15 @@ export class LoansService {
|
||||
return this.http.delete(`/loans/${accountId}/charges/${chargeId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} loanId Loans Account Id
|
||||
* @param {string} command Schedule command
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
applyCommandLoanScheduleVariations(loanId: string, command: string, payload: any): Observable<any> {
|
||||
return this.http.post(`/loans/${loanId}/schedule?command=${command}`, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} accountId Loans Account Id
|
||||
* @param {string} transactionId Transaction Id
|
||||
|
||||
+5
-2
@@ -74,7 +74,7 @@
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Delinquency Bucket</mat-label>
|
||||
<mat-select formControlName="delinquencyBucketId">
|
||||
<mat-select formControlName="delinquencyBucketId" required>
|
||||
<mat-option *ngFor="let delinquencyBucket of delinquencyBucketData" [value]="delinquencyBucket.id">
|
||||
{{ delinquencyBucket.name }}
|
||||
</mat-option>
|
||||
@@ -162,7 +162,10 @@
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Maximum gap between Installments</mat-label>
|
||||
<input type="number" matInput formControlName="maximumGap">
|
||||
<input type="number" matInput formControlName="maximumGap" required>
|
||||
<mat-error>
|
||||
Maximum gap between Installments is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -174,7 +174,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
'graceOnPrincipalAndInterestPayment': [true],
|
||||
'graceOnArrearsAgeing': [true]
|
||||
}),
|
||||
'delinquencyBucketId': ['']
|
||||
'delinquencyBucketId': ['', Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
.subscribe((allowVariableInstallments: any) => {
|
||||
if (allowVariableInstallments) {
|
||||
this.loanProductSettingsForm.addControl('minimumGap', new FormControl('', Validators.required));
|
||||
this.loanProductSettingsForm.addControl('maximumGap', new FormControl(''));
|
||||
this.loanProductSettingsForm.addControl('maximumGap', new FormControl('', Validators.required));
|
||||
} else {
|
||||
this.loanProductSettingsForm.removeControl('minimumGap');
|
||||
this.loanProductSettingsForm.removeControl('maximumGap');
|
||||
|
||||
+2
-4
@@ -124,10 +124,8 @@ export class ManageSavingsAccountComponent implements OnInit {
|
||||
} else {
|
||||
payload = {
|
||||
... this.manageSavingsAccountForm.value
|
||||
}
|
||||
if (this.transactionType.blockaccount) {
|
||||
command = 'block';
|
||||
}
|
||||
};
|
||||
command = 'block';
|
||||
|
||||
this.savingsService.executeSavingsAccountCommand(this.savingAccountId, command, payload).subscribe((response: any) => {
|
||||
this.router.navigate(['../../transactions'], { relativeTo: this.route });
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<div fxLayout="column" id="footer" class="m-b-20">
|
||||
<mat-divider fxFlexAlign="center" class="divider"></mat-divider>
|
||||
<p fxFlexAlign="center" class="footer-content">{{ 'labels.texts.Version' | translate }} <b>{{ version }}</b> - <b>{{ hash }}</b></p>
|
||||
<p fxFlexAlign="center" class="footer-content" *ngIf="isBusinessDateDefined">Current Business Date: <b>{{ businessDate | date: 'EEEE, MMMM dd, y' }}</b></p>
|
||||
<p fxFlexAlign="center" class="footer-content">{{ 'labels.texts.Version' | translate }} <b>{{ version }}</b> - <b>{{
|
||||
hash }}</b></p>
|
||||
<p fxFlexAlign="center" class="footer-content" *ngIf="isBusinessDateDefined">Current Business Date: <b>{{ businessDate
|
||||
| date: 'EEEE, MMMM dd, y' }}</b></p>
|
||||
<p fxFlexAlign="center" class="footer-content"><b>{{ server }}</b></p>
|
||||
<mat-divider fxFlexAlign="center" class="divider"></mat-divider>
|
||||
<p fxFlexAlign="center" class="footer-content">{{ 'APP_NAME' | translate }} {{ 'labels.texts.by' | translate }} Mifos</p>
|
||||
<p fxFlexAlign="center" class="footer-content">{{ 'APP_NAME' | translate }} {{ 'labels.texts.by' | translate }} Mifos
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,7 @@ export class FooterComponent implements OnInit, OnDestroy {
|
||||
version: string = environment.version;
|
||||
/** Mifos X hash */
|
||||
hash: string = environment.hash;
|
||||
server = '';
|
||||
/** Business Date */
|
||||
businessDate: Date = null;
|
||||
|
||||
@@ -58,6 +59,7 @@ export class FooterComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
this.getConfigurations();
|
||||
this.server = this.settingsService.server;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
@@ -74,17 +74,17 @@
|
||||
|
||||
<ng-container matColumnDef="mandatory">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center"> Mandatory </th>
|
||||
<td mat-cell *matCellDef="let column" class="center">
|
||||
<fa-icon *ngIf="column.isColumnNullable" icon="check-circle" size="lg" class="column-mandatory"
|
||||
<td mat-cell *matCellDef="let column">
|
||||
<fa-icon *ngIf="!column.isColumnNullable" icon="check-circle" size="lg" class="column-mandatory"
|
||||
matTooltip="Yes" matTooltipPosition="right"></fa-icon>
|
||||
<fa-icon *ngIf="!column.isColumnNullable" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
<fa-icon *ngIf="column.isColumnNullable" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
matTooltip="No" matTooltipPosition="right"></fa-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="unique">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center"> Unique </th>
|
||||
<td mat-cell *matCellDef="let column" class="center">
|
||||
<td mat-cell *matCellDef="let column">
|
||||
<fa-icon *ngIf="column.isColumnUnique" icon="check-circle" size="lg" class="column-mandatory"
|
||||
matTooltip="Yes" matTooltipPosition="right"></fa-icon>
|
||||
<fa-icon *ngIf="!column.isColumnUnique" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
<ng-container matColumnDef="indexed">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center"> Indexed </th>
|
||||
<td mat-cell *matCellDef="let column" class="center">
|
||||
<td mat-cell *matCellDef="let column">
|
||||
<fa-icon *ngIf="column.isColumnIndexed" icon="check-circle" size="lg" class="column-mandatory"
|
||||
matTooltip="Yes" matTooltipPosition="right"></fa-icon>
|
||||
<fa-icon *ngIf="!column.isColumnIndexed" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
|
||||
@@ -64,7 +64,7 @@ export class EditDataTableComponent implements OnInit {
|
||||
isColumnIndexed: undefined
|
||||
};
|
||||
/** Columns to be displayed in columns table. */
|
||||
displayedColumns: string[] = ['name', 'type', 'mandatory', 'length', 'code', 'unique', 'indexed', 'actions'];
|
||||
displayedColumns: string[] = ['name', 'type', 'length', 'code', 'mandatory', 'unique', 'indexed', 'actions'];
|
||||
/** Data source for columns table. */
|
||||
dataSource: MatTableDataSource<any>;
|
||||
/** Paginator for columns table. */
|
||||
@@ -204,8 +204,8 @@ export class EditDataTableComponent implements OnInit {
|
||||
this.dataForDialog.columnName = column.columnName;
|
||||
this.dataForDialog.columnDisplayType = column.columnDisplayType;
|
||||
this.dataForDialog.isColumnNullable = !column.isColumnNullable;
|
||||
this.dataForDialog.isColumnUnique = !column.isColumnUnique;
|
||||
this.dataForDialog.isColumnIndexed = !column.isColumnIndexed;
|
||||
this.dataForDialog.isColumnUnique = column.isColumnUnique;
|
||||
this.dataForDialog.isColumnIndexed = column.isColumnIndexed;
|
||||
this.dataForDialog.columnLength = column.columnLength;
|
||||
this.dataForDialog.columnCode = column.columnCode;
|
||||
this.dataForDialog.type = column.type;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
<ng-container matColumnDef="isColumnNullable">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center"> Mandatory </th>
|
||||
<td mat-cell *matCellDef="let dataTable" class="center">
|
||||
<td mat-cell *matCellDef="let dataTable">
|
||||
<fa-icon *ngIf="!dataTable.isColumnNullable" icon="check-circle" size="lg" class="column-mandatory"
|
||||
matTooltip="Yes" matTooltipPosition="right"></fa-icon>
|
||||
<fa-icon *ngIf="dataTable.isColumnNullable" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
<ng-container matColumnDef="isColumnUnique">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center"> Unique </th>
|
||||
<td mat-cell *matCellDef="let dataTable" class="center">
|
||||
<td mat-cell *matCellDef="let dataTable">
|
||||
<fa-icon *ngIf="dataTable.isColumnUnique" icon="check-circle" size="lg" class="column-mandatory"
|
||||
matTooltip="Yes" matTooltipPosition="right"></fa-icon>
|
||||
<fa-icon *ngIf="!dataTable.isColumnUnique" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
<ng-container matColumnDef="isColumnIndexed">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center"> Indexed </th>
|
||||
<td mat-cell *matCellDef="let dataTable" class="center">
|
||||
<td mat-cell *matCellDef="let dataTable">
|
||||
<fa-icon *ngIf="dataTable.isColumnIndexed" icon="check-circle" size="lg" class="column-mandatory"
|
||||
matTooltip="Yes" matTooltipPosition="right"></fa-icon>
|
||||
<fa-icon *ngIf="!dataTable.isColumnIndexed" icon="times-circle" size="lg" class="not-column-mandatory"
|
||||
|
||||
Reference in New Issue
Block a user