@@ -0,0 +1,69 @@
|
|||||||
|
<div class="mat-typography">
|
||||||
|
|
||||||
|
<h3>Address</h3>
|
||||||
|
|
||||||
|
<div fxLayout="row" fxLayoutAlign="flex-end" class="m-b-20">
|
||||||
|
<button mat-raised-button color="primary" (click)="addAddress()">
|
||||||
|
<fa-icon icon="plus"></fa-icon> Add
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-accordion>
|
||||||
|
|
||||||
|
<mat-expansion-panel *ngFor="let address of clientAddressData; index as i" class="address">
|
||||||
|
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-panel-title>
|
||||||
|
{{ getSelectedValue('addressTypeIdOptions',address.addressTypeId)?.name }}
|
||||||
|
</mat-panel-title>
|
||||||
|
|
||||||
|
<mat-panel-description>
|
||||||
|
{{ address.relationship }}
|
||||||
|
</mat-panel-description>
|
||||||
|
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<div class="address-actions" fxLayout="row" fxLayoutAlign="flex-end center">
|
||||||
|
<button mat-button color="primary" (click)="editAddress(address,i)">
|
||||||
|
<fa-icon icon="edit"></fa-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-button color="warn" (click)="deleteAddress(address,i)">
|
||||||
|
<fa-icon icon="trash"></fa-icon>
|
||||||
|
</button>
|
||||||
|
<mat-slide-toggle [checked]="address.isActive" (change)="toggleAddress(address)"></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span *ngIf="isFieldEnabled('street')">Street : {{address.street}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('addressLine1')">Address Line 1 : {{address.addressLine1}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('addressLine2')">Address Line 2 : {{address.addressLine2}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('addressLine3')">Address Line 3 : {{address.addressLine3}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('townVillage')">Town / Village : {{address.townVillage}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('city')">City : {{address.city}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('stateProvinceId')">State / Province :
|
||||||
|
{{getSelectedValue('stateProvinceIdOptions',address.stateProvinceId)?.name}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('countryId')">Country :
|
||||||
|
{{getSelectedValue('countryIdOptions',address.countryId)?.name}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('postalCode')">Postal Code : {{address.postalCode}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('isActive')">Active Status : {{address.isActive}}<br /></span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</mat-expansion-panel>
|
||||||
|
|
||||||
|
</mat-accordion>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
.address {
|
||||||
|
.address-actions{
|
||||||
|
margin-top: 1%;
|
||||||
|
button{
|
||||||
|
margin-right: 1%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin: 1% auto;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 2%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ClientAddressStepComponent } from './client-address-step.component';
|
||||||
|
|
||||||
|
describe('ClientAddressStepComponent', () => {
|
||||||
|
let component: ClientAddressStepComponent;
|
||||||
|
let fixture: ComponentFixture<ClientAddressStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ClientAddressStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ClientAddressStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { MatDialog } from '@angular/material';
|
||||||
|
|
||||||
|
/** 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';
|
||||||
|
|
||||||
|
/** Custom Dialogs */
|
||||||
|
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||||
|
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client Address Step Component
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-client-address-step',
|
||||||
|
templateUrl: './client-address-step.component.html',
|
||||||
|
styleUrls: ['./client-address-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ClientAddressStepComponent {
|
||||||
|
|
||||||
|
/** Client Address Field Config */
|
||||||
|
@Input() clientAddressFieldConfig: any;
|
||||||
|
/** Client Template */
|
||||||
|
@Input() clientTemplate: any;
|
||||||
|
|
||||||
|
/** Client Address Data */
|
||||||
|
clientAddressData: any[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatDialog} dialog Mat Dialog
|
||||||
|
*/
|
||||||
|
constructor(private dialog: MatDialog) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a client address
|
||||||
|
*/
|
||||||
|
addAddress() {
|
||||||
|
const data = {
|
||||||
|
title: 'Add Client Address',
|
||||||
|
formfields: this.getAddressFormFields()
|
||||||
|
};
|
||||||
|
const addAddressDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||||
|
addAddressDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.data) {
|
||||||
|
const addressData = response.data.value;
|
||||||
|
addressData.isActive = false;
|
||||||
|
for (const key in addressData) {
|
||||||
|
if (addressData[key] === '' || addressData[key] === undefined) {
|
||||||
|
delete addressData[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.clientAddressData.push(addressData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit Address
|
||||||
|
* @param {any} address Address
|
||||||
|
* @param {number} index Address index
|
||||||
|
*/
|
||||||
|
editAddress(address: any, index: number) {
|
||||||
|
const data = {
|
||||||
|
title: 'Edit Client Address',
|
||||||
|
formfields: this.getAddressFormFields(address),
|
||||||
|
layout: { addButtonText: 'Edit' }
|
||||||
|
};
|
||||||
|
const editAddressDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||||
|
editAddressDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.data) {
|
||||||
|
const addressData = response.data.value;
|
||||||
|
addressData.isActive = address.isActive;
|
||||||
|
for (const key in addressData) {
|
||||||
|
if (addressData[key] === '' || addressData[key] === undefined) {
|
||||||
|
delete addressData[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.clientAddressData[index] = addressData;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} address Client Address
|
||||||
|
* @param {number} index Address index
|
||||||
|
*/
|
||||||
|
deleteAddress(address: any, index: number) {
|
||||||
|
const deleteAddressDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||||
|
data: { deleteContext: `address type : ${address.addressType} ${index}` }
|
||||||
|
});
|
||||||
|
deleteAddressDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.delete) {
|
||||||
|
this.clientAddressData.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles address activity
|
||||||
|
* @param {any} address Address
|
||||||
|
*/
|
||||||
|
toggleAddress(address: any) {
|
||||||
|
address.isActive = address.isActive ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if field is enabled in address configuration
|
||||||
|
* @param {any} address Address
|
||||||
|
*/
|
||||||
|
isFieldEnabled(fieldName: any) {
|
||||||
|
return (this.clientAddressFieldConfig.find((fieldObj: any) => fieldObj.field === fieldName)).is_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves field Id from name.
|
||||||
|
* Find pipe doesn't work with accordian.
|
||||||
|
* @param {any} address Address
|
||||||
|
*/
|
||||||
|
getSelectedValue(fieldName: any, fieldId: any) {
|
||||||
|
return (this.clientTemplate.address[fieldName].find((fieldObj: any) => fieldObj.id === fieldId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets formfields for form dialog.
|
||||||
|
* @param {any} address Address
|
||||||
|
*/
|
||||||
|
getAddressFormFields(address?: any) {
|
||||||
|
let formfields: FormfieldBase[] = [];
|
||||||
|
formfields.push(this.isFieldEnabled('addressType') ? new SelectBase({
|
||||||
|
controlName: 'addressTypeId',
|
||||||
|
label: 'Address Type',
|
||||||
|
value: address ? address.addressTypeId : '',
|
||||||
|
options: { label: 'name', value: 'id', data: this.clientTemplate.address.addressTypeIdOptions },
|
||||||
|
order: 1,
|
||||||
|
required: true
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('street') ? new InputBase({
|
||||||
|
controlName: 'street',
|
||||||
|
label: 'Street',
|
||||||
|
value: address ? address.street : '',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
order: 2
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('addressLine1') ? new InputBase({
|
||||||
|
controlName: 'addressLine1',
|
||||||
|
label: 'Address Line 1',
|
||||||
|
value: address ? address.addressLine1 : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 3
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('addressLine2') ? new InputBase({
|
||||||
|
controlName: 'addressLine2',
|
||||||
|
label: 'Address Line 2',
|
||||||
|
value: address ? address.addressLine2 : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 4
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('addressLine3') ? new InputBase({
|
||||||
|
controlName: 'addressLine3',
|
||||||
|
label: 'Address Line 3',
|
||||||
|
value: address ? address.addressLine3 : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 5
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('townVillage') ? new InputBase({
|
||||||
|
controlName: 'townVillage',
|
||||||
|
label: 'Town / Village',
|
||||||
|
value: address ? address.townVillage : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 6
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('city') ? new InputBase({
|
||||||
|
controlName: 'city',
|
||||||
|
label: 'City',
|
||||||
|
value: address ? address.city : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 7
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('stateProvinceId') ? new SelectBase({
|
||||||
|
controlName: 'stateProvinceId',
|
||||||
|
label: 'State / Province',
|
||||||
|
value: address ? address.stateProvinceId : '',
|
||||||
|
options: { label: 'name', value: 'id', data: this.clientTemplate.address.stateProvinceIdOptions },
|
||||||
|
order: 8
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('countyDistrict') ? new InputBase({
|
||||||
|
controlName: 'countryDistrict',
|
||||||
|
label: 'Country District',
|
||||||
|
value: address ? address.countyDistrict : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 11
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('countryId') ? new SelectBase({
|
||||||
|
controlName: 'countryId',
|
||||||
|
label: 'Country',
|
||||||
|
value: address ? address.countryId : '',
|
||||||
|
options: { label: 'name', value: 'id', data: this.clientTemplate.address.countryIdOptions },
|
||||||
|
order: 10
|
||||||
|
}) : null);
|
||||||
|
formfields.push(this.isFieldEnabled('postalCode') ? new InputBase({
|
||||||
|
controlName: 'postalCode',
|
||||||
|
label: 'Postal Code',
|
||||||
|
value: address ? address.postalCode : '',
|
||||||
|
type: 'text',
|
||||||
|
order: 11
|
||||||
|
}) : null);
|
||||||
|
formfields = formfields.filter(field => field !== null);
|
||||||
|
return formfields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array of client addresses
|
||||||
|
*/
|
||||||
|
get address() {
|
||||||
|
return { address: this.clientAddressData };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
<h1 mat-dialog-title>{{ data.context }} Family Member</h1>
|
||||||
|
|
||||||
|
<form [formGroup]="familyMemberForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayout.lt-md="column" fxLayoutAlign="start center" fxLayoutGap="2%">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>First Name</mat-label>
|
||||||
|
<input formControlName="firstName" required matInput />
|
||||||
|
<mat-error *ngIf="familyMemberForm.controls.firstName.hasError('required')">
|
||||||
|
First Name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Middle Name</mat-label>
|
||||||
|
<input formControlName="middleName" matInput />
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Last Name</mat-label>
|
||||||
|
<input formControlName="lastName" required matInput />
|
||||||
|
<mat-error *ngIf="familyMemberForm.controls.lastName.hasError('required')">
|
||||||
|
Last Name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Qualification</mat-label>
|
||||||
|
<input formControlName="qualification" matInput />
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Age</mat-label>
|
||||||
|
<input type="number" formControlName="age" matInput />
|
||||||
|
<mat-error *ngIf="familyMemberForm.controls.age.hasError('required')">
|
||||||
|
Age is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox formControlName="isDependent" labelPosition="before" fxFlex="48%">Is Dependent?</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Relationship</mat-label>
|
||||||
|
<mat-select formControlName="relationshipId" required>
|
||||||
|
<mat-option *ngFor="let relation of data.options.relationshipIdOptions" [value]="relation.id">
|
||||||
|
{{ relation.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="familyMemberForm.controls.relationshipId.hasError('required')">
|
||||||
|
Relationship is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Gender</mat-label>
|
||||||
|
<mat-select formControlName="genderId">
|
||||||
|
<mat-option *ngFor="let gender of data.options.genderIdOptions" [value]="gender.id">
|
||||||
|
{{ gender.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="familyMemberForm.controls.genderId.hasError('required')">
|
||||||
|
Gender is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Profession</mat-label>
|
||||||
|
<mat-select formControlName="professionId">
|
||||||
|
<mat-option *ngFor="let profession of data.options.professionIdOptions" [value]="profession.id">
|
||||||
|
{{ profession.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Marital Status</mat-label>
|
||||||
|
<mat-select formControlName="maritalStatusId">
|
||||||
|
<mat-option *ngFor="let maritalStatus of data.options.maritalStatusIdOptions"
|
||||||
|
[value]="maritalStatus.id">
|
||||||
|
{{ maritalStatus.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="98%">
|
||||||
|
<mat-label>Date Of Birth</mat-label>
|
||||||
|
<input formControlName="dateOfBirth" matInput [min]="minDate" [max]="maxDate" [matDatepicker]="dueDatePicker">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="dueDatePicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #dueDatePicker></mat-datepicker>
|
||||||
|
<mat-error *ngIf="familyMemberForm.controls.dateOfBirth.hasError('required')">
|
||||||
|
Date of birth is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-dialog-actions align="center">
|
||||||
|
<button mat-raised-button mat-dialog-close>Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" [disabled]="!familyMemberForm.valid" [mat-dialog-close]="{ member: familyMember }">Confirm</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
|
|
||||||
|
</form>
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ClientFamilyMemberDialogComponent } from './client-family-member-dialog.component';
|
||||||
|
|
||||||
|
describe('ClientFamilyMemberDialogComponent', () => {
|
||||||
|
let component: ClientFamilyMemberDialogComponent;
|
||||||
|
let fixture: ComponentFixture<ClientFamilyMemberDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ClientFamilyMemberDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ClientFamilyMemberDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit, Inject } from '@angular/core';
|
||||||
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client Family Members Dialog
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-client-family-member-dialog',
|
||||||
|
templateUrl: './client-family-member-dialog.component.html',
|
||||||
|
styleUrls: ['./client-family-member-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class ClientFamilyMemberDialogComponent implements OnInit {
|
||||||
|
|
||||||
|
/** Minimum Due Date allowed. */
|
||||||
|
minDate = new Date(2000, 0, 1);
|
||||||
|
/** Maximum Due Date allowed. */
|
||||||
|
maxDate = new Date();
|
||||||
|
|
||||||
|
/** Add/Edit family member form. */
|
||||||
|
familyMemberForm: FormGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatDialogRef} dialogRef Client Family Member Dialog Reference
|
||||||
|
* @param {FormBuilder} formBuilder Form Builder
|
||||||
|
* @param {DatePipe} datePipe Date Pipe
|
||||||
|
* @param {any} data Dialog Data
|
||||||
|
*/
|
||||||
|
constructor(public dialogRef: MatDialogRef<ClientFamilyMemberDialogComponent>,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private datePipe: DatePipe,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.createFamilyMemberForm();
|
||||||
|
if (this.data.context === 'Edit') {
|
||||||
|
this.familyMemberForm.patchValue({
|
||||||
|
'firstName': this.data.member.firstName,
|
||||||
|
'middleName': this.data.member.middleName,
|
||||||
|
'lastName': this.data.member.lastName,
|
||||||
|
'qualification': this.data.member.qualification,
|
||||||
|
'age': this.data.member.age,
|
||||||
|
'isDependent': this.data.member.isDependent,
|
||||||
|
'relationshipId': this.data.member.relationshipId,
|
||||||
|
'genderId': this.data.member.genderId,
|
||||||
|
'professionId': this.data.member.professionId,
|
||||||
|
'maritalStatusId': this.data.member.maritalStatusId,
|
||||||
|
'dateOfBirth': this.data.member.dateOfBirth && new Date(this.data.member.dateOfBirth)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates Family Member Form
|
||||||
|
*/
|
||||||
|
createFamilyMemberForm() {
|
||||||
|
this.familyMemberForm = this.formBuilder.group({
|
||||||
|
'firstName': ['', Validators.required],
|
||||||
|
'middleName': [''],
|
||||||
|
'lastName': ['', Validators.required],
|
||||||
|
'qualification': [''],
|
||||||
|
'age': [''],
|
||||||
|
'isDependent': [''],
|
||||||
|
'relationshipId': ['', Validators.required],
|
||||||
|
'genderId': [''],
|
||||||
|
'professionId': [''],
|
||||||
|
'maritalStatusId': [''],
|
||||||
|
'dateOfBirth': ['']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Formatted Family Member
|
||||||
|
*/
|
||||||
|
get familyMember() {
|
||||||
|
const locale = 'en';
|
||||||
|
const dateFormat = 'dd MMMM yyyy';
|
||||||
|
// TODO: Update once language and date settings are setup
|
||||||
|
const familyMember = {
|
||||||
|
...this.familyMemberForm.value,
|
||||||
|
dateFormat,
|
||||||
|
locale
|
||||||
|
};
|
||||||
|
for (const key in familyMember) {
|
||||||
|
if (familyMember[key] === '' || familyMember[key] === undefined) {
|
||||||
|
delete familyMember[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (familyMember.dateOfBirth) {
|
||||||
|
familyMember.dateOfBirth = this.datePipe.transform(familyMember.dateOfBirth, dateFormat);
|
||||||
|
}
|
||||||
|
return familyMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
<div class="mat-typography">
|
||||||
|
|
||||||
|
<h3>Family Members</h3>
|
||||||
|
|
||||||
|
<div fxLayout="row" fxLayoutAlign="flex-end" class="m-b-20">
|
||||||
|
<button mat-raised-button color="primary" (click)="addFamilyMember()">
|
||||||
|
<fa-icon icon="plus"></fa-icon> Add
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-accordion>
|
||||||
|
|
||||||
|
<mat-expansion-panel *ngFor="let member of clientFamilyMembers;index as i" class="family-member">
|
||||||
|
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-panel-title>
|
||||||
|
{{ member.firstName }} {{ member.middleName ? member.middleName + ' ' + member.lastName : member.lastName }}
|
||||||
|
</mat-panel-title>
|
||||||
|
|
||||||
|
<mat-panel-description>
|
||||||
|
{{member.relationship}}
|
||||||
|
</mat-panel-description>
|
||||||
|
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<div class="family-member-actions" fxLayout="row" fxLayoutAlign="flex-end">
|
||||||
|
<button mat-button color="primary">
|
||||||
|
<fa-icon icon="edit" (click)="editFamilyMember(member, i)"></fa-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-button color="warn" (click)="deleteFamilyMember(member.firstName,i)">
|
||||||
|
<fa-icon icon="trash"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
First Name : {{ member.firstName }}<br />
|
||||||
|
Middle Name : {{ member.middleName }}<br />
|
||||||
|
Last Name : {{ member.lastName }}<br />
|
||||||
|
Qualification : {{ member.qualification }}<br />
|
||||||
|
Relationship : {{ member.relationshipId | find:clientTemplate.familyMemberOptions.relationshipIdOptions:'id':'name' }}<br />
|
||||||
|
Age : {{ member.age }}<br />
|
||||||
|
Is Dependent : {{ member.isDependent ? 'Yes' : 'No' }}<br />
|
||||||
|
Marital Status : {{ member.maritalStatusId | find:clientTemplate.familyMemberOptions.maritalStatusIdOptions:'id':'name' }}<br />
|
||||||
|
Gender : {{ member.genderId | find:clientTemplate.familyMemberOptions.genderIdOptions:'id':'name' }}<br />
|
||||||
|
Profession : {{member.professionId | find:clientTemplate.familyMemberOptions.professionIdOptions:'id':'name' }}<br />
|
||||||
|
Date Of Birth : {{member.dateOfBirth | date}}<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</mat-expansion-panel>
|
||||||
|
|
||||||
|
</mat-accordion>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
.family-member {
|
||||||
|
.family-member-actions{
|
||||||
|
margin-top: 1%;
|
||||||
|
button{
|
||||||
|
margin-right: 1%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin: 1% auto;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 2%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ClientFamilyMembersStepComponent } from './client-family-members-step.component';
|
||||||
|
|
||||||
|
describe('ClientFamilyMembersStepComponent', () => {
|
||||||
|
let component: ClientFamilyMembersStepComponent;
|
||||||
|
let fixture: ComponentFixture<ClientFamilyMembersStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ClientFamilyMembersStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ClientFamilyMembersStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
import { MatDialog } from '@angular/material';
|
||||||
|
|
||||||
|
/** Custom Components */
|
||||||
|
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||||
|
import { ClientFamilyMemberDialogComponent } from './client-family-member-dialog/client-family-member-dialog.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client Family Members Step
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-client-family-members-step',
|
||||||
|
templateUrl: './client-family-members-step.component.html',
|
||||||
|
styleUrls: ['./client-family-members-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ClientFamilyMembersStepComponent {
|
||||||
|
|
||||||
|
/** Cient Template */
|
||||||
|
@Input() clientTemplate: any;
|
||||||
|
/** Client Family Members */
|
||||||
|
clientFamilyMembers: any[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatDialog} dialog Mat Dialog
|
||||||
|
*/
|
||||||
|
constructor(public dialog: MatDialog) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a family member.
|
||||||
|
*/
|
||||||
|
addFamilyMember() {
|
||||||
|
const addFamilyMemberDialogRef = this.dialog.open(ClientFamilyMemberDialogComponent, {
|
||||||
|
data: {
|
||||||
|
context: 'Add',
|
||||||
|
options: this.clientTemplate.familyMemberOptions,
|
||||||
|
},
|
||||||
|
width: '50rem'
|
||||||
|
});
|
||||||
|
addFamilyMemberDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.member) {
|
||||||
|
this.clientFamilyMembers.push(response.member);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the family member.
|
||||||
|
* @param {any} member Family Member
|
||||||
|
* @param {any} index Tree Index
|
||||||
|
*/
|
||||||
|
editFamilyMember(member: any, index: any) {
|
||||||
|
const addFamilyMemberDialogRef = this.dialog.open(ClientFamilyMemberDialogComponent, {
|
||||||
|
data: {
|
||||||
|
context: 'Edit',
|
||||||
|
member: member,
|
||||||
|
options: this.clientTemplate.familyMemberOptions,
|
||||||
|
},
|
||||||
|
width: '50rem'
|
||||||
|
});
|
||||||
|
addFamilyMemberDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.member) {
|
||||||
|
this.clientFamilyMembers.splice(index, 1, response.member);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the family member
|
||||||
|
*/
|
||||||
|
deleteFamilyMember(name: string, index: number) {
|
||||||
|
const deleteFamilyMemberDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||||
|
data: { deleteContext: `Family member name : ${name} ${index}` }
|
||||||
|
});
|
||||||
|
deleteFamilyMemberDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.delete) {
|
||||||
|
this.clientFamilyMembers.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array of client family members.
|
||||||
|
*/
|
||||||
|
get familyMembers() {
|
||||||
|
return { familyMembers: this.clientFamilyMembers };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+215
@@ -0,0 +1,215 @@
|
|||||||
|
<form [formGroup]="createClientForm">
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Office</mat-label>
|
||||||
|
<mat-select required formControlName="officeId">
|
||||||
|
<mat-option *ngFor="let office of officeOptions" [value]="office.id">
|
||||||
|
{{ office.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="createClientForm.controls.officeId.hasError('required')">
|
||||||
|
Office is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Staff</mat-label>
|
||||||
|
<mat-select formControlName="staffId">
|
||||||
|
<mat-option *ngFor="let staff of staffOptions" [value]="staff.id">
|
||||||
|
{{ staff.displayName }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Legal Form</mat-label>
|
||||||
|
<mat-select formControlName="legalFormId">
|
||||||
|
<mat-option *ngFor="let legalForm of legalFormOptions" [value]="legalForm.id">
|
||||||
|
{{ legalForm.value }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.contains('fullname')" fxFlex="48%">
|
||||||
|
<mat-label>Name</mat-label>
|
||||||
|
<input matInput required formControlName="fullname">
|
||||||
|
<mat-error *ngIf="createClientForm.controls.fullname.hasError('required')">
|
||||||
|
Client name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="createClientForm.controls.fullname.hasError('pattern')">
|
||||||
|
Client name <strong>cannot</strong> begin with a special character or number
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.contains('firstname')" fxFlex="48%">
|
||||||
|
<mat-label>First Name</mat-label>
|
||||||
|
<input matInput required formControlName="firstname">
|
||||||
|
<mat-error *ngIf="createClientForm.controls.firstname.hasError('required')">
|
||||||
|
Client first name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="createClientForm.controls.firstname.hasError('pattern')">
|
||||||
|
Client first name <strong>cannot</strong> begin with a special character or number
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.contains('middlename')" fxFlex="48%">
|
||||||
|
<mat-label>Middle Name</mat-label>
|
||||||
|
<input matInput formControlName="middlename">
|
||||||
|
<mat-error *ngIf="createClientForm.controls.middlename.hasError('pattern')">
|
||||||
|
Client middle name <strong>cannot</strong> begin with a special character or number
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.contains('lastname')" fxFlex="48%">
|
||||||
|
<mat-label>Last Name</mat-label>
|
||||||
|
<input matInput required formControlName="lastname">
|
||||||
|
<mat-error *ngIf="createClientForm.controls.lastname.hasError('required')">
|
||||||
|
Client last name is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="createClientForm.controls.lastname.hasError('pattern')">
|
||||||
|
Client last name <strong>cannot</strong> begin with a special character or number
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>{{ createClientForm.value.legalFormId === 1 ? 'Date of Birth' : 'Incorporation Date' }}</mat-label>
|
||||||
|
<input matInput [max]="maxDate" [matDatepicker]="dateOfBirthDatePicker" formControlName="dateOfBirth">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="dateOfBirthDatePicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #dateOfBirthDatePicker></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>External Id</mat-label>
|
||||||
|
<input matInput formControlName="externalId">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Mobile No</mat-label>
|
||||||
|
<input matInput type="number" formControlName="mobileNo">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.value.legalFormId === 1" fxFlex="48%">
|
||||||
|
<mat-label>Gender</mat-label>
|
||||||
|
<mat-select formControlName="genderId">
|
||||||
|
<mat-option *ngFor="let gender of genderOptions" [value]="gender.id">
|
||||||
|
{{ gender.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox *ngIf="createClientForm.value.legalFormId === 1" fxFlex="48%" labelPosition="before" formControlName="isStaff" class="margin-v">
|
||||||
|
Is staff?
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Client Type</mat-label>
|
||||||
|
<mat-select formControlName="clientTypeId">
|
||||||
|
<mat-option *ngFor="let clientType of clientTypeOptions" [value]="clientType.id">
|
||||||
|
{{ clientType.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Client Classification</mat-label>
|
||||||
|
<mat-select formControlName="clientClassificationId">
|
||||||
|
<mat-option *ngFor="let clientClassification of clientClassificationTypeOptions" [value]="clientClassification.id">
|
||||||
|
{{ clientClassification.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Submitted On</mat-label>
|
||||||
|
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="submittedOnDatePicker" formControlName="submittedOnDate">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="submittedOnDatePicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #submittedOnDatePicker></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox fxFlex="48%" labelPosition="before" formControlName="active" class="margin-v">
|
||||||
|
Active?
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.contains('activationDate')" fxFlex="48%">
|
||||||
|
<mat-label>Activation Date</mat-label>
|
||||||
|
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="activatedOnDatePicker" required
|
||||||
|
formControlName="activationDate">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="activatedOnDatePicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #activatedOnDatePicker></mat-datepicker>
|
||||||
|
<mat-error *ngIf="createClientForm.controls.activationDate.hasError('required')">
|
||||||
|
Activation Date is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox fxFlex="48%" labelPosition="before" formControlName="addSavings" class="margin-v">
|
||||||
|
Open Savings Account?
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-form-field *ngIf="createClientForm.contains('savingsProductId')" fxFlex="48%">
|
||||||
|
<mat-label>Savings Product</mat-label>
|
||||||
|
<mat-select required formControlName="savingsProductId">
|
||||||
|
<mat-option *ngFor="let product of savingProductOptions" [value]="product.id">
|
||||||
|
{{ product.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="createClientForm.controls.savingsProductId.hasError('required')">
|
||||||
|
Savings product is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div fxFlex="100%" fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" formGroupName="clientNonPersonDetails"
|
||||||
|
*ngIf="createClientForm.contains('clientNonPersonDetails')">
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Incorporation Validity Till Date</mat-label>
|
||||||
|
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="incorpValidityTillDateDatePicker" formControlName="incorpValidityTillDate">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="incorpValidityTillDateDatePicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #incorpValidityTillDateDatePicker></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Incorporation Number</mat-label>
|
||||||
|
<input matInput formControlName="incorpNumber">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Main Business Line</mat-label>
|
||||||
|
<mat-select formControlName="mainBusinessLineId">
|
||||||
|
<mat-option *ngFor="let business of businessLineOptions" [value]="business.id">
|
||||||
|
{{ business.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>Constitution</mat-label>
|
||||||
|
<mat-select formControlName="constitutionId">
|
||||||
|
<mat-option *ngFor="let constitution of constitutionOptions" [value]="constitution.id">
|
||||||
|
{{ constitution.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="98%">
|
||||||
|
<mat-label>Remarks</mat-label>
|
||||||
|
<textarea matInput formControlName="remarks"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious disabled>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
.margin-v {
|
||||||
|
margin: 2em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ClientGeneralStepComponent } from './client-general-step.component';
|
||||||
|
|
||||||
|
describe('ClientGeneralStepComponent', () => {
|
||||||
|
let component: ClientGeneralStepComponent;
|
||||||
|
let fixture: ComponentFixture<ClientGeneralStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ClientGeneralStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ClientGeneralStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Client Component
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-client-general-step',
|
||||||
|
templateUrl: './client-general-step.component.html',
|
||||||
|
styleUrls: ['./client-general-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ClientGeneralStepComponent implements OnInit {
|
||||||
|
|
||||||
|
/** Minimum date allowed. */
|
||||||
|
minDate = new Date(2000, 0, 1);
|
||||||
|
/** Maximum date allowed. */
|
||||||
|
maxDate = new Date();
|
||||||
|
|
||||||
|
/** Client Template */
|
||||||
|
@Input() clientTemplate: any;
|
||||||
|
/** Create Client Form */
|
||||||
|
createClientForm: FormGroup;
|
||||||
|
|
||||||
|
/** Office Options */
|
||||||
|
officeOptions: any;
|
||||||
|
/** Staff Options */
|
||||||
|
staffOptions: any;
|
||||||
|
/** Legal Form Options */
|
||||||
|
legalFormOptions: any;
|
||||||
|
/** Client Type Options */
|
||||||
|
clientTypeOptions: any;
|
||||||
|
/** Client Classification Options */
|
||||||
|
clientClassificationTypeOptions: any;
|
||||||
|
/** Business Line Options */
|
||||||
|
businessLineOptions: any;
|
||||||
|
/** Constitution Options */
|
||||||
|
constitutionOptions: any;
|
||||||
|
/** Gender Options */
|
||||||
|
genderOptions: any;
|
||||||
|
/** Saving Product Options */
|
||||||
|
savingProductOptions: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormBuilder} formBuilder Form Builder
|
||||||
|
* @param {DatePipe} datePipe Date Pipe
|
||||||
|
*/
|
||||||
|
constructor(private formBuilder: FormBuilder,
|
||||||
|
private datePipe: DatePipe) {
|
||||||
|
this.setClientForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.setOptions();
|
||||||
|
this.buildDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the client form.
|
||||||
|
*/
|
||||||
|
setClientForm() {
|
||||||
|
this.createClientForm = this.formBuilder.group({
|
||||||
|
'officeId': ['', Validators.required],
|
||||||
|
'staffId': [''],
|
||||||
|
'legalFormId': [''],
|
||||||
|
'isStaff': [false],
|
||||||
|
'active': [false],
|
||||||
|
'addSavings': [false],
|
||||||
|
'accountNo': [''],
|
||||||
|
'externalId': [''],
|
||||||
|
'genderId': [''],
|
||||||
|
'mobileNo': [''],
|
||||||
|
'dateOfBirth': [''],
|
||||||
|
'clientTypeId': [''],
|
||||||
|
'clientClassificationId': [''],
|
||||||
|
'submittedOnDate': ['']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets select dropdown options.
|
||||||
|
*/
|
||||||
|
setOptions() {
|
||||||
|
this.officeOptions = this.clientTemplate.officeOptions;
|
||||||
|
this.staffOptions = this.clientTemplate.staffOptions;
|
||||||
|
this.legalFormOptions = this.clientTemplate.clientLegalFormOptions;
|
||||||
|
this.clientTypeOptions = this.clientTemplate.clientTypeOptions;
|
||||||
|
this.clientClassificationTypeOptions = this.clientTemplate.clientClassificationOptions;
|
||||||
|
this.businessLineOptions = this.clientTemplate.clientNonPersonMainBusinessLineOptions;
|
||||||
|
this.constitutionOptions = this.clientTemplate.clientNonPersonConstitutionOptions;
|
||||||
|
this.genderOptions = this.clientTemplate.genderOptions;
|
||||||
|
this.savingProductOptions = this.clientTemplate.savingProductOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds controls conditionally.
|
||||||
|
*/
|
||||||
|
buildDependencies() {
|
||||||
|
this.createClientForm.get('legalFormId').valueChanges.subscribe((legalFormId: any) => {
|
||||||
|
if (legalFormId === 1) {
|
||||||
|
this.createClientForm.removeControl('fullname');
|
||||||
|
this.createClientForm.removeControl('clientNonPersonDetails');
|
||||||
|
this.createClientForm.addControl('firstname', new FormControl('', [Validators.required, Validators.pattern('(^[A-z]).*')]));
|
||||||
|
this.createClientForm.addControl('middlename', new FormControl('', Validators.pattern('(^[A-z]).*')));
|
||||||
|
this.createClientForm.addControl('lastname', new FormControl('', [Validators.required, Validators.pattern('(^[A-z]).*')]));
|
||||||
|
} else {
|
||||||
|
this.createClientForm.removeControl('firstname');
|
||||||
|
this.createClientForm.removeControl('middlename');
|
||||||
|
this.createClientForm.removeControl('lastname');
|
||||||
|
this.createClientForm.addControl('fullname', new FormControl('', [Validators.required, Validators.pattern('(^[A-z]).*')]));
|
||||||
|
this.createClientForm.addControl('clientNonPersonDetails', this.formBuilder.group({
|
||||||
|
'constitutionId': [''],
|
||||||
|
'incorpValidityTillDate': [''],
|
||||||
|
'incorpNumber': [''],
|
||||||
|
'mainBusinessLineId': [''],
|
||||||
|
'remarks': ['']
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.createClientForm.get('legalFormId').patchValue(1);
|
||||||
|
this.createClientForm.get('active').valueChanges.subscribe((active: boolean) => {
|
||||||
|
if (active) {
|
||||||
|
this.createClientForm.addControl('activationDate', new FormControl('', Validators.required));
|
||||||
|
} else {
|
||||||
|
this.createClientForm.removeControl('activationDate');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.createClientForm.get('addSavings').valueChanges.subscribe((active: boolean) => {
|
||||||
|
if (active) {
|
||||||
|
this.createClientForm.addControl('savingsProductId', new FormControl('', Validators.required));
|
||||||
|
} else {
|
||||||
|
this.createClientForm.removeControl('savingsProductId');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client General Details
|
||||||
|
*/
|
||||||
|
get clientGeneralDetails() {
|
||||||
|
const generalDetails = this.createClientForm.value;
|
||||||
|
const dateFormat = 'dd MMMM yyyy';
|
||||||
|
const locale = 'en';
|
||||||
|
// TODO: Update once language and date settings are setup
|
||||||
|
for (const key in generalDetails) {
|
||||||
|
if (generalDetails[key] === '' || key === 'addSavings') {
|
||||||
|
delete generalDetails[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (generalDetails.submittedOnDate) {
|
||||||
|
generalDetails.submittedOnDate = this.datePipe.transform(generalDetails.submittedOnDate, dateFormat);
|
||||||
|
}
|
||||||
|
if (generalDetails.activationDate) {
|
||||||
|
generalDetails.activationDate = this.datePipe.transform(generalDetails.activationDate, dateFormat);
|
||||||
|
}
|
||||||
|
if (generalDetails.dateOfBirth) {
|
||||||
|
generalDetails.dateOfBirth = this.datePipe.transform(generalDetails.dateOfBirth, dateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (generalDetails.clientNonPersonDetails && generalDetails.clientNonPersonDetails.incorpValidityTillDate) {
|
||||||
|
generalDetails.clientNonPersonDetails = {
|
||||||
|
...generalDetails.clientNonPersonDetails,
|
||||||
|
incorpValidityTillDate: this.datePipe.transform(generalDetails.dateOfBirth, dateFormat),
|
||||||
|
dateFormat,
|
||||||
|
locale
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return generalDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+218
@@ -0,0 +1,218 @@
|
|||||||
|
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>General</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Name</span>
|
||||||
|
<span fxFlex="60%" *ngIf="client.legalFormId === 2">{{ client.fullname }}</span>
|
||||||
|
<span fxFlex="60%" *ngIf="client.legalFormId === 1">{{ client.firstname }} {{ client.middlename ? client.middlename + ' ' + client.lastname : client.lastname }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Office</span>
|
||||||
|
<span fxFlex="60%">{{ client.officeId | find:clientTemplate.officeOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Legal Form</span>
|
||||||
|
<span fxFlex="60%">{{ client.legalFormId | find:clientTemplate.clientLegalFormOptions:'id':'value' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.staffId">
|
||||||
|
<span fxFlex="40%">Staff</span>
|
||||||
|
<span fxFlex="60%">{{ client.staffId | find:clientTemplate.staffOptions:'id':'displayName' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.dateOfBirth">
|
||||||
|
<span fxFlex="40%">{{ client.legalFormId === 1 ? 'Date of Birth' : 'Incorporation Date' }}</span>
|
||||||
|
<span fxFlex="60%">{{ client.dateOfBirth | date }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.externalId">
|
||||||
|
<span fxFlex="40%">External Id</span>
|
||||||
|
<span fxFlex="60%">{{ client.externalId }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.mobileNo">
|
||||||
|
<span fxFlex="40%">Mobile No</span>
|
||||||
|
<span fxFlex="60%">{{ client.mobileNo }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.clientTypeId">
|
||||||
|
<span fxFlex="40%">Client Type</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientTypeId | find:clientTemplate.clientTypeOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.clientClassificationId">
|
||||||
|
<span fxFlex="40%">Client Classification</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientClassificationId | find:clientTemplate.clientClassificationOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.savingsProductId">
|
||||||
|
<span fxFlex="40%">Savings Product</span>
|
||||||
|
<span fxFlex="60%">{{ client.savingsProductId | find:clientTemplate.savingProductOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.submittedOnDate">
|
||||||
|
<span fxFlex="40%">Submitted On Date</span>
|
||||||
|
<span fxFlex="60%">{{ client.submittedOnDate | date }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Active?</span>
|
||||||
|
<span fxFlex="60%">{{ client.active ? 'Yes' : 'No' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.activationDate">
|
||||||
|
<span fxFlex="40%">Activation Date</span>
|
||||||
|
<span fxFlex="60%">{{ client.activationDate | date }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-container *ngIf="client.legalFormId === 1">
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.genderId">
|
||||||
|
<span fxFlex="40%">Gender</span>
|
||||||
|
<span fxFlex="60%">{{ client.genderId | find:clientTemplate.genderOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Is Staff?</span>
|
||||||
|
<span fxFlex="60%">{{ client.isStaff ? 'Yes' : 'No' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="client.legalFormId === 2">
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.clientNonPersonDetails.incorpValidityTillDate">
|
||||||
|
<span fxFlex="40%">Incorporation Validity Till Date</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientNonPersonDetails.incorpValidityTillDate | date }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Incorportation Number</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientNonPersonDetails.incorpNumber || 'Not Provided' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.clientNonPersonDetails.mainBusinessLineId">
|
||||||
|
<span fxFlex="40%">Main Business Line</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientNonPersonDetails.mainBusinessLineId | find:clientTemplate.clientNonPersonMainBusinessLineOptions:'id':'name' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.clientNonPersonDetails.constitutionId">
|
||||||
|
<span fxFlex="40%">Constitution</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientNonPersonDetails.constitutionId | find:clientTemplate.clientNonPersonConstitutionOptions:'id':'name'}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="40%">Remarks</span>
|
||||||
|
<span fxFlex="60%">{{ client.clientNonPersonDetails.remarks || 'N/A' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.familyMembers.length" fxLayout="row wrap" fxLayout.lt-md="column" class="m-b-20">
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Family Members</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<mat-accordion fxFlexFill class="m-t-5">
|
||||||
|
|
||||||
|
<mat-expansion-panel *ngFor="let member of client.familyMembers" class="family-member">
|
||||||
|
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-panel-title>
|
||||||
|
{{ member.firstName }} {{ member.middleName ? member.middleName + ' ' + member.lastName : member.lastName }}
|
||||||
|
</mat-panel-title>
|
||||||
|
|
||||||
|
<mat-panel-description>
|
||||||
|
{{member.relationship}}
|
||||||
|
</mat-panel-description>
|
||||||
|
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
First Name : {{ member.firstName }}<br />
|
||||||
|
Middle Name : {{ member.middleName }}<br />
|
||||||
|
Last Name : {{ member.lastName }}<br />
|
||||||
|
Qualification : {{ member.qualification }}<br />
|
||||||
|
Relationship : {{ member.relationshipId | find:clientTemplate.familyMemberOptions.relationshipIdOptions:'id':'name' }}<br />
|
||||||
|
Age : {{ member.age }}<br />
|
||||||
|
Is Dependent : {{ member.isDependent ? 'Yes' : 'No' }}<br />
|
||||||
|
Marital Status : {{ member.maritalStatusId | find:clientTemplate.familyMemberOptions.maritalStatusIdOptions:'id':'name' }}<br />
|
||||||
|
Gender : {{ member.genderId | find:clientTemplate.familyMemberOptions.genderIdOptions:'id':'name' }}<br />
|
||||||
|
Profession : {{ member.professionId | find:clientTemplate.familyMemberOptions.professionIdOptions:'id':'name' }}<br />
|
||||||
|
Date Of Birth : {{ member.dateOfBirth | date }}<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</mat-expansion-panel>
|
||||||
|
|
||||||
|
</mat-accordion>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="client.address.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<h3 class="mat-h3" fxFlexFill>Address</h3>
|
||||||
|
|
||||||
|
<mat-divider fxFlexFill></mat-divider>
|
||||||
|
|
||||||
|
<mat-accordion fxFlexFill class="m-t-5">
|
||||||
|
|
||||||
|
<mat-expansion-panel *ngFor="let address of client.address" class="address">
|
||||||
|
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-panel-title>
|
||||||
|
{{ getSelectedValue('addressTypeIdOptions',address.addressTypeId)?.name }}
|
||||||
|
</mat-panel-title>
|
||||||
|
|
||||||
|
<mat-panel-description>
|
||||||
|
{{address.relationship}}
|
||||||
|
</mat-panel-description>
|
||||||
|
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span *ngIf="isFieldEnabled('street')">Street : {{address.street}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('addressLine1')">Address Line 1 : {{address.addressLine1}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('addressLine2')">Address Line 2 : {{address.addressLine2}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('addressLine3')">Address Line 3 : {{address.addressLine3}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('townVillage')">Town / Village : {{address.townVillage}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('city')">City : {{address.city}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('stateProvinceId')">State / Province :
|
||||||
|
{{getSelectedValue('stateProvinceIdOptions',address.stateProvinceId)?.name}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('countryId')">Country :
|
||||||
|
{{getSelectedValue('countryIdOptions',address.countryId)?.name}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('postalCode')">Postal Code : {{address.postalCode}}<br /></span>
|
||||||
|
<span *ngIf="isFieldEnabled('isActive')">Active Status : {{address.isActive}}<br /></span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</mat-expansion-panel>
|
||||||
|
|
||||||
|
</mat-accordion>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button [routerLink]="['../']">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="submit.emit()">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
h2, h3, h4 {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-divider {
|
||||||
|
margin: 0 0 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-t {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.family-member {
|
||||||
|
h3 {
|
||||||
|
margin: 1% auto;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 2%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
h3 {
|
||||||
|
margin: 1% auto;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 2%;
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ClientPreviewStepComponent } from './client-preview-step.component';
|
||||||
|
|
||||||
|
describe('ClientPreviewStepComponent', () => {
|
||||||
|
let component: ClientPreviewStepComponent;
|
||||||
|
let fixture: ComponentFixture<ClientPreviewStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ClientPreviewStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ClientPreviewStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, Output, EventEmitter, Input } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client Preview Step Component
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-client-preview-step',
|
||||||
|
templateUrl: './client-preview-step.component.html',
|
||||||
|
styleUrls: ['./client-preview-step.component.scss']
|
||||||
|
})
|
||||||
|
export class ClientPreviewStepComponent {
|
||||||
|
|
||||||
|
/** Client Address field configuration */
|
||||||
|
@Input() clientAddressFieldConfig: any;
|
||||||
|
/** Client Template */
|
||||||
|
@Input() clientTemplate: any;
|
||||||
|
/** Client Object */
|
||||||
|
@Input() client: any;
|
||||||
|
|
||||||
|
/** Form submission event */
|
||||||
|
@Output() submit = new EventEmitter();
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilized in address preview.
|
||||||
|
* Find pipe doesn't work with accordian.
|
||||||
|
* @param {any} fieldName Field Name
|
||||||
|
* @param {any} fieldId Field Id
|
||||||
|
*/
|
||||||
|
getSelectedValue(fieldName: any, fieldId: any) {
|
||||||
|
return (this.clientTemplate.address[fieldName].find((fieldObj: any) => fieldObj.id === fieldId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilized in address preview to check if field is enabled in configuration.
|
||||||
|
* @param {any} fieldName Field Name
|
||||||
|
*/
|
||||||
|
isFieldEnabled(fieldName: any) {
|
||||||
|
return (this.clientAddressFieldConfig.find((fieldObj: any) => fieldObj.field === fieldName)).is_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ import { ClientActionsComponent } from './clients-view/client-actions/client-act
|
|||||||
import { ViewChargeComponent } from './clients-view/charges/view-charge/view-charge.component';
|
import { ViewChargeComponent } from './clients-view/charges/view-charge/view-charge.component';
|
||||||
import { ClientPayChargesComponent } from './clients-view/charges/client-pay-charges/client-pay-charges.component';
|
import { ClientPayChargesComponent } from './clients-view/charges/client-pay-charges/client-pay-charges.component';
|
||||||
import { EditClientComponent } from './edit-client/edit-client.component';
|
import { EditClientComponent } from './edit-client/edit-client.component';
|
||||||
|
import { CreateClientComponent } from './create-client/create-client.component';
|
||||||
|
|
||||||
/** Custom Resolvers */
|
/** Custom Resolvers */
|
||||||
import { ClientViewResolver } from './common-resolvers/client-view.resolver';
|
import { ClientViewResolver } from './common-resolvers/client-view.resolver';
|
||||||
@@ -55,7 +56,16 @@ const routes: Routes = [
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: ClientsComponent,
|
component: ClientsComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
data: { title: extract('Create Client'), breadcrumb: 'Create Client', routeParamBreadcrumb: false },
|
||||||
|
component: CreateClientComponent,
|
||||||
|
resolve: {
|
||||||
|
clientAddressFieldConfig: ClientAddressFieldConfigurationResolver,
|
||||||
|
clientTemplate: ClientTemplateResolver
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':clientId',
|
path: ':clientId',
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-button" fxLayoutGap="25px">
|
<div class="action-button" fxLayoutGap="25px">
|
||||||
<button mat-raised-button color="primary" [routerLink]="['./import']">
|
<button mat-raised-button color="primary" [routerLink]="['import']">
|
||||||
<fa-icon icon="download"></fa-icon> Import Client
|
<fa-icon icon="download"></fa-icon> Import Client
|
||||||
</button>
|
</button>
|
||||||
<button mat-raised-button color="primary" [routerLink]="['./add']">
|
<button mat-raised-button color="primary" [routerLink]="['create']">
|
||||||
<fa-icon icon="plus"></fa-icon> Create Client
|
<fa-icon icon="plus"></fa-icon> Create Client
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,7 +65,6 @@
|
|||||||
<td mat-cell *matCellDef="let row"> {{row.officeName}} </td>
|
<td mat-cell *matCellDef="let row"> {{row.officeName}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
<!-- ID Column -->
|
<!-- ID Column -->
|
||||||
<ng-container matColumnDef="staff">
|
<ng-container matColumnDef="staff">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header='staffName'> StaffName </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header='staffName'> StaffName </th>
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ import { DeleteSignatureDialogComponent } from './clients-view/custom-dialogs/de
|
|||||||
import { UploadImageDialogComponent } from './clients-view/custom-dialogs/upload-image-dialog/upload-image-dialog.component';
|
import { UploadImageDialogComponent } from './clients-view/custom-dialogs/upload-image-dialog/upload-image-dialog.component';
|
||||||
import { ClientScreenReportsComponent } from './clients-view/client-actions/client-screen-reports/client-screen-reports.component';
|
import { ClientScreenReportsComponent } from './clients-view/client-actions/client-screen-reports/client-screen-reports.component';
|
||||||
import { EditClientComponent } from './edit-client/edit-client.component';
|
import { EditClientComponent } from './edit-client/edit-client.component';
|
||||||
|
import { CreateClientComponent } from './create-client/create-client.component';
|
||||||
|
import { ClientGeneralStepComponent } from './client-stepper/client-general-step/client-general-step.component';
|
||||||
|
import { ClientFamilyMembersStepComponent } from './client-stepper/client-family-members-step/client-family-members-step.component';
|
||||||
|
import { ClientPreviewStepComponent } from './client-stepper/client-preview-step/client-preview-step.component';
|
||||||
|
import { ClientAddressStepComponent } from './client-stepper/client-address-step/client-address-step.component';
|
||||||
|
import { ClientFamilyMemberDialogComponent } from './client-stepper/client-family-members-step/client-family-member-dialog/client-family-member-dialog.component';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,7 +111,13 @@ import { EditClientComponent } from './edit-client/edit-client.component';
|
|||||||
DeleteSignatureDialogComponent,
|
DeleteSignatureDialogComponent,
|
||||||
UploadImageDialogComponent,
|
UploadImageDialogComponent,
|
||||||
ClientScreenReportsComponent,
|
ClientScreenReportsComponent,
|
||||||
EditClientComponent
|
EditClientComponent,
|
||||||
|
CreateClientComponent,
|
||||||
|
ClientGeneralStepComponent,
|
||||||
|
ClientFamilyMembersStepComponent,
|
||||||
|
ClientPreviewStepComponent,
|
||||||
|
ClientAddressStepComponent,
|
||||||
|
ClientFamilyMemberDialogComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
UploadDocumentDialogComponent,
|
UploadDocumentDialogComponent,
|
||||||
@@ -114,7 +126,8 @@ import { EditClientComponent } from './edit-client/edit-client.component';
|
|||||||
ViewSignatureDialogComponent,
|
ViewSignatureDialogComponent,
|
||||||
UploadSignatureDialogComponent,
|
UploadSignatureDialogComponent,
|
||||||
DeleteSignatureDialogComponent,
|
DeleteSignatureDialogComponent,
|
||||||
UploadImageDialogComponent
|
UploadImageDialogComponent,
|
||||||
|
ClientFamilyMemberDialogComponent
|
||||||
],
|
],
|
||||||
providers: [DatePipe]
|
providers: [DatePipe]
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ export class ClientsService {
|
|||||||
return this.http.get(`/clients/${clientId}`);
|
return this.http.get(`/clients/${clientId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createClient(client: any) {
|
||||||
|
return this.http.post(`/clients`, client);
|
||||||
|
}
|
||||||
|
|
||||||
updateClient(clientId: string, client: any) {
|
updateClient(clientId: string, client: any) {
|
||||||
return this.http.put(`/clients/${clientId}`, client);
|
return this.http.put(`/clients/${clientId}`, client);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<mat-horizontal-stepper class="mat-elevation-z8" labelPosition="bottom" #clientStepper>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="number">
|
||||||
|
<fa-icon icon="pencil-alt" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="edit">
|
||||||
|
<fa-icon icon="pencil-alt" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="done">
|
||||||
|
<fa-icon icon="check" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="error">
|
||||||
|
<fa-icon icon="exclamation-triangle" size="lg"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template matStepperIcon="preview">
|
||||||
|
<fa-icon icon="eye" size="sm"></fa-icon>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<mat-step [stepControl]="clientGeneralForm">
|
||||||
|
|
||||||
|
<ng-template matStepLabel>GENERAL</ng-template>
|
||||||
|
|
||||||
|
<mifosx-client-general-step [clientTemplate]="clientTemplate"></mifosx-client-general-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>FAMILY MEMBERS</ng-template>
|
||||||
|
|
||||||
|
<mifosx-client-family-members-step [clientTemplate]="clientTemplate"></mifosx-client-family-members-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>ADDRESS</ng-template>
|
||||||
|
|
||||||
|
<mifosx-client-address-step
|
||||||
|
[clientTemplate]="clientTemplate"
|
||||||
|
[clientAddressFieldConfig]="clientAddressFieldConfig"
|
||||||
|
>
|
||||||
|
</mifosx-client-address-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step *ngIf="clientGeneralForm.valid" completed>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>PREVIEW</ng-template>
|
||||||
|
|
||||||
|
<mifosx-client-preview-step
|
||||||
|
[clientTemplate]="clientTemplate"
|
||||||
|
[clientAddressFieldConfig]="clientAddressFieldConfig"
|
||||||
|
[client]="client" (submit)="submit()"
|
||||||
|
>
|
||||||
|
</mifosx-client-preview-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
|
</mat-horizontal-stepper>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CreateClientComponent } from './create-client.component';
|
||||||
|
|
||||||
|
describe('CreateClientComponent', () => {
|
||||||
|
let component: CreateClientComponent;
|
||||||
|
let fixture: ComponentFixture<CreateClientComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CreateClientComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CreateClientComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, ViewChild } from '@angular/core';
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
|
/** Custom Services */
|
||||||
|
import { ClientsService } from '../clients.service';
|
||||||
|
|
||||||
|
/** Custom Components */
|
||||||
|
import { ClientGeneralStepComponent } from '../client-stepper/client-general-step/client-general-step.component';
|
||||||
|
import { ClientFamilyMembersStepComponent } from '../client-stepper/client-family-members-step/client-family-members-step.component';
|
||||||
|
import { ClientAddressStepComponent } from '../client-stepper/client-address-step/client-address-step.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Client Component.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-create-client',
|
||||||
|
templateUrl: './create-client.component.html',
|
||||||
|
styleUrls: ['./create-client.component.scss']
|
||||||
|
})
|
||||||
|
export class CreateClientComponent {
|
||||||
|
|
||||||
|
/** Client General Step */
|
||||||
|
@ViewChild(ClientGeneralStepComponent) clientGeneralStep: ClientGeneralStepComponent;
|
||||||
|
/** Client Family Members Step */
|
||||||
|
@ViewChild(ClientFamilyMembersStepComponent) clientFamilyMembersStep: ClientFamilyMembersStepComponent;
|
||||||
|
/** Client Address Step */
|
||||||
|
@ViewChild(ClientAddressStepComponent) clientAddressStep: ClientAddressStepComponent;
|
||||||
|
|
||||||
|
/** Client Template */
|
||||||
|
clientTemplate: any;
|
||||||
|
/** Client Address Field Config */
|
||||||
|
clientAddressFieldConfig: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches client and address template from `resolve`
|
||||||
|
* @param {ActivatedRoute} route Activated Route
|
||||||
|
* @param {Router} router Router
|
||||||
|
* @param {ClientsService} clientsService Clients Service
|
||||||
|
*/
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private clientsService: ClientsService) {
|
||||||
|
this.route.data.subscribe((data: { clientTemplate: any, clientAddressFieldConfig: any }) => {
|
||||||
|
this.clientTemplate = data.clientTemplate;
|
||||||
|
this.clientAddressFieldConfig = data.clientAddressFieldConfig;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves general information about client.
|
||||||
|
*/
|
||||||
|
get clientGeneralForm() {
|
||||||
|
return this.clientGeneralStep.createClientForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the client object
|
||||||
|
*/
|
||||||
|
get client() {
|
||||||
|
return {
|
||||||
|
...this.clientGeneralStep.clientGeneralDetails,
|
||||||
|
...this.clientFamilyMembersStep.familyMembers,
|
||||||
|
...this.clientAddressStep.address
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Submits the create client form.
|
||||||
|
*/
|
||||||
|
submit() {
|
||||||
|
const locale = 'en';
|
||||||
|
const dateFormat = 'dd MMMM yyyy';
|
||||||
|
// TODO: Update once language and date settings are setup
|
||||||
|
const clientData = {
|
||||||
|
...this.client,
|
||||||
|
dateFormat,
|
||||||
|
locale
|
||||||
|
};
|
||||||
|
this.clientsService.createClient(clientData).subscribe((response: any) => {
|
||||||
|
this.router.navigate(['../', response.resourceId], { relativeTo: this.route });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user