fix conflict
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 210 KiB |
@ -1,28 +0,0 @@
|
|||||||
<ion-header>
|
|
||||||
<ion-toolbar>
|
|
||||||
<nav-buttons [navigate]="false" (backClick)="onRejectClicked()" ></nav-buttons>
|
|
||||||
<ion-title>{{ 'general,usage-agreement' | translate}}</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
</ion-header>
|
|
||||||
|
|
||||||
<ion-content padding>
|
|
||||||
<scroll-content>
|
|
||||||
<ion-grid>
|
|
||||||
<ion-row *ngIf="agreementContent" class="ion-justify-content-center">
|
|
||||||
<ion-col [size]="11">
|
|
||||||
<div class="html-container" [innerHTML]="agreementContent | safeHtml"> </div>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
</ion-grid>
|
|
||||||
<page-trailer [small]="true"></page-trailer>
|
|
||||||
</scroll-content>
|
|
||||||
<footer>
|
|
||||||
<ion-grid>
|
|
||||||
<ion-row class="ion-justify-content-center">
|
|
||||||
<ion-col [size]="10" [sizeLg]="8" [sizeXl]="6" no-padding>
|
|
||||||
<ion-button (click)="onAcceptClicked()" expand="block">{{ 'general,accept' | translate}}</ion-button>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
</ion-grid>
|
|
||||||
</footer>
|
|
||||||
</ion-content>
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
.agreement_area{
|
|
||||||
width: 100%;
|
|
||||||
height: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.html-container {
|
|
||||||
width: 96%;
|
|
||||||
padding: 2%;
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AgreementComponent } from './agreement.component';
|
|
||||||
|
|
||||||
describe('AgreementComponent', () => {
|
|
||||||
let component: AgreementComponent;
|
|
||||||
let fixture: ComponentFixture<AgreementComponent>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ AgreementComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(AgreementComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
|
||||||
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
|
||||||
import { AgreementService } from './service/agreement.service';
|
|
||||||
import { CheckUserAgreementResponse } from './service/models/check-user-agreement.response';
|
|
||||||
import { GetUserAgreementResponse } from './service/models/get-user-agreement.response';
|
|
||||||
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-agreement',
|
|
||||||
templateUrl: './agreement.component.html',
|
|
||||||
styleUrls: ['./agreement.component.scss']
|
|
||||||
})
|
|
||||||
export class AgreementComponent implements OnInit {
|
|
||||||
|
|
||||||
public agreementContent: string;
|
|
||||||
constructor(
|
|
||||||
public ts: TranslatorService,
|
|
||||||
public cs: CommonService,
|
|
||||||
public agreementService: AgreementService,
|
|
||||||
public auth: AuthenticationService
|
|
||||||
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.checkUserAgreement();
|
|
||||||
}
|
|
||||||
|
|
||||||
checkUserAgreement() {
|
|
||||||
this.agreementService.checkUserAgreement(
|
|
||||||
() => {
|
|
||||||
this.checkUserAgreement();
|
|
||||||
}, this.ts.trPK('general', 'retry')).subscribe((result: CheckUserAgreementResponse) => {
|
|
||||||
if (this.cs.validResponse(result)) {
|
|
||||||
if (result.IsPatientAlreadyAgreed) {
|
|
||||||
// this.auth.setUserAgreed(true);
|
|
||||||
this.cs.openHome();
|
|
||||||
} else {
|
|
||||||
this.getUserAgreement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private getUserAgreement() {
|
|
||||||
this.agreementService.getAgreement(
|
|
||||||
() => {
|
|
||||||
this.getUserAgreement();
|
|
||||||
}, this.ts.trPK('general', 'retry')).subscribe((result: GetUserAgreementResponse) => {
|
|
||||||
if (this.cs.validResponse(result)) {
|
|
||||||
this.agreementContent = result.UserAgreementContent;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onAcceptClicked() {
|
|
||||||
this.agreementService.addUserAgreement(
|
|
||||||
() => {
|
|
||||||
this.onAcceptClicked();
|
|
||||||
}, this.ts.trPK('general', 'retry')).subscribe((result: GetUserAgreementResponse) => {
|
|
||||||
if (this.cs.validResponse(result)) {
|
|
||||||
//this.auth.setUserAgreed(true);
|
|
||||||
this.cs.openHome();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onRejectClicked() {
|
|
||||||
this.auth.clearUser().subscribe(success => {
|
|
||||||
this.cs.openHome();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AgreementService } from './agreement.service';
|
|
||||||
|
|
||||||
describe('AgreementService', () => {
|
|
||||||
beforeEach(() => TestBed.configureTestingModule({}));
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
const service: AgreementService = TestBed.get(AgreementService);
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { ConnectorService } from 'src/app/hmg-common/services/connector/connector.service';
|
|
||||||
import { CheckUserAgreementRequest } from './models/check-user-agreement.request';
|
|
||||||
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { CheckUserAgreementResponse } from './models/check-user-agreement.response';
|
|
||||||
import { Request } from 'src/app/hmg-common/services/models/request';
|
|
||||||
import { GetUserAgreementResponse } from './models/get-user-agreement.response';
|
|
||||||
import { AddUserAgreementRequest } from './models/add-user-agreement.request';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class AgreementService {
|
|
||||||
|
|
||||||
public static checkAgreementURL = 'Services/Patients.svc/REST/CheckForUsageAgreement';
|
|
||||||
public static getAgreementURL = 'Services/Patients.svc/REST/GetUsageAgreementText';
|
|
||||||
public static addAgreementURL = 'Services/Patients.svc/REST/AddUsageAgreement';
|
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public con: ConnectorService,
|
|
||||||
public auth: AuthenticationService
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public checkUserAgreement(onError: any, errorLabel: string): Observable<CheckUserAgreementResponse> {
|
|
||||||
const request = new CheckUserAgreementRequest();
|
|
||||||
request.Region = 1;
|
|
||||||
this.auth.authenticateRequest(request);
|
|
||||||
request.TokenID = '';
|
|
||||||
return this.con.post(AgreementService.checkAgreementURL, request, onError, errorLabel);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public getAgreement(onError: any, errorLabel: string): Observable<GetUserAgreementResponse> {
|
|
||||||
const request = new Request();
|
|
||||||
this.auth.setPublicFields(request);
|
|
||||||
request.TokenID = '';
|
|
||||||
return this.con.post(AgreementService.getAgreementURL, request, onError, errorLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addUserAgreement(onError: any, errorLabel: string): Observable<GetUserAgreementResponse> {
|
|
||||||
const request = new AddUserAgreementRequest();
|
|
||||||
request.Region = 1;
|
|
||||||
this.auth.authenticateRequest(request);
|
|
||||||
request.TokenID = '';
|
|
||||||
return this.con.post(AgreementService.addAgreementURL, request, onError, errorLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import { Request } from 'src/app/hmg-common/services/models/request';
|
|
||||||
|
|
||||||
export class AddUserAgreementRequest extends Request {
|
|
||||||
Region: number; // 1
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import { Request } from 'src/app/hmg-common/services/models/request';
|
|
||||||
|
|
||||||
export class CheckUserAgreementRequest extends Request {
|
|
||||||
Region: number; // 1
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import { Response } from 'src/app/hmg-common/services/models/response';
|
|
||||||
|
|
||||||
export class CheckUserAgreementResponse extends Response {
|
|
||||||
IsPatientAlreadyAgreed: boolean;
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import { Response } from 'src/app/hmg-common/services/models/response';
|
|
||||||
|
|
||||||
export class GetUserAgreementResponse extends Response {
|
|
||||||
UserAgreementContent: string;
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { Request } from '../../models/request';
|
|
||||||
|
|
||||||
export class CheckPatientRegisterationRequest extends Request {
|
|
||||||
PatientIdentificationID: string; // "iqama"
|
|
||||||
PatientMobileNumber: string; // "phone without start 0"
|
|
||||||
TokenID: string; // should be empty ""
|
|
||||||
ZipCode: string; // "966 or 971"
|
|
||||||
isRegister: boolean;
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { GeofencingService } from './geofencing.service';
|
|
||||||
|
|
||||||
describe('GeofencingService', () => {
|
|
||||||
beforeEach(() => TestBed.configureTestingModule({}));
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
const service: GeofencingService = TestBed.get(GeofencingService);
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,446 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { BackgroundGeolocation, BackgroundGeolocationEvents } from '@ionic-native/background-geolocation/ngx';
|
|
||||||
import { BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '@ionic-native/background-geolocation/ngx';
|
|
||||||
import { UserLocalNotificationService } from '../user-local-notification/user-local-notification.service';
|
|
||||||
import { Platform } from '@ionic/angular';
|
|
||||||
import { LocationModel } from './models/location.model';
|
|
||||||
import { ConnectorService } from '../connector/connector.service';
|
|
||||||
import { NativeStorage } from '@ionic-native/native-storage/ngx';
|
|
||||||
import { AuthenticationService } from '../authentication/authentication.service';
|
|
||||||
import { ZoneModel } from './models/zone.model';
|
|
||||||
import { CommonService } from '../common/common.service';
|
|
||||||
import { InsertLocationRequest } from './models/insert-location.request';
|
|
||||||
import { GeoUserModel } from './models/geo-user.model';
|
|
||||||
import { TranslatorService } from '../translator/translator.service';
|
|
||||||
|
|
||||||
export enum zoneState {
|
|
||||||
out = 0, enter = 1, exit = 2, in = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class GeofencingService {
|
|
||||||
public static ZONES_KEY = 'geofencing-zones';
|
|
||||||
public static USER_DATA_KEY = 'geofencing-user-data';
|
|
||||||
public static GEO_STATUS_KEY = 'geofencing-status';
|
|
||||||
public static zonesUrl = 'Services/Patients.svc/REST/GeoF_GetAllPoints';
|
|
||||||
public static loggingUrl = 'Services/Patients.svc/rest/GeoF_InsertPatientFileInfo';
|
|
||||||
private zonesList: ZoneModel [];
|
|
||||||
private userData: GeoUserModel;
|
|
||||||
private isPaused: boolean;
|
|
||||||
private debug: boolean;
|
|
||||||
|
|
||||||
locations: any [];
|
|
||||||
constructor(
|
|
||||||
private backgroundGeolocation: BackgroundGeolocation,
|
|
||||||
public notif: UserLocalNotificationService,
|
|
||||||
public platform: Platform,
|
|
||||||
public con: ConnectorService,
|
|
||||||
public auth: AuthenticationService,
|
|
||||||
public storage: NativeStorage,
|
|
||||||
public cs: CommonService,
|
|
||||||
public authService: AuthenticationService,
|
|
||||||
public ts: TranslatorService,
|
|
||||||
) {
|
|
||||||
this.debug = false;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* logs location on server.
|
|
||||||
*/
|
|
||||||
private logLocation(id: number, type: number, userData: GeoUserModel, zone: ZoneModel) {
|
|
||||||
this.toast('logging location..');
|
|
||||||
this.setNotification('Logging location ' , 'location id: ' + id + ' type: ' + type);
|
|
||||||
const req = new InsertLocationRequest();
|
|
||||||
req.PointsID = id;
|
|
||||||
req.GeoType = type;
|
|
||||||
//req.PatientID = userData.PatientID;
|
|
||||||
//req.PatientOutSA = userData.PatientOutSA;
|
|
||||||
this.auth.setPublicFields(req);
|
|
||||||
this.con.postNoLoad(GeofencingService.loggingUrl, req, () => {
|
|
||||||
zone.pendingRequest = type; // failed to log, setup pending request
|
|
||||||
this.storeZones(this.zonesList);
|
|
||||||
this.log('pending request from onError');
|
|
||||||
this.setNotification('Pending request from onError', 'zone: ' + zone.Description + ' request type: ' + type);
|
|
||||||
}).subscribe((response) => {
|
|
||||||
if (this.cs.validResponse(response)) {
|
|
||||||
this.setNotification('Log success' , 'location id: ' + id + ' patientID: ' + userData.PatientID);
|
|
||||||
this.log('logged successfuly');
|
|
||||||
zone.pendingRequest = zoneState.out; // cancel pending requests if any
|
|
||||||
} else {
|
|
||||||
zone.pendingRequest = type; // failed to log, setup pending request
|
|
||||||
this.log('pending request from invalid');
|
|
||||||
this.setNotification('Pending request from invalid', 'zone: ' + zone.Description + ' request type: ' + type);
|
|
||||||
}
|
|
||||||
this.storeZones(this.zonesList);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Requests geofence zones list
|
|
||||||
*/
|
|
||||||
private requestZones() {
|
|
||||||
const req = this.auth.getPublicRequest();
|
|
||||||
this.con.postNoLoad(GeofencingService.zonesUrl, req, _ => { // TODO: handle error
|
|
||||||
}).subscribe((response: any) => {
|
|
||||||
if (this.cs.validResponse(response)) {
|
|
||||||
if (this.cs.hasData(response.GeoF_PointsList)) {
|
|
||||||
// update zonelist if it doesnt exist or if the server has an updated one
|
|
||||||
if (!this.cs.hasData(this.zonesList) || (this.zonesList.length !== response.GeoF_PointsList.length)) {
|
|
||||||
this.log('setting new zone list');
|
|
||||||
this.zonesList = response.GeoF_PointsList;
|
|
||||||
for (const zone of this.zonesList) {
|
|
||||||
zone.in = false;
|
|
||||||
}
|
|
||||||
this.log('storing zones');
|
|
||||||
this.storeZones(this.zonesList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Store zones list in local storage
|
|
||||||
*/
|
|
||||||
public async storeZones(zones: ZoneModel []) {
|
|
||||||
return await this.storage.setItem(GeofencingService.ZONES_KEY, zones);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Retrieve and set list of zones from local storage
|
|
||||||
*/
|
|
||||||
public async setZones() {
|
|
||||||
try {
|
|
||||||
const data = await this.storage.getItem(GeofencingService.ZONES_KEY);
|
|
||||||
if (this.cs.hasData(data)) {
|
|
||||||
this.zonesList = data;
|
|
||||||
} else {
|
|
||||||
this.requestZones(); // zones list not stored in local storage
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
this.requestZones(); // zones list not stored in local storage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async storeUserData(user: GeoUserModel) {
|
|
||||||
return await this.storage.setItem(GeofencingService.USER_DATA_KEY, user);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Retrieve and set user data from local storage
|
|
||||||
*/
|
|
||||||
public async setUserFromStorage() {
|
|
||||||
const data = await this.storage.getItem(GeofencingService.USER_DATA_KEY);
|
|
||||||
if (data) {
|
|
||||||
this.userData = data;
|
|
||||||
} else {
|
|
||||||
this.userData = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// turns location tracking on. Sets geo user data and zones list
|
|
||||||
*/
|
|
||||||
public async turnTrackingOn(patientID?: number, outSa?: number): Promise<boolean> {
|
|
||||||
this.toast('turning tracking on');
|
|
||||||
// set zones list from storage
|
|
||||||
await this.setZones();
|
|
||||||
// update zone list from server
|
|
||||||
this.requestZones();
|
|
||||||
|
|
||||||
// Set user data
|
|
||||||
if (patientID) {
|
|
||||||
this.userData = new GeoUserModel;
|
|
||||||
this.userData.PatientID = patientID;
|
|
||||||
this.userData.PatientOutSA = outSa;
|
|
||||||
} else if (!this.userData) {
|
|
||||||
try {
|
|
||||||
await this.setUserFromStorage();
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.userData.isTrackingOn = true;
|
|
||||||
this.storeUserData(this.userData);
|
|
||||||
this.startTracking();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// turns location tracking off. Stops background tracking
|
|
||||||
*/
|
|
||||||
public turnTrackingOff() {
|
|
||||||
this.toast('turning tracking off');
|
|
||||||
this.stopTracking();
|
|
||||||
if (this.userData) {
|
|
||||||
this.userData.isTrackingOn = false;
|
|
||||||
this.storeUserData(this.userData);
|
|
||||||
} else {
|
|
||||||
this.setUserFromStorage().then(() => {
|
|
||||||
this.userData.isTrackingOn = false;
|
|
||||||
this.storeUserData(this.userData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Check if geofencing service is enabled
|
|
||||||
*/
|
|
||||||
public async isTrackingEnabled(): Promise<boolean> {
|
|
||||||
// if (this.userData) {
|
|
||||||
// return this.userData.isTrackingOn;
|
|
||||||
// } else {
|
|
||||||
try {
|
|
||||||
await this.setUserFromStorage();
|
|
||||||
if (this.userData) {
|
|
||||||
return this.userData.isTrackingOn;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
throw false;
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// setup and start background gelocation plugin
|
|
||||||
*/
|
|
||||||
public startTracking() {
|
|
||||||
const config: BackgroundGeolocationConfig = {
|
|
||||||
desiredAccuracy: 10000, // HIGH_ACCURACY = 1 // low = 10000
|
|
||||||
stationaryRadius: 20, // 20
|
|
||||||
distanceFilter: 10, // 10
|
|
||||||
debug: false, // enable this hear sounds for background-geolocation life-cycle.
|
|
||||||
stopOnTerminate: false, // enable this to clear background location settings when the app terminates
|
|
||||||
// startOnBoot: true,
|
|
||||||
// Android options
|
|
||||||
notificationsEnabled: false,
|
|
||||||
interval: 60000, // interval vars for improved battery life
|
|
||||||
fastestInterval: 120000,
|
|
||||||
activitiesInterval: 10000,
|
|
||||||
startForeground: false,
|
|
||||||
notificationTitle: 'Running in the background',
|
|
||||||
notificationText: '',
|
|
||||||
// IOS options
|
|
||||||
saveBatteryOnBackground: false
|
|
||||||
};
|
|
||||||
this.backgroundGeolocation.configure(config)
|
|
||||||
.then((location: BackgroundGeolocationResponse) => {
|
|
||||||
});
|
|
||||||
|
|
||||||
this.backgroundGeolocation.on(BackgroundGeolocationEvents.location)
|
|
||||||
.subscribe((location: BackgroundGeolocationResponse) => {
|
|
||||||
this.reportLocation(location);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.backgroundGeolocation.on(BackgroundGeolocationEvents.stationary)
|
|
||||||
.subscribe((location: BackgroundGeolocationResponse) => {
|
|
||||||
this.reportLocation(location);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.storage.getItem(GeofencingService.GEO_STATUS_KEY).then(status => {
|
|
||||||
if (!status) {
|
|
||||||
this.backgroundGeolocation.start();
|
|
||||||
this.storage.setItem(GeofencingService.GEO_STATUS_KEY, true);
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
this.toast('turning geofencing on');
|
|
||||||
this.backgroundGeolocation.start();
|
|
||||||
this.storage.setItem(GeofencingService.GEO_STATUS_KEY, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Helper to startTracking()
|
|
||||||
*/
|
|
||||||
private async reportLocation(location: BackgroundGeolocationResponse) {
|
|
||||||
// Check if zones and user is set
|
|
||||||
if (!this.userData) {
|
|
||||||
await this.setUserFromStorage();
|
|
||||||
}
|
|
||||||
if (!this.cs.hasData(this.zonesList)) {
|
|
||||||
await this.setZones();
|
|
||||||
}
|
|
||||||
if (this.platform.is('ios')) {
|
|
||||||
this.backgroundGeolocation.startTask().then((taskKey) => {
|
|
||||||
this.checklocationInZones(location, this.zonesList, this.userData);
|
|
||||||
this.backgroundGeolocation.endTask(taskKey);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.checklocationInZones(location, this.zonesList, this.userData);
|
|
||||||
}
|
|
||||||
this.storeZones(this.zonesList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// stops background geoloacation plugin tracking
|
|
||||||
*/
|
|
||||||
public stopTracking() {
|
|
||||||
this.toast('Stop Tracking' );
|
|
||||||
this.storage.setItem(GeofencingService.GEO_STATUS_KEY, false);
|
|
||||||
this.backgroundGeolocation.stop().then(value => {
|
|
||||||
// this.toast('Stop Tracking value returned: ' + value);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Checks if given location triggers any zone events (enter, exit) for all zones, and pauses the service if
|
|
||||||
// the location was far from all zones
|
|
||||||
*/
|
|
||||||
private checklocationInZones(location: BackgroundGeolocationResponse, zones: ZoneModel [], user: GeoUserModel) {
|
|
||||||
this.printLocation(location, 'check location in zones');
|
|
||||||
let currentMinDist = 9999999;
|
|
||||||
for (const zone of zones) {
|
|
||||||
const userLocation = new LocationModel(location.latitude, location.longitude);
|
|
||||||
const event = this.checkLocationInZone(userLocation, zone);
|
|
||||||
const currentDistance = this.distanceFromZone(userLocation, zone);
|
|
||||||
currentMinDist = (currentMinDist > currentDistance ? currentDistance : currentMinDist);
|
|
||||||
if (zone.GEOF_ID === 16) {
|
|
||||||
this.log(zone.Description);
|
|
||||||
this.log('zone state: ' + zone.in + ' pending: ' + zone.pendingRequest + 'current event: ' + event);
|
|
||||||
}
|
|
||||||
if (event === zoneState.in) {
|
|
||||||
zone.in = true;
|
|
||||||
}
|
|
||||||
// send enter request
|
|
||||||
if (event === zoneState.enter ||
|
|
||||||
(event === zoneState.in && zone.pendingRequest === zoneState.enter)) {
|
|
||||||
zone.in = true;
|
|
||||||
this.setNotification('Enter ZONE ' + zone.Description, 'location lat: ' + location.latitude + ' lng: ' + location.longitude);
|
|
||||||
this.log('enter Zone' + zone.Description + ' ' + 'location: ' + location.latitude + ',' + location.longitude);
|
|
||||||
this.logLocation(zone.GEOF_ID, zoneState.enter, user, zone);
|
|
||||||
}
|
|
||||||
// send exit request
|
|
||||||
if (event === zoneState.exit ||
|
|
||||||
(event === zoneState.out && zone.pendingRequest === zoneState.exit)) {
|
|
||||||
zone.in = false;
|
|
||||||
this.setNotification('Exit ZONE ' + zone.Description, 'location lat: ' + location.latitude + ' lng: ' + location.longitude);
|
|
||||||
this.log('exit Zone' + zone.Description + ' ' + 'location: ' + location.latitude + ',' + location.longitude);
|
|
||||||
this.logLocation(zone.GEOF_ID, zoneState.exit, user, zone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const minDist = this.toDecimalDegrees(5000); // minimum distance location needs to be to all zones to pause service
|
|
||||||
const maxDist = this.toDecimalDegrees(10000); // Max distance used to have a factor between 0-1
|
|
||||||
if (currentMinDist >= minDist) {
|
|
||||||
const currentDis = (currentMinDist > maxDist ? maxDist : currentMinDist);
|
|
||||||
this.pauseService((currentDis - minDist) / (maxDist - minDist));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Checks the state of given location for the given zone
|
|
||||||
*/
|
|
||||||
private checkLocationInZone(userLocation: LocationModel, zone: ZoneModel): zoneState {
|
|
||||||
const isIn = this.isPointInZone(userLocation.lng, userLocation.lat, zone.Longitude,
|
|
||||||
zone.Latitude, this.toDecimalDegrees(zone.Radius));
|
|
||||||
if (isIn === false && zone.in === true) {
|
|
||||||
return zoneState.exit;
|
|
||||||
}
|
|
||||||
if (isIn === true && zone.in === false) {
|
|
||||||
return zoneState.enter;
|
|
||||||
}
|
|
||||||
if (isIn) {
|
|
||||||
return zoneState.in;
|
|
||||||
}
|
|
||||||
return zoneState.out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// calculates the distance between given location and given zone
|
|
||||||
*/
|
|
||||||
private distanceFromZone(userLocation: LocationModel, zone: ZoneModel): number {
|
|
||||||
return this.distance(userLocation.lng, userLocation.lat, zone.Longitude, zone.Latitude);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// checks if a point p is in a circular zone with center z and radius r
|
|
||||||
*/
|
|
||||||
public isPointInZone(xp, yp, xz, yz, r): boolean {
|
|
||||||
return this.distance(xp, yp, xz, yz) < r;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Measures distance between two points
|
|
||||||
*/
|
|
||||||
public distance(xp, yp, xz, yz): number {
|
|
||||||
return Math.sqrt(Math.pow(Math.abs(xp - xz), 2) + Math.pow(Math.abs(yp - yz) , 2));
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Convert meters to decimal degrees
|
|
||||||
*/
|
|
||||||
public toDecimalDegrees(meters: number) {
|
|
||||||
return meters / 1000 / 111.32;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Pauses tracking service for a time multiplied by given factor
|
|
||||||
*/
|
|
||||||
public pauseService(factor: number) {
|
|
||||||
if (!this.isPaused) {
|
|
||||||
this.stopTracking();
|
|
||||||
this.isPaused = true;
|
|
||||||
// time to pause min=120 sec max=1800 sec
|
|
||||||
const time = (1680000 * factor); // time in milliseconds
|
|
||||||
this.setNotification('pausing tracking service', 'Pause for ' + time + ' FYI factor is: ' + factor);
|
|
||||||
setTimeout(() => {
|
|
||||||
this.startTracking();
|
|
||||||
this.isPaused = false;
|
|
||||||
this.setNotification('resuming tracking service', 'Paused for ' + time + ' FYI factor is: ' + factor);
|
|
||||||
}, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public startGeoFromHome() {
|
|
||||||
if (this.cs.isCordova()) {
|
|
||||||
this.isTrackingEnabled().then((result) => {
|
|
||||||
if (result) {
|
|
||||||
this.turnTrackingOff();
|
|
||||||
this.turnTrackingOn();
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
// first time login, setup geofencing
|
|
||||||
// local storage should reset when user logs out
|
|
||||||
if (this.authService.isAuthenticated()) {
|
|
||||||
const user = this.authService.getAuthenticatedUser();
|
|
||||||
this.turnTrackingOff();
|
|
||||||
this.cs.presentConfirmDialog(this.ts.trPK('settings', 'enable-geo'), () => {
|
|
||||||
// this.turnTrackingOn(user.PatientID, +user.PatientOutSA);
|
|
||||||
}, () => {
|
|
||||||
// this.turnTrackingOn(user.PatientID, +user.PatientOutSA);
|
|
||||||
this.turnTrackingOff();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- TESTING FUNCTIONS -------------- //
|
|
||||||
public setNotification(title: string, text: string) {
|
|
||||||
if (this.debug) {
|
|
||||||
const date = new Date();
|
|
||||||
date.setSeconds(date.getSeconds() + 2);
|
|
||||||
this.notif.createNotification(title, text, date, 'geofencing');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public printLocation(location: BackgroundGeolocationResponse, source: string) {
|
|
||||||
if (this.debug) {
|
|
||||||
console.log('-------------------------------------------------------------');
|
|
||||||
console.log(source);
|
|
||||||
console.log(this.zonesList);
|
|
||||||
console.log(location);
|
|
||||||
console.log('location: ' + location.latitude + ', ' + location.longitude);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public printAllLocations() {
|
|
||||||
if (this.debug) {
|
|
||||||
this.backgroundGeolocation.getLocations().then(locations => {
|
|
||||||
console.log(locations);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public log(msg: string) {
|
|
||||||
if (this.debug) {
|
|
||||||
console.log(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public toast(msg: string) {
|
|
||||||
if (this.debug) {
|
|
||||||
this.cs.toast(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
export class GeoUserModel {
|
|
||||||
PatientID: number;
|
|
||||||
PatientOutSA: number;
|
|
||||||
isTrackingOn: boolean;
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { Request } from 'src/app/hmg-common/services/models/request';
|
|
||||||
|
|
||||||
export class InsertLocationRequest extends Request {
|
|
||||||
PointsID: number;
|
|
||||||
GeoType: number; // 1 enter 2 exit
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
export class LocationModel {
|
|
||||||
lat: number;
|
|
||||||
lng: number;
|
|
||||||
constructor(lat: number, lng: number, radius?: number, name?: string) {
|
|
||||||
this.lat = lat;
|
|
||||||
this.lng = lng;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import { zoneState } from '../geofencing.service';
|
|
||||||
|
|
||||||
export class ZoneModel {
|
|
||||||
CreatedBy?: number;
|
|
||||||
CreatedOn?: string;
|
|
||||||
Description: string;
|
|
||||||
DescriptionN?: string;
|
|
||||||
GEOF_ID?: number;
|
|
||||||
IsCity?: boolean;
|
|
||||||
Latitude: string;
|
|
||||||
Longitude: string;
|
|
||||||
ProjectID?: number;
|
|
||||||
Radius: number;
|
|
||||||
Type?: number;
|
|
||||||
in: boolean;
|
|
||||||
pendingRequest: zoneState;
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { UserLocalNotificationService } from './user-local-notification.service';
|
|
||||||
|
|
||||||
describe('UserLocalNotificationService', () => {
|
|
||||||
beforeEach(() => TestBed.configureTestingModule({}));
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
const service: UserLocalNotificationService = TestBed.get(UserLocalNotificationService);
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications/ngx';
|
|
||||||
|
|
||||||
export interface UserLocalData {
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
|
|
||||||
export class UserLocalNotificationService {
|
|
||||||
|
|
||||||
public static STORAGE_KEY = 'notifications';
|
|
||||||
constructor(
|
|
||||||
public localNotification: LocalNotifications,
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public async requestNotificationPermission(): Promise<boolean> {
|
|
||||||
const hasPermission = await this.checkNotificationPermission();
|
|
||||||
if (!hasPermission) {
|
|
||||||
return await this.localNotification.requestPermission();
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async checkNotificationPermission(): Promise<boolean> {
|
|
||||||
return await this.localNotification.hasPermission();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async cancelCategoryNotifications(category: string) {
|
|
||||||
const notifications = await this.localNotification.getAll();
|
|
||||||
for (const notification of notifications) {
|
|
||||||
const parsedData = JSON.parse(notification.data);
|
|
||||||
const notifCategory = parsedData['category'];
|
|
||||||
if (notifCategory === category) {
|
|
||||||
await this.localNotification.cancel(notification.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async isCategoryExist(category: string) {
|
|
||||||
const notifications = await this.localNotification.getAll();
|
|
||||||
for (const notification of notifications) {
|
|
||||||
const parsedData = JSON.parse(notification.data);
|
|
||||||
const notifCategory = parsedData['category'];
|
|
||||||
// alert( 'notifCategory:' + notifCategory + ' category:' + category);
|
|
||||||
if (notifCategory === category) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public createNotification(title: string, text: string, date: Date,
|
|
||||||
category: string) {
|
|
||||||
const notifID = this.generateNotificationID();
|
|
||||||
this.scheduleNotification(notifID, title, text, date, category);
|
|
||||||
}
|
|
||||||
|
|
||||||
private scheduleNotification(notifId: number, title: string, text: string,
|
|
||||||
date: Date, category: string) {
|
|
||||||
this.localNotification.on('click').subscribe(notification => {
|
|
||||||
this.localNotification.clear(notification.id);
|
|
||||||
});
|
|
||||||
this.localNotification.schedule({
|
|
||||||
id: notifId,
|
|
||||||
title: title,
|
|
||||||
text: text,
|
|
||||||
trigger: {at: date},
|
|
||||||
data : {'category': category},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteAllNotifications() {
|
|
||||||
this.localNotification.clearAll();
|
|
||||||
this.localNotification.cancelAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public cancelNotification(notifID: number) {
|
|
||||||
this.localNotification.cancel(notifID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public clearTriggeredNotifications() {
|
|
||||||
this.localNotification.clearAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private generateNotificationID(): number {
|
|
||||||
return Date.now() + Math.floor(Math.random() * (1000 - 1) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getNotifications(): Promise<ILocalNotification[]> {
|
|
||||||
const notifs = await this.localNotification.getAll();
|
|
||||||
return notifs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
<ion-grid class="zoomIn">
|
|
||||||
<ion-row>
|
|
||||||
<!-- button with text under-->
|
|
||||||
<ion-col text-center *ngFor="let method of methods" [size]="6">
|
|
||||||
<ion-grid>
|
|
||||||
<ion-row text-center (click)="openPayment(method.method)">
|
|
||||||
<ion-col center [size]="12">
|
|
||||||
<img class="button-anim rubberBand" [src]=" 'assets/icon/payment/' + method.icon + '.png'">
|
|
||||||
</ion-col>
|
|
||||||
<ion-col center [size]="12">
|
|
||||||
<ion-text color="primary">{{ method.title | translate }}</ion-text>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
<ion-row>
|
|
||||||
<ion-col [size]="12" class="slideInUp">
|
|
||||||
<divider></divider>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
</ion-grid>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
<ion-row>
|
|
||||||
<div style="height: 1cm;"></div>
|
|
||||||
</ion-row>
|
|
||||||
<ion-row class="ion-justify-content-center">
|
|
||||||
<ion-col [size]="10" [sizeLg]="8" [sizeXl]="6" no-padding>
|
|
||||||
<ion-button (click)="onCancel()" expand="block">
|
|
||||||
{{'general,cancel' | translate}}
|
|
||||||
</ion-button>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
|
|
||||||
</ion-grid>
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PaymentPage } from './payment.page';
|
|
||||||
|
|
||||||
describe('PaymentPage', () => {
|
|
||||||
let component: PaymentPage;
|
|
||||||
let fixture: ComponentFixture<PaymentPage>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ PaymentPage ],
|
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PaymentPage);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
|
||||||
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
|
||||||
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
|
||||||
import { SharedDataService } from 'src/app/hmg-common/services/shared-data-service/shared-data.service';
|
|
||||||
import { PaymentService } from './service/payment.service';
|
|
||||||
import { PayRequestInfo } from './service/models/pay-request.info';
|
|
||||||
import { PaymentInfoModel } from './service/models/payment-info.model';
|
|
||||||
import { PaymentValidationResponse } from './service/models/payment-validation.response';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'payment',
|
|
||||||
templateUrl: './payment.component.html',
|
|
||||||
styleUrls: ['./payment.component.scss'],
|
|
||||||
})
|
|
||||||
export class PaymentComponent implements OnInit {
|
|
||||||
|
|
||||||
|
|
||||||
public methods = [
|
|
||||||
{
|
|
||||||
icon: 'visa',
|
|
||||||
title: 'payment,visa',
|
|
||||||
method: PaymentService.VISA
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'sadad',
|
|
||||||
title: 'payment,sadad',
|
|
||||||
method: PaymentService.SADAD
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'mada',
|
|
||||||
title: 'payment,mada',
|
|
||||||
method: PaymentService.MADA
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'mastercard',
|
|
||||||
title: 'payment,mastercard',
|
|
||||||
method: PaymentService.MASTERCARD
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'instalment',
|
|
||||||
title: 'payment,instalment',
|
|
||||||
method: PaymentService.INSTALMENT
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
@Output() success = new EventEmitter();
|
|
||||||
@Output() faild = new EventEmitter();
|
|
||||||
@Output() cancel = new EventEmitter();
|
|
||||||
public orderDescription: string;
|
|
||||||
public amount: number;
|
|
||||||
private requestInfo: PayRequestInfo;
|
|
||||||
constructor(
|
|
||||||
public ts: TranslatorService,
|
|
||||||
public cs: CommonService,
|
|
||||||
public paymentService: PaymentService,
|
|
||||||
public sharedData: SharedDataService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input() set payRequestInfo(payRequestInfo: PayRequestInfo) {
|
|
||||||
this.requestInfo = payRequestInfo;
|
|
||||||
this.amount = payRequestInfo.amount;
|
|
||||||
this.orderDescription = payRequestInfo.orderDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
get payRequestInfo(): PayRequestInfo {
|
|
||||||
return this.requestInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public openPayment(method: string) {
|
|
||||||
/*this.paymentService.openPayment(this.amount, method, this.orderDescription).subscribe((success) => {
|
|
||||||
if (success) {
|
|
||||||
this.success.emit(this.requestInfo.data);
|
|
||||||
} else {
|
|
||||||
this.faild.emit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public onComplete(info: PaymentInfoModel) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public onCancel() {
|
|
||||||
this.cancel.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
export class PayRequestInfo {
|
|
||||||
public static SHARED_DATA = 'pay-request-info-shared';
|
|
||||||
amount: number;
|
|
||||||
orderDescription: string;
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
export class PaymentInfoModel {
|
|
||||||
transactionId: string;
|
|
||||||
amount: number;
|
|
||||||
|
|
||||||
constructor(amount: number, transactionId: string){
|
|
||||||
this.transactionId = transactionId;
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { Request } from 'src/app/hmg-common/services/models/request';
|
|
||||||
|
|
||||||
export class PaymentValidationRequest extends Request {
|
|
||||||
MerchantModuleSessionID: string;
|
|
||||||
PayOneProject: number ; // 0
|
|
||||||
PayOneService: number; // 4
|
|
||||||
LanguageID: number;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Response } from 'src/app/hmg-common/services/models/response';
|
|
||||||
|
|
||||||
export class PaymentValidationResponse extends Response {
|
|
||||||
public static SHARED_DATA = 'payment_validation_shared';
|
|
||||||
Amount: number;
|
|
||||||
Merchant_Reference: string;
|
|
||||||
Response_Message: string;
|
|
||||||
}
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { PaymentInfoModel } from './models/payment-info.model';
|
|
||||||
import { PaymentValidationRequest } from './models/payment-validation.request';
|
|
||||||
import { PaymentValidationResponse } from './models/payment-validation.response';
|
|
||||||
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
|
||||||
import { ConnectorService } from 'src/app/hmg-common/services/connector/connector.service';
|
|
||||||
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
|
||||||
import { GuidService } from 'src/app/hmg-common/services/guid/guid.service';
|
|
||||||
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class PaymentService {
|
|
||||||
|
|
||||||
public static MADA = 'MADA';
|
|
||||||
public static MASTERCARD = 'MASTERCARD';
|
|
||||||
public static SADAD = 'SADAD ';
|
|
||||||
public static VISA = 'VISA';
|
|
||||||
public static INSTALMENT = 'INSTALMENT';
|
|
||||||
public static validateURL = 'Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID';
|
|
||||||
private static SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public cs: CommonService,
|
|
||||||
public ts: TranslatorService,
|
|
||||||
public con: ConnectorService,
|
|
||||||
public authService: AuthenticationService,
|
|
||||||
public guid: GuidService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
|
|
||||||
public validatePayment(transactionID: string, onError: any, errorLabel: string): Observable<PaymentValidationResponse> {
|
|
||||||
const request = new PaymentValidationRequest();
|
|
||||||
request.ClientRequestID = transactionID;
|
|
||||||
// this.authService.authenticateRequest(request);
|
|
||||||
return this.con.post(PaymentService.validateURL, request, onError, errorLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public openPayment(amount: number, method: string, orderDesc: string, ): Observable<boolean> {
|
|
||||||
return Observable.create(observer => {
|
|
||||||
const transactionID = this.guid.generate();
|
|
||||||
this.cs.openBrowser( this.generateURL( amount, method, orderDesc, transactionID) ,
|
|
||||||
() => this.notifyCallerDone(observer, true) ,
|
|
||||||
() => this.notifyCallerDone(observer, false) );
|
|
||||||
// this.hmgBrowser.registerBack(() => this.notifyCaller(observer, amount, transactionID));
|
|
||||||
// this.hmgBrowser.registerClose(() => this.notifyCaller(observer, amount, transactionID));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private notifyCaller(observer: any, amount: number, transactionID: string) {
|
|
||||||
observer.next(new PaymentInfoModel(amount, transactionID)) ;
|
|
||||||
observer.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private notifyCallerDone(observer: any,done: boolean) {
|
|
||||||
observer.next( done) ;
|
|
||||||
observer.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private generateURL( amount: number, method: string, orderDesc: string, transactionID: string): string {
|
|
||||||
let form = this.getForm();
|
|
||||||
const user = this.authService.getAuthenticatedUser();
|
|
||||||
if (user) {
|
|
||||||
form = form.replace('EMAIL_VALUE', user.Email || user.EmailAddress);
|
|
||||||
}
|
|
||||||
form = form.replace('AMOUNT_VALUE', (amount || 0 ).toString());
|
|
||||||
form = form.replace('METHOD_VALUE', method);
|
|
||||||
form = form.replace('ORDER_DESCRIPTION_VALUE', orderDesc);
|
|
||||||
form = form.replace('ORDER_ID_VALUE', transactionID);
|
|
||||||
form = form.replace('SERVICE_URL_VALUE', PaymentService.SERVICE_URL);
|
|
||||||
console.log(form);
|
|
||||||
const base64URL = 'data:text/html;base64,' + btoa(form);
|
|
||||||
console.log(base64URL);
|
|
||||||
return base64URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getForm(): string {
|
|
||||||
return '<html> ' +
|
|
||||||
'<head></head>' +
|
|
||||||
'<body>' +
|
|
||||||
'<form id="paymentForm" action="SERVICE_URL_VALUE" method="post">' +
|
|
||||||
'<input type="hidden" name="Amount" value="AMOUNT_VALUE">' +
|
|
||||||
'<input type="hidden" name="ServID" value="2">' +
|
|
||||||
'<input type="hidden" name="Email" value="EMAIL_VALUE">' +
|
|
||||||
'<input type="hidden" name="PaymentOption" value="METHOD_VALUE">' +
|
|
||||||
'<input type="hidden" name="Order_Desc" value="ORDER_DESCRIPTION_VALUE">' +
|
|
||||||
'<input type="hidden" name="OrderID" value="ORDER_ID_VALUE">' +
|
|
||||||
'<input type="hidden" name="ChannelID" value="3">' +
|
|
||||||
'<input type="hidden" name="ProjID" value="0">' +
|
|
||||||
'<input type="hidden" name="Lang" value="en" >' +
|
|
||||||
'<input type="hidden" name="ReturnURL" value="' + TranslatorService.getCurrentLanguageName() + '" >' +
|
|
||||||
'</form>' +
|
|
||||||
'<script type="text/javascript"> document.getElementById("paymentForm").submit(); </script>' +
|
|
||||||
'</body>' +
|
|
||||||
'</html>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PaymentService } from './payment.service';
|
|
||||||
|
|
||||||
describe('PaymentService', () => {
|
|
||||||
beforeEach(() => TestBed.configureTestingModule({}));
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
const service: PaymentService = TestBed.get(PaymentService);
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { PaymentInfoModel } from './models/payment-info.model';
|
|
||||||
import { PaymentValidationRequest } from './models/payment-validation.request';
|
|
||||||
import { PaymentValidationResponse } from './models/payment-validation.response';
|
|
||||||
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
|
||||||
import { ConnectorService } from 'src/app/hmg-common/services/connector/connector.service';
|
|
||||||
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
|
||||||
import { GuidService } from 'src/app/hmg-common/services/guid/guid.service';
|
|
||||||
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
|
||||||
|
|
||||||
import { Response } from 'src/app/hmg-common/services/models/response';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class PaymentService {
|
|
||||||
|
|
||||||
public static MADA = 'MADA';
|
|
||||||
public static MASTERCARD = 'MASTERCARD';
|
|
||||||
public static SADAD = 'SADAD ';
|
|
||||||
public static VISA = 'VISA';
|
|
||||||
public static INSTALMENT = 'INSTALMENT';
|
|
||||||
private static SERVICE_URL = 'https://hmgwebservices.com/PayOneDev/Pay_Request.aspx';
|
|
||||||
public static paymentStatusURL = 'Services/PayOne.svc/REST/PayOneGetRequestsByProjectServiceAndItem';
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public cs: CommonService,
|
|
||||||
public ts: TranslatorService,
|
|
||||||
public con: ConnectorService,
|
|
||||||
public authService: AuthenticationService,
|
|
||||||
public guid: GuidService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public getPaymentLanguageID(): number {
|
|
||||||
return TranslatorService.getCurrentLanguageName() == 'en' ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPaymentStatus(transactionID: string, onError: any, errorLabel: string):
|
|
||||||
Observable<Response> {
|
|
||||||
const request = new PaymentValidationRequest();
|
|
||||||
request.MerchantModuleSessionID = transactionID;
|
|
||||||
request.PayOneProject = 0;
|
|
||||||
request.PayOneService = 4;
|
|
||||||
request.LanguageID = this.getPaymentLanguageID();
|
|
||||||
this.authService.authenticateRequest(request);
|
|
||||||
return this.con.postNoLoad(PaymentService.paymentStatusURL, request, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
public openPayment(amount: number, transactionID: string, orderDesc: string): Observable<boolean> {
|
|
||||||
return Observable.create(observer => {
|
|
||||||
// const transactionID = this.guid.generate();
|
|
||||||
this.cs.openBrowser(this.generateURL(amount, orderDesc, transactionID),
|
|
||||||
() => this.notifyCallerDone(observer, true),
|
|
||||||
() => this.notifyCallerDone(observer, false),
|
|
||||||
() => this.notifyCallerDone(observer, true),
|
|
||||||
['success' ]);
|
|
||||||
// this.hmgBrowser.registerBack(() => this.notifyCaller(observer, amount, transactionID));
|
|
||||||
// this.hmgBrowser.registerClose(() => this.notifyCaller(observer, amount, transactionID));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private notifyCaller(observer: any, amount: number, transactionID: string) {
|
|
||||||
observer.next(new PaymentInfoModel(amount, transactionID));
|
|
||||||
observer.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private notifyCallerDone(observer: any, done: boolean) {
|
|
||||||
observer.next(done);
|
|
||||||
observer.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private generateURL(amount: number, orderDesc: string, transactionID: string): string {
|
|
||||||
let form = this.getForm();
|
|
||||||
const user = this.authService.getAuthenticatedUser();
|
|
||||||
// if (user) {
|
|
||||||
// form = form.replace('EMAIL_VALUE', user.Email || user.EmailAddress);
|
|
||||||
// }
|
|
||||||
form = form.replace('AMOUNT_VALUE', (amount || 0).toString());
|
|
||||||
form = form.replace('ORDER_DESCRIPTION_VALUE', orderDesc);
|
|
||||||
form = form.replace('SESSION_ID_VALUE', transactionID);
|
|
||||||
form = form.replace('REQUEST_ID_VALUE', transactionID);
|
|
||||||
form = form.replace('PROJECT_ID_VALUE', 'ENTED');
|
|
||||||
form = form.replace('SERVICE_URL_VALUE', PaymentService.SERVICE_URL);
|
|
||||||
console.log(form);
|
|
||||||
const base64URL = 'data:text/html;base64,' + btoa(form);
|
|
||||||
console.log(base64URL);
|
|
||||||
return base64URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getForm(): string {
|
|
||||||
return '<html> ' +
|
|
||||||
'<head></head>' +
|
|
||||||
'<body>' +
|
|
||||||
'<form id="paymentForm" action="SERVICE_URL_VALUE" method="post">' +
|
|
||||||
'<input type="hidden" name="amount" value="AMOUNT_VALUE">' +
|
|
||||||
'<input type="hidden" name="ProjID" value="PROJECT_ID_VALUE">' +
|
|
||||||
'<input type="hidden" name="PaymentDesc" value="ORDER_DESCRIPTION_VALUE">' +
|
|
||||||
'<input type="hidden" name="sessID" value="SESSION_ID_VALUE">' +
|
|
||||||
'<input type="hidden" name="reqID" value="REQUEST_ID_VALUE">' +
|
|
||||||
'<input type="hidden" name="PayType" value="0">' +
|
|
||||||
'<input type="hidden" name="langID" value="' + (TranslatorService.getCurrentLanguageName() == 'en' ? '1' : '0') + '" >' +
|
|
||||||
'<input type="hidden" name="ResponseContinueURL" value="http://hmg.com/Documents/success.html" >' +
|
|
||||||
'<input type="hidden" name="BackClickUrl" value="http://hmg.com/Documents/success.html" >' +
|
|
||||||
'</form>' +
|
|
||||||
'<script type="text/javascript"> document.getElementById("paymentForm").submit(); </script>' +
|
|
||||||
'</body>' +
|
|
||||||
'</html>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "679409052782",
|
||||||
|
"firebase_url": "https://mohemm-dce93.firebaseio.com",
|
||||||
|
"project_id": "mohemm-dce93",
|
||||||
|
"storage_bucket": "mohemm-dce93.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:679409052782:android:dba155ac0859d7fea78a7f",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "hmg.cloudSolutions.mohem"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "679409052782-mtd6d8rjltucnm9uatn6g7et08sm6lbv.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyDgWjuSBIKGghWxYg_KGBRIZTi-O_UA8mU"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "679409052782-mtd6d8rjltucnm9uatn6g7et08sm6lbv.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "448880075189",
|
||||||
|
"firebase_url": "https://al-habib-mohemm.firebaseio.com",
|
||||||
|
"project_id": "al-habib-mohemm",
|
||||||
|
"storage_bucket": "al-habib-mohemm.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:448880075189:android:5bb4821d515a826d88b9fc",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.cloudsolutions.alhabibmohemm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "448880075189-49hc2l78pr9hsmr9p3k7j411r40diej8.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyC8nrli7eyuRNow8nF-QHvDMOxqUkj6fEw"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "448880075189-49hc2l78pr9hsmr9p3k7j411r40diej8.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
,HMG/Mohamed.Mekawy,CS-1F-MOHAMED,01.10.2019 15:25,file:///C:/Users/mohamed.mekawy/AppData/Roaming/LibreOffice/4;
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
GET_SHIFT_TYPES
|
||||||
|
GET_TIME_CARD_SUMMARY
|
||||||
|
GET_DAY_HOURS_TYPE_DETAILS
|
||||||
|
GET_SCHEDULE_SHIFTS_DETAILS
|
||||||
|
GET_SWIPES
|
||||||
|
GET_PAYSLIP
|
||||||
|
GET_SUMMARY_OF_PAYMENT
|
||||||
|
GET_EARNINGS
|
||||||
|
GET_DEDUCTIONS
|
||||||
|
GET_PAYMENT_INFORMATION
|
||||||
|
GET_MO_NOTIFICATION_BODY
|
||||||
|
GET_PR_NOTIFICATION_BODY
|
||||||
|
GET_PO_NOTIFICATION_BODY
|
||||||
|
GET_PO_ITEM_HISTORY
|
||||||
|
GET_QUOTATION_ANALYSIS
|
||||||
|
GET_PENDING_REQ_FUNCTIONS
|
||||||
|
GET_PENDING_REQ_DETAILS
|
||||||
|
UPDATE_EMPLOYEE_IMAGE
|
||||||
|
GET_OBJECT_VALUES
|
||||||
|
GET_EMPLOYEE_PHONES
|
||||||
|
SUBMIT_PHONES_TRANSACTION
|
||||||
|
START_PHONES_APPROVAL_PROCESS
|
||||||
|
GET_PHONES_NOTIFICATION_BODY
|
||||||
|
GET_EMPLOYEE_BASIC_DETAILS
|
||||||
|
GET_BASIC_DET_COLS_STRUCTURE
|
||||||
|
GET_BASIC_DET_DFF_STRUCTURE
|
||||||
|
SUBMIT_BASIC_DET_TRANSACTION
|
||||||
|
START_BASIC_DET_APPR_PROCESS
|
||||||
|
GET_BASIC_DET_NTF_BODY
|
||||||
|
GET_MO_ITEM_HISTORY
|
||||||
|
GET_COUNTRIES
|
||||||
|
GET_EMPLOYEE_ADDRESS
|
||||||
|
GET_ADDRESS_DFF_STRUCTURE
|
||||||
|
SUBMIT_ADDRESS_TRANSACTION
|
||||||
|
START_ADDRESS_APPROVAL_PROCESS
|
||||||
|
GET_ADDRESS_NOTIFICATION_BODY
|
||||||
|
GET_EMPLOYEE_CONTACTS
|
||||||
|
GET_CONTACT_DETAILS
|
||||||
|
GET_CONTACT_COLS_STRUCTURE
|
||||||
|
GET_CONTACT_DFF_STRUCTURE
|
||||||
|
SUBMIT_CONTACT_TRANSACTION
|
||||||
|
START_CONTACT_APPROVAL_PROCESS
|
||||||
|
GET_TERM_COLS_STRUCTURE
|
||||||
|
GET_TERM_DFF_STRUCTURE
|
||||||
|
SUBMIT_TERM_TRANSACTION
|
||||||
|
START_TERM_APPROVAL_PROCESS
|
||||||
|
GET_TERM_NOTIFICATION_BODY
|
||||||
|
GET_CONTACT_NOTIFICATION_BODY
|
||||||