@@ -35,6 +35,7 @@ import { TemplatesModule } from './templates/templates.module';
|
||||
import { UsersModule } from './users/users.module';
|
||||
import { ReportsModule } from './reports/reports.module';
|
||||
import { NotificationsModule } from './notifications/notifications.module';
|
||||
import { CollectionsModule } from './collections/collections.module';
|
||||
|
||||
/** Main Routing Module */
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
@@ -68,6 +69,7 @@ import { AppRoutingModule } from './app-routing.module';
|
||||
TemplatesModule,
|
||||
UsersModule,
|
||||
NotificationsModule,
|
||||
CollectionsModule,
|
||||
AppRoutingModule,
|
||||
],
|
||||
declarations: [WebAppComponent, NotFoundComponent],
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
/** Routing Imports */
|
||||
import { Route } from '../core/route/route.service';
|
||||
|
||||
/** Translation Imports */
|
||||
import { extract } from '../core/i18n/i18n.service';
|
||||
|
||||
/** Custom Components */
|
||||
import { IndividualCollectionSheetComponent } from './individual-collection-sheet/individual-collection-sheet.component';
|
||||
|
||||
/** Custom Resolvers */
|
||||
import { GetOfficesResolver } from './individual-collection-sheet/get-offices.resolver';
|
||||
|
||||
const routes: Routes = [
|
||||
Route.withShell([
|
||||
{
|
||||
path: 'collections',
|
||||
children: [
|
||||
{
|
||||
path: 'individual-collection-sheet',
|
||||
data: { title: extract('Individual Collection Sheet'), breadcrumb: 'Individual Collection Sheet', routeParamBreadcrumb: false },
|
||||
component: IndividualCollectionSheetComponent,
|
||||
resolve: {
|
||||
officesData: GetOfficesResolver
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
])
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
providers: [GetOfficesResolver],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class CollectionsRoutingModule { }
|
||||
@@ -0,0 +1,22 @@
|
||||
/** Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
/** Custom Modules */
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { PipesModule } from '../pipes/pipes.module';
|
||||
import { CollectionsRoutingModule } from './collections-routing.module';
|
||||
|
||||
/** Custom Components */
|
||||
import { IndividualCollectionSheetComponent } from './individual-collection-sheet/individual-collection-sheet.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
PipesModule,
|
||||
CollectionsRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
IndividualCollectionSheetComponent
|
||||
]
|
||||
})
|
||||
export class CollectionsModule { }
|
||||
@@ -0,0 +1,12 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CollectionsService } from './collections.service';
|
||||
|
||||
describe('CollectionsService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: CollectionsService = TestBed.get(CollectionsService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Collections Service
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CollectionsService {
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
/**
|
||||
* Returns all the offices
|
||||
*/
|
||||
getOffices(): Observable<any> {
|
||||
return this.http.get(`/offices`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the loan officer(staffs) for the particular office
|
||||
* @param {officeId} OfficeId any
|
||||
*/
|
||||
getStaffs(officeId: any): Observable<any> {
|
||||
const httpParams = new HttpParams()
|
||||
.set('officeId', officeId)
|
||||
.set('status', 'all');
|
||||
return this.http.get(`/staff`, { params: httpParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Collection Sheet Data
|
||||
* @param {data} data any
|
||||
*/
|
||||
retrieveCollectionSheetData(data: any): Observable<any> {
|
||||
const httpParams = new HttpParams().set('command', 'generateCollectionSheet');
|
||||
return this.http.post(`/collectionsheet`, data, { params: httpParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the Save Collection Sheet Data
|
||||
* @param {data} data any
|
||||
*/
|
||||
executeSaveCollectionSheet(data: any): Observable<any> {
|
||||
const httpParams = new HttpParams().set('command', 'saveCollectionSheet');
|
||||
return this.http.post(`/collectionsheet`, data, { params: httpParams });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/** Custom Services */
|
||||
import { CollectionsService } from '../collections.service';
|
||||
|
||||
/**
|
||||
* Returns all the offices data.
|
||||
*/
|
||||
@Injectable()
|
||||
export class GetOfficesResolver implements Resolve<Object> {
|
||||
|
||||
/**
|
||||
* @param {CollectionsService} CollectionsService Collections service.
|
||||
*/
|
||||
constructor(private collectionsService: CollectionsService) { }
|
||||
|
||||
/**
|
||||
* Returns the Collection Office Data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(): Observable<any> {
|
||||
return this.collectionsService.getOffices();
|
||||
}
|
||||
|
||||
}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
<mat-card class="container" *ngIf="!isCollapsed">
|
||||
|
||||
<div class="alert" *ngIf="noData">
|
||||
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
No repayments and disbursal are available for selected client and meeting date
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<form [formGroup]="collectionSheetForm" (ngSubmit)="previewCollectionSheet()">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" fxLayoutAlign.gt-sm="start center">
|
||||
|
||||
<mat-form-field fxFlex="98%">
|
||||
<mat-label>Branch Office</mat-label>
|
||||
<mat-select formControlName="officeId" required>
|
||||
<mat-option *ngFor="let office of officesData" [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="collectionSheetForm.controls.officeId.hasError('required')">
|
||||
Branch Office is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="98%">
|
||||
<mat-label>Repayment date</mat-label>
|
||||
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="transactionDatePicker" required
|
||||
formControlName="transactionDate" required>
|
||||
<mat-datepicker-toggle matSuffix [for]="transactionDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #transactionDatePicker></mat-datepicker>
|
||||
<mat-error *ngIf="collectionSheetForm.controls.transactionDate.hasError('required')">
|
||||
Repayment Date is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="98%">
|
||||
<mat-label>Staff</mat-label>
|
||||
<mat-select formControlName="staffId">
|
||||
<mat-option *ngFor="let loanOfficer of loanOfficerData" [value]="loanOfficer.id">
|
||||
{{ loanOfficer.displayName }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">Cancel</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!collectionSheetForm.valid">
|
||||
<fa-icon icon="search"></fa-icon> Collection Sheet
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
|
||||
</form>
|
||||
|
||||
</mat-card>
|
||||
|
||||
<div class="showCollectionSheet">
|
||||
|
||||
<div class="container" *ngIf="isCollapsed">
|
||||
|
||||
<mat-card>
|
||||
|
||||
<div class="m-b-20">
|
||||
<button mat-raised-button color="primary" (click)="isCollapsed = false">
|
||||
Parameters
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="loansDataSource">
|
||||
|
||||
<h2 class="mat-h2">Due Collections</h2>
|
||||
|
||||
<table class="mat-elevation-z1" mat-table [dataSource]="loansDataSource" matSort>
|
||||
|
||||
<ng-container matColumnDef="loanAccount">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Loan Account# </th>
|
||||
<td mat-cell *matCellDef="let loan"> {{ loan.accountId }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="productName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Product Name </th>
|
||||
<td mat-cell *matCellDef="let loan"> {{ loan.productShortName }}({{ loan.productId }}) </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="clientName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Client Name </th>
|
||||
<td mat-cell *matCellDef="let loan"> {{ loan.clientName }}({{ loan.clientId }}) </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="totalDue">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Total Due </th>
|
||||
<td mat-cell *matCellDef="let loan"> {{ loan.totalDue }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="charges">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Charges </th>
|
||||
<td mat-cell *matCellDef="let loan"> {{ loan.feeDue }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Actions </th>
|
||||
<td mat-cell *matCellDef="let loan; let i = index">
|
||||
<button mat-raised-button color="primary" (click)="showAndStorePaymentDetails('loans', loan, i)">Add Payment</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="loansDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: loansDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="savingsDataSource">
|
||||
|
||||
<h2 class="mat-h2">Due Savings Collections</h2>
|
||||
|
||||
<table class="mat-elevation-z1" mat-table [dataSource]="savingsDataSource" matSort>
|
||||
|
||||
<ng-container matColumnDef="depositAccount">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Deposit Account </th>
|
||||
<td mat-cell *matCellDef="let saving"> {{ saving.depositAccountType }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="savingsAccountNo">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Savings Account # </th>
|
||||
<td mat-cell *matCellDef="let saving"> {{ saving.accountId }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="productName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Product Name </th>
|
||||
<td mat-cell *matCellDef="let saving"> {{ saving.productName }}({{ saving.productId }}) </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="clientName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Client Name </th>
|
||||
<td mat-cell *matCellDef="let saving"> {{ saving.clientName }}({{ saving.clientId }}) </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="totalDue">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Total Due </th>
|
||||
<td mat-cell *matCellDef="let saving"> {{ saving.dueAmount }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Actions </th>
|
||||
<td mat-cell *matCellDef="let saving; let j = index">
|
||||
<button mat-raised-button color="primary" (click)="showAndStorePaymentDetails('savings', saving, j)">Add Payment</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="savingsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: savingsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">Cancel</button>
|
||||
<button mat-raised-button color="primary" (click)="submit()">Submit</button>
|
||||
</mat-card-actions>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
.container {
|
||||
|
||||
max-width: 37em;
|
||||
|
||||
.margin-v {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.margin-b {
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.showCollectionSheet {
|
||||
.container {
|
||||
max-width: 73rem;
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
background-color: rgb(253, 236, 234);
|
||||
padding: 6px 16px;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.43;
|
||||
border-radius: 4px;
|
||||
letter-spacing: 0.01071em;
|
||||
|
||||
.message {
|
||||
padding: 8px 0;
|
||||
}
|
||||
.alert-check {
|
||||
color:#f44336;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { IndividualCollectionSheetComponent } from './individual-collection-sheet.component';
|
||||
|
||||
describe('IndividualCollectionSheetComponent', () => {
|
||||
let component: IndividualCollectionSheetComponent;
|
||||
let fixture: ComponentFixture<IndividualCollectionSheetComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ IndividualCollectionSheetComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(IndividualCollectionSheetComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+331
@@ -0,0 +1,331 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { DatePipe } from '@angular/common';
|
||||
|
||||
/** Services Import */
|
||||
import { CollectionsService } from '../collections.service';
|
||||
|
||||
/** Custom Dialogs */
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
|
||||
/** Custom Models */
|
||||
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';
|
||||
|
||||
/**
|
||||
* Individual Collection Sheet
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-individual-collection-sheet',
|
||||
templateUrl: './individual-collection-sheet.component.html',
|
||||
styleUrls: ['./individual-collection-sheet.component.scss']
|
||||
})
|
||||
export class IndividualCollectionSheetComponent implements OnInit {
|
||||
|
||||
/** Offices Data */
|
||||
officesData: any;
|
||||
/** Loan Officer Data */
|
||||
loanOfficerData: any = [];
|
||||
/** Loans Data */
|
||||
loansData: any = [];
|
||||
/** Savings Data */
|
||||
savingsData: any = [];
|
||||
/** Minimum Date allowed. */
|
||||
minDate = new Date(2000, 0, 1);
|
||||
/** Maximum Date allowed. */
|
||||
maxDate = new Date();
|
||||
/** Collection Sheet form. */
|
||||
collectionSheetForm: FormGroup;
|
||||
/** Toggles b/w form and table */
|
||||
isCollapsed = false;
|
||||
/** Collections Sheet Data */
|
||||
collectionSheetData: any;
|
||||
/** checks and stores the local storage values */
|
||||
Success: boolean;
|
||||
/** Bulk Disbursement Transactions Data */
|
||||
bulkDisbursementTransactionsData = {};
|
||||
/** Bulk Repayment Transactions Data */
|
||||
bulkRepaymentTransactions: any[] = [];
|
||||
/** Bulk Savings Due Data */
|
||||
bulkSavingsDueTransactions: any[] = [];
|
||||
/** Checks if there is no client data in the response */
|
||||
noData = false;
|
||||
|
||||
/** Columns to be displayed in loans table. */
|
||||
loansDisplayedColumns: string[] = ['loanAccount', 'productName', 'clientName', 'totalDue', 'charges', 'actions'];
|
||||
/** Columns to be displayed in savings table. */
|
||||
savingsDisplayedColumns: string[] = ['depositAccount', 'savingsAccountNo', 'productName', 'clientName', 'totalDue', 'actions'];
|
||||
|
||||
/** Data source for loans table. */
|
||||
loansDataSource: MatTableDataSource<any>;
|
||||
/** Data source for savings table. */
|
||||
savingsDataSource: MatTableDataSource<any>;
|
||||
|
||||
|
||||
/** Paginator for table. */
|
||||
@ViewChild(MatPaginator, { read: true }) paginator: MatPaginator;
|
||||
/** Sorter for table. */
|
||||
@ViewChild(MatSort, { read: true }) sort: MatSort;
|
||||
|
||||
/**
|
||||
* Retrieves the offices data from `resolve`.
|
||||
* @param {FormBuilder} formBuilder Form Builder.
|
||||
* @param {OrganizationService} collectionsService Organization Service.
|
||||
* @param {Route} route Route.
|
||||
* @param {DatePipe} datePipe Date Pipe to format date.
|
||||
* @param {Dialog} dialog Dialog component.
|
||||
* @param {Router} router Router for navigation.
|
||||
*/
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
private collectionsService: CollectionsService,
|
||||
private route: ActivatedRoute,
|
||||
private datePipe: DatePipe,
|
||||
public dialog: MatDialog,
|
||||
private router: Router, ) {
|
||||
this.route.data.subscribe((data: { officesData: any }) => {
|
||||
this.officesData = data.officesData;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (localStorage.getItem('Success')) {
|
||||
localStorage.removeItem('Success');
|
||||
this.Success = true;
|
||||
setTimeout(() => { this.Success = false; }, 3000);
|
||||
}
|
||||
this.createCollectionSheetForm();
|
||||
this.buildDependencies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Individual Collection Sheet Form
|
||||
*/
|
||||
createCollectionSheetForm() {
|
||||
this.collectionSheetForm = this.formBuilder.group({
|
||||
'officeId': ['', Validators.required],
|
||||
'transactionDate': [new Date(), Validators.required],
|
||||
'staffId': ['']
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for the office id value change
|
||||
*/
|
||||
buildDependencies() {
|
||||
this.collectionSheetForm.get('officeId').valueChanges.subscribe((value: any) => {
|
||||
this.collectionsService.getStaffs(value).subscribe((response: any) => {
|
||||
this.loanOfficerData = response;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the data source, paginator and sorter for loans and savings table.
|
||||
* @param {any} data
|
||||
*/
|
||||
organizeData(data: any) {
|
||||
data.clients.forEach((client: any) => {
|
||||
if (client.loans) {
|
||||
client.loans.forEach((loan: any) => {
|
||||
const loanData = {
|
||||
...loan,
|
||||
clientName: client.clientName,
|
||||
clientId: client.clientId
|
||||
};
|
||||
this.loansData.push(loanData);
|
||||
});
|
||||
}
|
||||
if (client.savings) {
|
||||
client.savings.forEach((saving: any) => {
|
||||
const savingData = {
|
||||
...saving,
|
||||
clientName: client.clientName,
|
||||
clientId: client.clientId
|
||||
};
|
||||
this.savingsData.push(savingData);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (this.loansData.length > 0) {
|
||||
this.loansDataSource = new MatTableDataSource(this.loansData);
|
||||
this.loansDataSource.paginator = this.paginator;
|
||||
this.loansDataSource.sort = this.sort;
|
||||
}
|
||||
if (this.savingsData.length > 0) {
|
||||
this.savingsDataSource = new MatTableDataSource(this.savingsData);
|
||||
this.savingsDataSource.paginator = this.paginator;
|
||||
this.savingsDataSource.sort = this.sort;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Loan Total Due Amount
|
||||
*/
|
||||
getLoanTotalDueAmount (loan: any) {
|
||||
let principalInterestDue = loan.totalDue;
|
||||
let chargesDue = loan.chargesDue;
|
||||
if (isNaN(principalInterestDue)) {
|
||||
principalInterestDue = 0;
|
||||
}
|
||||
if (isNaN(chargesDue)) {
|
||||
chargesDue = 0;
|
||||
}
|
||||
return Math.ceil((Number(principalInterestDue) + Number(chargesDue)) * 100) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the payment dialog box and stores the return data
|
||||
*/
|
||||
showAndStorePaymentDetails(type: any, selectedData: any, index: number) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'paymentTypeId',
|
||||
label: 'Payment Type',
|
||||
options: { label: 'name', value: 'id', data: this.collectionSheetData.paymentTypeOptions },
|
||||
required: false
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'accountNumber',
|
||||
label: 'Account #',
|
||||
type: 'number',
|
||||
required: false
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'checkNumber',
|
||||
label: 'Cheque #',
|
||||
type: 'number',
|
||||
required: false
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'routingCode',
|
||||
label: 'Routing Code',
|
||||
type: 'text',
|
||||
required: false
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'receiptNumber',
|
||||
label: 'Receipt #',
|
||||
type: 'number',
|
||||
required: false
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'bankNumber',
|
||||
label: 'Bank #',
|
||||
type: 'number',
|
||||
required: false
|
||||
}),
|
||||
];
|
||||
const data = {
|
||||
title: `Payment for ${type === 'loans' ? 'Loan' : 'Saving'} Id ${type === 'loans' ? selectedData.loanId : selectedData.savingsId}`,
|
||||
layout: { addButtonText: 'Confirm' },
|
||||
formfields: formfields
|
||||
};
|
||||
const showPaymentDetailsDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
showPaymentDetailsDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
if (type === 'loans') {
|
||||
const totalDue = this.getLoanTotalDueAmount(selectedData);
|
||||
const loanTransaction = {
|
||||
loanId: selectedData.loanId,
|
||||
transactionAmount: totalDue
|
||||
};
|
||||
if (response.data.value.paymentTypeId !== '') {
|
||||
loanTransaction['paymentTypeId'] = response.data.value.paymentTypeId;
|
||||
loanTransaction['accountNumber'] = response.data.value.accountNumber;
|
||||
loanTransaction['checkNumber'] = response.data.value.checkNumber;
|
||||
loanTransaction['routingCode'] = response.data.value.routingCode;
|
||||
loanTransaction['receiptNumber'] = response.data.value.receiptNumber;
|
||||
loanTransaction['bankNumber'] = response.data.value.bankNumber;
|
||||
}
|
||||
this.bulkRepaymentTransactions.push(loanTransaction);
|
||||
} else {
|
||||
let dueAmount = selectedData.dueAmount;
|
||||
if (isNaN(dueAmount)) {
|
||||
dueAmount = 0;
|
||||
}
|
||||
const savingsTransaction = {
|
||||
savingsId: selectedData.savingsId,
|
||||
transactionAmount: dueAmount,
|
||||
depositAccountType: selectedData.depositAccountType === 'Saving Deposit' ? 100 : (selectedData.depositAccountType === 'Recurring Deposit' ? 300 : 400)
|
||||
};
|
||||
if (response.data.paymentTypeId !== '') {
|
||||
savingsTransaction['paymentTypeId'] = response.data.paymentTypeId;
|
||||
savingsTransaction['accountNumber'] = response.data.accountNumber;
|
||||
savingsTransaction['checkNumber'] = response.data.checkNumber;
|
||||
savingsTransaction['routingCode'] = response.data.routingCode;
|
||||
savingsTransaction['receiptNumber'] = response.data.receiptNumber;
|
||||
savingsTransaction['bankNumber'] = response.data.bankNumber;
|
||||
}
|
||||
if (savingsTransaction.transactionAmount > 0) {
|
||||
this.bulkSavingsDueTransactions.push(savingsTransaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches collection sheet data
|
||||
*/
|
||||
previewCollectionSheet() {
|
||||
// TODO: Update once language and date settings are setup
|
||||
const locale = 'en';
|
||||
const dateFormat = 'dd MMMM yyyy';
|
||||
const collectionSheet = {
|
||||
...this.collectionSheetForm.value,
|
||||
'transactionDate': this.datePipe.transform(this.collectionSheetForm.value.transactionDate, dateFormat),
|
||||
dateFormat,
|
||||
locale
|
||||
};
|
||||
if (collectionSheet.staffId === '') {
|
||||
delete collectionSheet.staffId;
|
||||
}
|
||||
this.collectionsService.retrieveCollectionSheetData(collectionSheet).subscribe((response: any) => {
|
||||
if (response.clients.length > 0) {
|
||||
this.collectionSheetData = response;
|
||||
this.organizeData(response);
|
||||
this.isCollapsed = true;
|
||||
} else {
|
||||
this.noData = true;
|
||||
setTimeout(() => { this.noData = false; }, 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the data with all the payments data
|
||||
*/
|
||||
submit() {
|
||||
// TODO: Update once language and date settings are setup
|
||||
const locale = 'en';
|
||||
const dateFormat = 'dd MMMM yyyy';
|
||||
this.bulkDisbursementTransactionsData['bulkRepaymentTransactions'] = this.bulkRepaymentTransactions;
|
||||
this.bulkDisbursementTransactionsData['bulkSavingsDueTransactions'] = this.bulkSavingsDueTransactions;
|
||||
const finalSubmitData = {
|
||||
dateFormat,
|
||||
locale,
|
||||
actualDisbursementDate: this.datePipe.transform(this.collectionSheetForm.value.transactionDate, dateFormat),
|
||||
transactionDate: this.datePipe.transform(this.collectionSheetForm.value.transactionDate, dateFormat),
|
||||
bulkDisbursementTransactions: this.bulkDisbursementTransactionsData
|
||||
};
|
||||
this.collectionsService.executeSaveCollectionSheet(finalSubmitData).subscribe(() => {
|
||||
this.reload();
|
||||
localStorage.setItem('Success', 'true');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refetches data for the component
|
||||
* TODO: Replace by a custom reload component instead of hard-coded back-routing.
|
||||
*/
|
||||
reload() {
|
||||
const url: string = this.router.url;
|
||||
this.router.navigateByUrl(`/collections`, { skipLocationChange: true })
|
||||
.then(() => this.router.navigate([url]));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,6 +73,12 @@
|
||||
</mat-icon>
|
||||
<a matLine>Navigation</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item [routerLink]="['/collections/individual-collection-sheet']">
|
||||
<mat-icon matListIcon>
|
||||
<i class="fa fa-tasks "></i>
|
||||
</mat-icon>
|
||||
<a matLine>Individual Collection Sheet</a>
|
||||
</mat-list-item>
|
||||
<mat-list-item [routerLink]="['/notifications']">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="bell" size="sm"></fa-icon>
|
||||
|
||||
Reference in New Issue
Block a user