Skip to content

Commit 2bfe9a2

Browse files
Merge pull request #67 from josehernandezfintecheandomx/views/paymenthub_003
Backend services integration for Voucher and Identity mapper
2 parents 1894d72 + ac70f23 commit 2bfe9a2

File tree

83 files changed

+880
-3459
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+880
-3459
lines changed

angular.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
"scripts": [],
4141
"allowedCommonJsDependencies": [
4242
"lodash",
43-
"@ckeditor/ckeditor5-build-classic"
43+
"@ckeditor/ckeditor5-build-classic",
44+
"moment",
45+
"jwt-decode",
46+
"js-sha256",
47+
"base64-js",
48+
"clone-deep"
4449
],
4550
"vendorChunk": true,
4651
"extractLicenses": false,

docker-compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ services:
2020
- PH_ACT_BACKEND_SERVER_URL=https://paymenthub.qa.oneacrefund.org/opsapp/api/v1
2121
- PH_PLATFORM_TENANT_ID=phdefault
2222
- PH_PLATFORM_TENANT_IDS=phdefault
23+
- PH_REGISTERING_INSTITUTION_ID=SocialInstitution
2324
- PH_AUTH_ENABLED=false
2425
- PH_OAUTH_ENABLED=false
2526
- PH_OAUTH_TYPE=keycloak

env.sample

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
PH_OPS_BACKEND_SERVER_URL=https://paymenthub.qa.oneacrefund.org/opsapp/api/v1
32

43
PH_VOU_BACKEND_SERVER_URL=https://paymenthub.qa.oneacrefund.org/opsapp/api/v1
@@ -9,12 +8,22 @@ PH_PLATFORM_TENANT_ID=phdefault
98

109
PH_PLATFORM_TENANT_IDS=phdefault
1110

11+
PH_REGISTERING_INSTITUTION_ID=SocialInstitution
12+
1213
PH_AUTH_ENABLED=true
1314

1415
PH_OAUTH_ENABLED=false
1516

17+
PH_OAUTH_TYPE=keycloak
18+
1619
PH_OAUTH_SERVER_URL=https://ops-bk.sandbox.fynarfin.io
1720

21+
PH_OAUTH_REALM=paymenthub
22+
23+
PH_OAUTH_CLIENT_ID=opsapp
24+
25+
PH_OAUTH_CLIENT_SECRET=Y2xpZW50Og==
26+
1827
PH_OAUTH_BASIC_AUTH=true
1928

2029
PH_OAUTH_BASIC_AUTH_TOKEN=Y2xpZW50Og==

src/app/account-mapper/account-mapper/account-mapper.component.html

+16-10
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,35 @@ <h3 class="m-r-10">Filters</h3>
3838
</mat-accordion>
3939

4040
<mat-card class="container">
41-
42-
<table mat-table [dataSource]="dataSource" matSort>
41+
<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar>
42+
43+
<table mat-table [dataSource]="dataSource" matSort *ngIf="!isLoading">
4344

4445
<ng-container matColumnDef="governmentEntity">
4546
<th mat-header-cell *matHeaderCellDef mat-sort-header> Government Entity </th>
4647
<td mat-cell *matCellDef="let item" > {{
47-
shortenValue(item.transactionId) }} </td>
48+
item.registeringInstitutionId }}
49+
</td>
4850
</ng-container>
4951

5052
<ng-container matColumnDef="financialInstitution">
5153
<th mat-header-cell *matHeaderCellDef mat-sort-header> Financial Institution </th>
52-
<td mat-cell *matCellDef="let item" > {{
53-
shortenValue(item.transactionId) }} </td>
54+
<td mat-cell *matCellDef="let item" >
55+
{{ item.payeeIdentity }}
56+
</td>
5457
</ng-container>
5558

5659
<ng-container matColumnDef="functionalId">
5760
<th mat-header-cell *matHeaderCellDef mat-sort-header> Functional ID </th>
58-
<td mat-cell *matCellDef="let item"> {{ item.amount }} </td>
61+
<td mat-cell *matCellDef="let item">
62+
</td>
5963
</ng-container>
6064

6165
<ng-container matColumnDef="financialAddress">
6266
<th mat-header-cell *matHeaderCellDef mat-sort-header> Financial Address </th>
63-
<td mat-cell *matCellDef="let item"> {{ item.amount }} </td>
67+
<td mat-cell *matCellDef="let item">
68+
<mifosx-identifier identifier="{{item.financialAddress}}"></mifosx-identifier>
69+
</td>
6470
</ng-container>
6571

