added bus service

This commit is contained in:
Gansner Pascal
2020-05-05 14:28:49 +02:00
parent 0da20e82df
commit ca174a4e6e
7 changed files with 234 additions and 2 deletions
+8
View File
@@ -14,5 +14,13 @@
"^/slsapi": ""
},
"changeOrigin": true
},
"/coronabusapi": {
"target": "https://corona-api-dmz.psi.ch/bus.asmx",
"secure": false,
"pathRewrite": {
"^/coronabusapi": ""
},
"changeOrigin": true
}
}
+10
View File
@@ -0,0 +1,10 @@
import { HttpHeaders, HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export class SoapApiHelper {
public static call<T>(http: HttpClient, url: string, data: object): Observable<T> {
return http.post<T>(url, data, { responseType: 'json', headers: new HttpHeaders({ 'ContentType': 'application/json' }) })
.pipe(map((response: any) => response.d));
}
}
+30
View File
@@ -25,3 +25,33 @@ export interface Departure {
end_time: string,
date: string
}
export enum BusStatus {
Ok = 0,
Cirtical = 1,
Full = 2,
}
export enum BusDirection {
ToPSI,
FromPSI
}
export interface BusInformationDTO {
BusId: number;
Status: BusStatus;
Nb: number;
}
export interface BusInformation {
id: number;
status: BusStatus;
currentNb: number;
}
export interface Bus {
id: number;
date: Date;
direction: BusDirection;
}
@@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { CoronaBusService } from './corona-bus.service';
describe('CoronaBusService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: CoronaBusService = TestBed.get(CoronaBusService);
expect(service).toBeTruthy();
});
});
+168
View File
@@ -0,0 +1,168 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BusInformationDTO, Bus, BusDirection, BusInformation, BusStatus } from '../interfaces/bus-schedule';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { map, switchMap } from 'rxjs/operators';
import { SoapApiHelper } from '../classes/api-helper';
@Injectable({
providedIn: 'root'
})
export class CoronaBusService {
public static readonly STORAGE_NAME = 'bus-selection';
constructor(private http: HttpClient) { }
/**
* The bus selection will be saved on the server and in the local storage.
*
* @param date date of travel without hours, minutes and seconds
* @param id unique id of the bus
* @param direction direction of the bus
*/
public async selectBusAsync(date: Date, id: number, direction: BusDirection): Promise<any> {
date = new Date(date.toDateString());
return new Promise<any>((resolve, reject) => {
if (this.isBusSelected(date, direction)) {
reject('A bus is already selected for this date and direction.');
}
this.addPersonToBus(date, id)
.subscribe(
_ => {
this.saveSelection(date, id, direction);
resolve();
}, error => {
reject(error);
}
);
});
}
/**
* Changes the bus selection for a specific date and direction.
*
* @param date date of travel without hours, minutes and seconds
* @param newIid unique id of the currently selected bus
* @param direction direction of the previously selected bus
*/
public async changeSelectionAsync(date: Date, newId: number, direction: BusDirection): Promise<any> {
date = new Date(date.toDateString());
return new Promise<any>((resolve, reject) => {
if (!this.isBusSelected(date, direction)) {
reject('Can not cange selection. No bus is selected for this direction and date.');
}
let selected = this.loadSelections().find(bus => bus.date.getTime() === date.getTime() && bus.direction === direction);
this.changePersonsBus(date, selected.id, newId)
.subscribe(
_ => {
this.saveSelection(date, newId, direction);
resolve();
}, error => {
reject(error);
}
);
});
}
/**
* Returns all selected buses.
*/
public getSelections(): Bus[] {
return this.loadSelections();
}
/**
* Loads the selected buses from the local storage.
*/
private loadSelections(): Bus[] {
let busStorage = localStorage.getItem(CoronaBusService.STORAGE_NAME);
if (!busStorage) {
return [];
}
let selections = <Bus[]>JSON.parse(busStorage);
selections = selections.map(row => <Bus>{ id: row.id, date: new Date(row.date), direction: row.direction });
return selections;
}
/**
* Saves the bus selction to the local storage.
* If a bus is already selected on this date it will update this selection.
*
* @param date date of travel without hours, minutes and seconds
* @param id id of the bus course
*/
private saveSelection(date: Date, id: number, direction: BusDirection): void {
date = new Date(date.toDateString()); // make sure the date has no time
const today = new Date(new Date().toDateString());
let selections = this.loadSelections();
selections = selections.filter(selection => selection.date.getTime() >= today.getTime());
let index = selections.findIndex(selection => selection.date.getTime() === date.getTime() && selection.direction === direction);
if (index >= 0) {
selections[index].id = id;
} else {
selections.push({ date, id, direction });
}
localStorage.setItem(CoronaBusService.STORAGE_NAME, JSON.stringify(selections));
}
/**
* Checks if a bus is selected at the given date for the given direction.
*
* @param date date of travel without hours, minutes and seconds
* @param direction direction of the bus
*/
private isBusSelected(date: Date, direction: BusDirection): boolean {
console.dir(date);
let index = this.loadSelections().findIndex(bus => bus.date.getTime() === date.getTime() && bus.direction === direction);
console.dir(index);
return index >= 0;
}
/**
* Increments the number of persons on the backend.
*
* @param date date of travel without hours, minutes and seconds
* @param id unique id of the bus
*/
private addPersonToBus(date: Date, id: number): Observable<void> {
return SoapApiHelper.call(this.http, environment.corona_bus_api + '/AddPersonToBus', { date, id });
}
/**
* Decrements the number of persons on the old bus and increments it on the new bus.
*
* @param date date of travel without hours, minutes and seconds
* @param oldId uniqe id of the previously selected bus
* @param newId unique id of the current selelcted bus
*/
private changePersonsBus(date: Date, oldId: number, newId: number): Observable<void> {
return SoapApiHelper.call(this.http, environment.corona_bus_api + '/ChangePersonsBus', { date, oldId, newId });
}
/**
* Loads the status of a specific bus from the backend.
*
* @param date date of travel without hours, minutes and seconds
* @param id unique id of the bus
*/
private getBusStatus(date: Date, id: number): Observable<any> {
return SoapApiHelper.call(this.http, environment.corona_bus_api + '/GetBusStatus', { date, id });
}
/**
* Loads all buses and teihr status which have at least one passenger.
* If the bus has no passenger the bus might appear in this list.
*
* @param date date of travel without hours, minutes and seconds
*/
public getBusesStatus(date: Date): Observable<BusInformation[]> {
return SoapApiHelper.call<BusInformationDTO[]>(this.http, environment.corona_bus_api + '/GetBusesStatus', { date })
.pipe(map(dtos => dtos.map(dto => <BusInformation>{ id: dto.BusId, status: dto.Status, currentNb: dto.Nb })));
}
}
+3 -1
View File
@@ -17,5 +17,7 @@ export const environment = {
// zpt image and calendar urls
zptforecast: 'http://spotscan.ch/forecast/forecast-snapshot.png?',
zptshifts: 'http://spotscan.ch/1715/shifts-1715-2019.PNG?',
zptcalendar: 'http://spotscan.ch/CPTcalendar/'
zptcalendar: 'http://spotscan.ch/CPTcalendar/',
// corona
corona_bus_api: 'https://corona-api-dmz.psi.ch/bus.asmx',
};
+3 -1
View File
@@ -22,7 +22,9 @@ export const environment = {
zptforecast: 'http://spotscan.ch/forecast/forecast-snapshot.png?',
zptshifts: 'http://spotscan.ch/1715/shifts-1715-2019.PNG?',
zptcalendar: 'http://spotscan.ch/CPTcalendar/',
};
// corona
corona_bus_api: 'coronabusapi',
};
/*
* For easier debugging in development mode, you can import the following file