@@ -30,6 +30,7 @@ export class GroupActionsResolver implements Resolve<Object> {
|
|||||||
switch (actionName) {
|
switch (actionName) {
|
||||||
case 'Attendance':
|
case 'Attendance':
|
||||||
case 'Manage Members':
|
case 'Manage Members':
|
||||||
|
case 'Transfer Clients':
|
||||||
return this.groupsService.getGroupData(groupId);
|
return this.groupsService.getGroupData(groupId);
|
||||||
case 'Assign Staff':
|
case 'Assign Staff':
|
||||||
return this.groupsService.getGroupData(groupId, 'true');
|
return this.groupsService.getGroupData(groupId, 'true');
|
||||||
|
|||||||
@@ -6,3 +6,4 @@
|
|||||||
<mifosx-manage-group-members *ngIf="actions['Manage Members']"></mifosx-manage-group-members>
|
<mifosx-manage-group-members *ngIf="actions['Manage Members']"></mifosx-manage-group-members>
|
||||||
<mifosx-edit-group-meeting *ngIf="actions['Edit Meeting']"></mifosx-edit-group-meeting>
|
<mifosx-edit-group-meeting *ngIf="actions['Edit Meeting']"></mifosx-edit-group-meeting>
|
||||||
<mifosx-edit-group-meeting-schedule *ngIf="actions['Edit Meeting Schedule']"></mifosx-edit-group-meeting-schedule>
|
<mifosx-edit-group-meeting-schedule *ngIf="actions['Edit Meeting Schedule']"></mifosx-edit-group-meeting-schedule>
|
||||||
|
<mifosx-group-transfer-clients *ngIf="actions['Transfer Clients']"></mifosx-group-transfer-clients>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export class GroupActionsComponent {
|
|||||||
'Manage Members': boolean
|
'Manage Members': boolean
|
||||||
'Edit Meeting': boolean
|
'Edit Meeting': boolean
|
||||||
'Edit Meeting Schedule': boolean
|
'Edit Meeting Schedule': boolean
|
||||||
|
'Transfer Clients': boolean
|
||||||
} = {
|
} = {
|
||||||
'Assign Staff': false,
|
'Assign Staff': false,
|
||||||
'Close': false,
|
'Close': false,
|
||||||
@@ -30,7 +31,8 @@ export class GroupActionsComponent {
|
|||||||
'Attendance': false,
|
'Attendance': false,
|
||||||
'Manage Members': false,
|
'Manage Members': false,
|
||||||
'Edit Meeting': false,
|
'Edit Meeting': false,
|
||||||
'Edit Meeting Schedule': false
|
'Edit Meeting Schedule': false,
|
||||||
|
'Transfer Clients': false
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<mat-card>
|
||||||
|
|
||||||
|
<form [formGroup]="transferClientsForm">
|
||||||
|
|
||||||
|
<mat-card-content>
|
||||||
|
|
||||||
|
<div fxLayout="column">
|
||||||
|
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Select Client Members for Transfer</mat-label>
|
||||||
|
<mat-select required formControlName="clients" multiple>
|
||||||
|
<mat-option *ngFor="let member of clientMembers" [value]="{ id: member.id }">
|
||||||
|
{{ member.displayName }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="transferClientsForm.controls.clients.hasError('required')">
|
||||||
|
Office is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox class="m-t-10 m-b-10" labelPosition="before" formControlName="inheritDestinationGroupLoanOfficer">
|
||||||
|
Inherit Group Loan Officer?
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Destination Group</mat-label>
|
||||||
|
<input matInput formControlName="destinationGroupId" [matAutocomplete]="groupsAutocomplete">
|
||||||
|
<mat-error *ngIf="transferClientsForm.controls.destinationGroupId.hasError('required')">
|
||||||
|
Destination Group is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-autocomplete autoActiveFirstOption #groupsAutocomplete="matAutocomplete" [displayWith]="displayGroup">
|
||||||
|
<mat-option *ngFor="let group of groupsData" [value]="group">
|
||||||
|
{{ group.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-autocomplete>
|
||||||
|
|
||||||
|
<div class="mat-table" *ngIf="transferClientsForm.get('destinationGroupId').value">
|
||||||
|
<div class="mat-header-row">
|
||||||
|
<div class="mat-header-cell">Destination Group Details</div>
|
||||||
|
</div>
|
||||||
|
<div class="mat-row">
|
||||||
|
<div class="mat-cell">Name</div>
|
||||||
|
<div class="mat-cell">{{transferClientsForm.get('destinationGroupId').value.name}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="mat-row">
|
||||||
|
<div class="mat-cell">Id</div>
|
||||||
|
<div class="mat-cell">{{transferClientsForm.get('destinationGroupId').value.id}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="mat-row">
|
||||||
|
<div class="mat-cell">Activation Date</div>
|
||||||
|
<div class="mat-cell">{{(transferClientsForm.get('destinationGroupId').value.activationDate | date) || 'Not Activated'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="mat-row">
|
||||||
|
<div class="mat-cell">Staff</div>
|
||||||
|
<div class="mat-cell">{{transferClientsForm.get('destinationGroupId').value.staffName || 'Unassigned'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="mat-row">
|
||||||
|
<div class="mat-cell">External Id</div>
|
||||||
|
<div class="mat-cell">{{transferClientsForm.get('destinationGroupId').value.externalId || 'Unassigned'}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-card-content>
|
||||||
|
|
||||||
|
<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]="!transferClientsForm.valid" (click)="submit()">Submit</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
.container {
|
||||||
|
max-width: 37rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-table {
|
||||||
|
display: block;
|
||||||
|
font-family: Tahoma, Verdana;
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-row,
|
||||||
|
.mat-header-row {
|
||||||
|
display: flex;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 30px;
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-cell,
|
||||||
|
.mat-header-cell {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GroupTransferClientsComponent } from './group-transfer-clients.component';
|
||||||
|
|
||||||
|
describe('GroupTransferClientsComponent', () => {
|
||||||
|
let component: GroupTransferClientsComponent;
|
||||||
|
let fixture: ComponentFixture<GroupTransferClientsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ GroupTransferClientsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(GroupTransferClientsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit, AfterViewInit } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
|
/** Custom Services */
|
||||||
|
import { GroupsService } from 'app/groups/groups.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group Transfer Clients component.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-group-transfer-clients',
|
||||||
|
templateUrl: './group-transfer-clients.component.html',
|
||||||
|
styleUrls: ['./group-transfer-clients.component.scss']
|
||||||
|
})
|
||||||
|
export class GroupTransferClientsComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
|
/** Transfer Clients form. */
|
||||||
|
transferClientsForm: FormGroup;
|
||||||
|
/** Group Data */
|
||||||
|
groupData: any;
|
||||||
|
/** Group data. */
|
||||||
|
groupsData: any = [];
|
||||||
|
/** Staff data. */
|
||||||
|
staffData: any;
|
||||||
|
/** Group Members. */
|
||||||
|
clientMembers: any[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the offices data from `resolve`.
|
||||||
|
* @param {FormBuilder} formBuilder Form Builder.
|
||||||
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
|
* @param {Router} router Router for navigation
|
||||||
|
* @param {GroupsService} groupsService GroupsService.
|
||||||
|
*/
|
||||||
|
constructor(private formBuilder: FormBuilder,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private groupsService: GroupsService) {
|
||||||
|
this.route.data.subscribe((data: { groupActionData: any }) => {
|
||||||
|
this.groupData = data.groupActionData;
|
||||||
|
this.clientMembers = this.groupData.clientMembers;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.createTransferClientsForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribes to Groups search filter:
|
||||||
|
*/
|
||||||
|
ngAfterViewInit() {
|
||||||
|
this.transferClientsForm.get('destinationGroupId').valueChanges.subscribe( (value: string) => {
|
||||||
|
if (value.length >= 2) {
|
||||||
|
this.groupsService.getFilteredGroups('name', 'ASC', value, this.groupData.officeId)
|
||||||
|
.subscribe( (data: any) => {
|
||||||
|
this.groupsData = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the transfer clients form.
|
||||||
|
*/
|
||||||
|
createTransferClientsForm() {
|
||||||
|
this.transferClientsForm = this.formBuilder.group({
|
||||||
|
'clients': ['', Validators.required],
|
||||||
|
'inheritDestinationGroupLoanOfficer': [false],
|
||||||
|
'destinationGroupId': ['', Validators.required]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays Group name in form control input.
|
||||||
|
* @param {any} group Group data.
|
||||||
|
* @returns {string} Group name if valid otherwise undefined.
|
||||||
|
*/
|
||||||
|
displayGroup(group: any): string | undefined {
|
||||||
|
return group ? group.name : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the group form and transfers the clients,
|
||||||
|
* if successful redirects to group.
|
||||||
|
*/
|
||||||
|
submit() {
|
||||||
|
const locale = 'en';
|
||||||
|
const data = {
|
||||||
|
...this.transferClientsForm.value,
|
||||||
|
destinationGroupId: this.transferClientsForm.get('destinationGroupId').value.id,
|
||||||
|
locale
|
||||||
|
};
|
||||||
|
this.groupsService.executeGroupCommand(this.groupData.id, 'transferClients', data).subscribe(() => {
|
||||||
|
this.router.navigate(['../../'], { relativeTo: this.route });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<i class="fa fa-edit"></i>Edit</button>
|
<i class="fa fa-edit"></i>Edit</button>
|
||||||
<button mat-raised-button *mifosxHasPermission="'CREATE_CLIENT'">
|
<button mat-raised-button *mifosxHasPermission="'CREATE_CLIENT'">
|
||||||
<i class="fa fa-plus"></i>Add Clients</button>
|
<i class="fa fa-plus"></i>Add Clients</button>
|
||||||
<button mat-raised-button *mifosxHasPermission="'ASSOCIATECLIENTS_GROUP'">
|
<button mat-raised-button *mifosxHasPermission="'ASSOCIATECLIENTS_GROUP'" (click)="doAction('Transfer Clients')">
|
||||||
<i class="fa fa-exchange"></i>Transfer Clients</button>
|
<i class="fa fa-exchange"></i>Transfer Clients</button>
|
||||||
<button mat-raised-button *mifosxHasPermission="'TRANSFERCLIENTS_GROUP'" (click)="doAction('Manage Members')">
|
<button mat-raised-button *mifosxHasPermission="'TRANSFERCLIENTS_GROUP'" (click)="doAction('Manage Members')">
|
||||||
<i class="fa fa-user"></i>Manage Members</button>
|
<i class="fa fa-user"></i>Manage Members</button>
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ export class GroupsViewComponent {
|
|||||||
case 'Attach Meeting':
|
case 'Attach Meeting':
|
||||||
case 'Attendance':
|
case 'Attendance':
|
||||||
case 'Manage Members':
|
case 'Manage Members':
|
||||||
|
case 'Transfer Clients':
|
||||||
this.router.navigate([`actions/${name}`], { relativeTo: this.route });
|
this.router.navigate([`actions/${name}`], { relativeTo: this.route });
|
||||||
break;
|
break;
|
||||||
case 'Edit Meeting':
|
case 'Edit Meeting':
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { GroupAttendanceComponent } from './groups-view/group-actions/group-atte
|
|||||||
import { ManageGroupMembersComponent } from './groups-view/group-actions/manage-group-members/manage-group-members.component';
|
import { ManageGroupMembersComponent } from './groups-view/group-actions/manage-group-members/manage-group-members.component';
|
||||||
import { EditGroupMeetingComponent } from './groups-view/group-actions/edit-group-meeting/edit-group-meeting.component';
|
import { EditGroupMeetingComponent } from './groups-view/group-actions/edit-group-meeting/edit-group-meeting.component';
|
||||||
import { EditGroupMeetingScheduleComponent } from './groups-view/group-actions/edit-group-meeting-schedule/edit-group-meeting-schedule.component';
|
import { EditGroupMeetingScheduleComponent } from './groups-view/group-actions/edit-group-meeting-schedule/edit-group-meeting-schedule.component';
|
||||||
|
import { GroupTransferClientsComponent } from './groups-view/group-actions/group-transfer-clients/group-transfer-clients.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groups Module
|
* Groups Module
|
||||||
@@ -66,7 +67,8 @@ import { EditGroupMeetingScheduleComponent } from './groups-view/group-actions/e
|
|||||||
GroupAttendanceComponent,
|
GroupAttendanceComponent,
|
||||||
ManageGroupMembersComponent,
|
ManageGroupMembersComponent,
|
||||||
EditGroupMeetingComponent,
|
EditGroupMeetingComponent,
|
||||||
EditGroupMeetingScheduleComponent
|
EditGroupMeetingScheduleComponent,
|
||||||
|
GroupTransferClientsComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
UnassignRoleDialogComponent,
|
UnassignRoleDialogComponent,
|
||||||
|
|||||||
@@ -19,6 +19,23 @@ export class GroupsService {
|
|||||||
*/
|
*/
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} orderBy Property by which entries should be sorted.
|
||||||
|
* @param {string} sortOrder Sort order: ascending or descending.
|
||||||
|
* @param {string} name Filter value for groups names.
|
||||||
|
* @returns {Observable<any>} Groups.
|
||||||
|
*/
|
||||||
|
getFilteredGroups(orderBy: string, sortOrder: string, name: string, officeId?: any): Observable<any> {
|
||||||
|
let httpParams = new HttpParams()
|
||||||
|
.set('name', name)
|
||||||
|
.set('sortOrder', sortOrder)
|
||||||
|
.set('orderBy', orderBy);
|
||||||
|
if (officeId) {
|
||||||
|
httpParams = httpParams.set('officeId', officeId);
|
||||||
|
}
|
||||||
|
return this.http.get('/groups', { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {any} filterBy Properties by which entries should be filtered.
|
* @param {any} filterBy Properties by which entries should be filtered.
|
||||||
* @param {string} orderBy Property by which entries should be sorted.
|
* @param {string} orderBy Property by which entries should be sorted.
|
||||||
@@ -27,7 +44,7 @@ export class GroupsService {
|
|||||||
* @param {number} limit Number of entries within the page.
|
* @param {number} limit Number of entries within the page.
|
||||||
* @returns {Observable<any>} Groups.
|
* @returns {Observable<any>} Groups.
|
||||||
*/
|
*/
|
||||||
getGroups(filterBy: any, orderBy: string, sortOrder: string, offset: number, limit: number): Observable<any> {
|
getGroups(filterBy: any, orderBy: string, sortOrder: string, offset?: number, limit?: number): Observable<any> {
|
||||||
let httpParams = new HttpParams()
|
let httpParams = new HttpParams()
|
||||||
.set('offset', offset.toString())
|
.set('offset', offset.toString())
|
||||||
.set('limit', limit.toString())
|
.set('limit', limit.toString())
|
||||||
|
|||||||
Reference in New Issue
Block a user