6672
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
@@ -69,9 +75,9 @@ <h3 class="m-r-10">Filters</h3>
6975

7076
</table>
7177

72-
<mat-paginator [length]="dataSource?.records$ | async" [pageSize]="10" [pageSizeOptions]="[10, 25, 50, 100]"
73-
showFirstLastButtons='false'></mat-paginator>
74-
78+
<mat-paginator [pageSize]="pageSize" [pageSizeOptions]="[50, 100, 200]" [length]="totalRows" (page)="pageChanged($event)"
79+
showFirstLastButtons></mat-paginator>
80+
7581
</mat-card>
7682

7783
</div>

src/app/account-mapper/account-mapper/account-mapper.component.ts

+39-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
import { Component } from '@angular/core';
1+
import { Component, ViewChild } from '@angular/core';
22
import { AccountMapperService } from '../services/account-mapper.service';
33
import { UntypedFormControl } from '@angular/forms';
44
import { TransactionsDataSource } from 'app/payment-hub/transactions/dataSource/transactions.datasource';
5+
import { MatPaginator, PageEvent } from '@angular/material/paginator';
6+
import { MatSort } from '@angular/material/sort';
7+
import { MatTableDataSource } from '@angular/material/table';
8+
import { AccountData } from '../models/account-mapper.model';
9+
import { Dates } from 'app/core/utils/dates';
510

611
@Component({
712
selector: 'mifosx-account-mapper',
813
templateUrl: './account-mapper.component.html',
914
styleUrls: ['./account-mapper.component.scss']
1015
})
1116
export class AccountMapperComponent {
17+
18+
@ViewChild(MatPaginator) paginator: MatPaginator;
19+
@ViewChild(MatSort) sort: MatSort;
20+
1221
/** government Entity form control. */
1322
governmentEntity = new UntypedFormControl();
1423
/** financial Institution form control. */
@@ -21,26 +30,47 @@ export class AccountMapperComponent {
2130
/** Columns to be displayed in transactions table. */
2231
displayedColumns: string[] = ['governmentEntity', 'financialInstitution', 'functionalId', 'financialAddress'];
2332
/** Data source for transactions table. */
24-
dataSource: TransactionsDataSource;
33+
dataSource = new MatTableDataSource();
2534

26-
batchesData: any;
35+
totalRows: number = 0;
36+
currentPage: number = 0;
2737

28-
page: number = 0;
29-
size: number = 100;
38+
pageSize = 50;
39+
isLoading = false;
3040

31-
constructor(private accountMapperService: AccountMapperService) { }
41+
accountsData: AccountData;
42+
43+
constructor(private dates: Dates,
44+
private accountMapperService: AccountMapperService) { }
3245

3346
ngOnInit(): void {
3447
this.getAccounts();
3548
}
3649

3750
getAccounts(): void {
38-
this.accountMapperService.getAccounts(this.page, this.size, 'requestFile', 'asc')
39-
.subscribe((batches: any) => {
40-
this.batchesData = batches;
51+
this.isLoading = true;
52+
this.accountMapperService.getAccounts(this.currentPage, this.pageSize, 'requestFile', 'asc')
53+
.subscribe((accounts: AccountData) => {
54+
this.dataSource = new MatTableDataSource(accounts.content);
55+
this.totalRows = accounts.totalElements;
56+
this.isLoading = false;
57+
}, (error: any) => {
58+
this.isLoading = false;
4159
});
4260
}
4361

62+
convertTimestampToUTCDate(timestamp: any) {
63+
if (!timestamp) {
64+
return undefined;
65+
}
66+
return this.dates.formatUTCDate(new Date(timestamp));
67+
}
68+
69+
pageChanged(event: PageEvent) {
70+
this.pageSize = event.pageSize;
71+
this.currentPage = event.pageIndex;
72+
this.getAccounts();
73+
}
4474

4575
searchAccounts(): void {
4676

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Pageable, Sort } from "app/shared/models/data.model";
2+
3+
export interface AccountData {
4+
content: Account[];
5+
pageable: Pageable;
6+
totalPages: number;
7+
totalElements: number;
8+
last: boolean;
9+
size: number;
10+
number: number;
11+
sort: Sort;
12+
numberOfElements: number;
13+
first: boolean;
14+
empty: boolean;
15+
}
16+
17+
export interface Account {
18+
registeringInstitutionId: string;
19+
payeeIdentity: string;
20+
paymentModality: string;
21+
financialAddress: string;
22+
bankingInstitutionCode: string;
23+
}
24+

src/app/account-mapper/services/account-mapper.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class AccountMapperService {
2222
.set('sortOrder', sortOrder)
2323
.set('orderBy', orderBy);
2424

25-
return this.http.get(this.apiPrefix + '/vouchers', { params: httpParams });
25+
return this.http.get(this.apiPrefix + '/beneficiaries', { params: httpParams });
2626
}
2727

2828
}

src/app/app.module.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { PaymentHubModule } from './payment-hub/paymenthub.module';
3030
/** Main Routing Module */
3131
import { AppRoutingModule } from './app-routing.module';
3232

33-
import { DatePipe, LocationStrategy } from '@angular/common';
33+
import { DatePipe } from '@angular/common';
3434
import { VouchersModule } from './vouchers/vouchers.module';
3535
import { AccountMapperModule } from './account-mapper/account-mapper.module';
3636
import { KeycloakAngularModule } from 'keycloak-angular';
@@ -49,7 +49,7 @@ import { KeycloakAngularModule } from 'keycloak-angular';
4949
loader: {
5050
provide: TranslateLoader,
5151
useFactory: httpTranslateLoader,
52-
deps: [HttpClient, LocationStrategy]
52+
deps: [HttpClient]
5353
}
5454
}),
5555
KeycloakAngularModule,
@@ -73,6 +73,6 @@ import { KeycloakAngularModule } from 'keycloak-angular';
7373
})
7474
export class AppModule { }
7575

76-
export function httpTranslateLoader(http: HttpClient, locationStrategy: LocationStrategy) {
76+
export function httpTranslateLoader(http: HttpClient) {
7777
return new TranslateHttpLoader(http, `/assets/translations/`, '.json');
7878
}

src/app/core/authentication/authentication.interceptor.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/c
44

55
/** rxjs Imports */
66
import { Observable, Subject, BehaviorSubject, throwError } from 'rxjs';
7-
import { switchMap, take, filter, catchError } from 'rxjs/operators';
8-
9-
import { AuthenticationService } from './authentication.service';
10-
import { Router } from '@angular/router';
117

128
import { environment } from '../../../environments/environment';
139
import { SettingsService } from 'app/settings/settings.service';
@@ -39,7 +35,15 @@ export class AuthenticationInterceptor implements HttpInterceptor {
3935
*/
4036
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
4137
if (this.settingsService.tenantIdentifier) {
42-
httpOptions.headers['Platform-TenantId'] = this.settingsService.tenantIdentifier;
38+
const url: string = request.url;
39+
if ((url.indexOf('/batches') > 0) || (url.indexOf('/transactions') > 0)) {
40+
httpOptions.headers['Platform-TenantId'] = this.settingsService.tenantIdentifier;
41+
delete httpOptions.headers['X-Registering-Institution-ID'];
42+
}
43+
if ((url.indexOf('/vouchers') > 0) || (url.indexOf('/benefici') > 0)) {
44+
httpOptions.headers['X-Registering-Institution-ID'] = environment.backend.registeringInstituionId;
45+
delete httpOptions.headers['Platform-TenantId'];
46+
}
4347
} else {
4448
delete httpOptions.headers['Platform-TenantId'];
4549
}

src/app/core/authentication/authentication.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export class AuthenticationService {
165165
private getUserDetails(loginContext: LoginContext,tokenResponse: OAuth2Token) {
166166
if (this.isOauthKeyCloak()) {
167167
this.oauthKeycloakService.introspect(tokenResponse).subscribe((userDetails: Introspect) => {
168-
console.log(userDetails);
168+
// console.log(userDetails);
169169
this.storage.setItem(this.oAuthUserDetailsStorageKey, JSON.stringify(userDetails));
170170
this.onLoginSuccess({ username: loginContext.username, accessToken: tokenResponse.access_token, authenticated: true, tenantId: loginContext.tenant } as any);
171171

src/app/login/login-form/login-form.component.html

+9-9
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,49 @@
44
<span matPrefix>
55
<fa-icon icon="user-circle" size="lg"></fa-icon>&nbsp;&nbsp;
66
</span>
7-
<mat-label>Tenant</mat-label>
7+
<mat-label>{{'labels.inputs.Tenant' | translate}}</mat-label>
88
<input matInput type="text" formControlName="tenant">
99
<mat-error *ngIf="loginForm.controls.tenant.hasError('required')">
10-
Tenant is <strong>required</strong>
10+
{{'labels.texts.Tenant is' | translate}} <strong>{{'labels.texts.required' | translate}}</strong>
1111
</mat-error>
1212
</mat-form-field>
1313

1414
<mat-form-field fxFlexAlign="center" class="login-input">
1515
<span matPrefix>
1616
<fa-icon icon="user-circle" size="lg"></fa-icon>&nbsp;&nbsp;
1717
</span>
18-
<mat-label>Username</mat-label>
18+
<mat-label>{{'labels.inputs.Username' | translate}}</mat-label>
1919
<input matInput type="text" autocomplete="off" formControlName="username">
2020
<mat-error *ngIf="loginForm.controls.username.hasError('required')">
21-
Username is <strong>required</strong>
21+
{{'labels.texts.Username is' | translate}} <strong>{{'labels.texts.required' | translate}}</strong>
2222
</mat-error>
2323
</mat-form-field>
2424

2525
<mat-form-field fxFlexAlign="center" class="login-input">
2626
<span matPrefix>
2727
<fa-icon icon="lock" size="lg"></fa-icon>&nbsp;&nbsp;
2828
</span>
29-
<mat-label>Password</mat-label>
29+
<mat-label>{{'labels.inputs.Password' | translate}}</mat-label>
3030
<input matInput type="{{ passwordInputType }}" formControlName="password">
3131
<button mat-button *ngIf="loginForm.controls.password.value && !loading" matSuffix mat-icon-button
3232
(mousedown)="passwordInputType = 'text'" (mouseup)="passwordInputType = 'password'">
3333
<fa-icon *ngIf="passwordInputType === 'password'" icon="eye"></fa-icon>
3434
<fa-icon *ngIf="passwordInputType === 'text'" icon="eye-slash"></fa-icon>
3535
</button>
3636
<mat-error *ngIf="loginForm.controls.password.hasError('required')">
37-
Password is <strong>required</strong>
37+
{{'labels.texts.Password is' | translate}} <strong>{{'labels.texts.required' | translate}}</strong>
3838
</mat-error>
3939
</mat-form-field>
4040

41-
<mat-checkbox fxFlexAlign="center" formControlName="remember" class="m-t-10">Remember me</mat-checkbox>
41+
<mat-checkbox fxFlexAlign="center" formControlName="remember" class="m-t-10">{{'labels.texts.Remember me' | translate}}</mat-checkbox>
4242

4343
<button mat-raised-button color="primary" fxFlexAlign="center" class="login-button" [disabled]="!loginForm.valid">
44-
Login
44+
{{'labels.buttons.Login' | translate}}
4545
<mat-spinner [diameter]="20" *ngIf="loading"></mat-spinner>
4646
</button>
4747

4848
<button type="button" mat-button fxFlexAlign="center" class="login-button" (click)="forgotPassword()" [disabled]="loading">
49-
Forgot Password?
49+
{{'labels.buttons.Forgot Password?' | translate}}
5050
</button>
5151

5252
</form>

src/app/login/login.component.html

+1-7
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,9 @@
1313
</div>
1414

1515
<div fxLayout="row" fxFlex="3 0 auto" fxLayoutAlign="center start">
16-
<p>Payment Hub EE - Operations Management</p>
16+
<p>{{ 'APP_NAME' | translate }}</p>
1717
</div>
1818

19-
<!--
20-
Type of Form:
21-
Login
22-
Reset Password
23-
Forgot Password (TODO: Decision to be taken on providing this feature.)
24-
-->
2519
<div fxLayout="row" fxFlex="3 0 auto" fxLayoutAlign="center start">
2620
<mifosx-login-form *ngIf="!resetPassword && !twoFactorAuthenticationRequired"></mifosx-login-form>
2721
<mifosx-reset-password *ngIf="resetPassword"></mifosx-reset-password>

src/app/login/login.module.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { LoginRoutingModule } from './login-routing.module';
99
import { LoginComponent } from './login.component';
1010
import { LoginFormComponent } from './login-form/login-form.component';
1111
import { ResetPasswordComponent } from './reset-password/reset-password.component';
12-
import { TranslateModule } from '@ngx-translate/core';
1312

1413
/**
1514
* Login Module
@@ -19,8 +18,7 @@ import { TranslateModule } from '@ngx-translate/core';
1918
@NgModule({
2019
imports: [
2120
SharedModule,
22-
LoginRoutingModule,
23-
TranslateModule.forRoot()
21+
LoginRoutingModule
2422
],
2523
declarations: [
2624
LoginComponent,

0 commit comments

Comments
 (0)