solvice-js-client
Version:
A JavaScript client to access the Solvice api.
148 lines (124 loc) • 5.29 kB
text/typescript
import {IOrder} from "./models/order";
import {ILocation} from "./models/location";
import {IFleetUnit} from "./models/fleet-unit";
import {HttpClient} from "./http-client";
import {IVrpOrder} from "./models/order";
import {IVrpFleetUnit} from "./models/fleet-unit";
import {ISolverOptions, SolverOptionType} from "./models/options";
export interface IClientOptions {
apiUrl?: string;
version?: number;
}
export class BaseClient<OrderType extends IOrder, FleetUnitType extends IFleetUnit> {
private clientOptions: IClientOptions = {
apiUrl: "https://api.solvice.io",
version: 1
};
private locations: ILocation[] = [];
private orders: OrderType[] = [];
private fleet: FleetUnitType[] = [];
private options: ISolverOptions = {};
constructor(options: IClientOptions = {}) {
if (options.apiUrl) {
this.clientOptions.apiUrl = options.apiUrl;
}
if (options.version) {
this.clientOptions.version = options.version;
}
}
public addLocation(location: ILocation) : void {
this.verifyLocation(location);
this.locations.push(location);
}
public addOrder(order: OrderType) : void {
this.verifyOrder(order);
this.orders.push(order);
}
public addFleetUnit(fleetUnit: FleetUnitType) {
this.verifyFleetUnit(fleetUnit);
this.fleet.push(fleetUnit);
}
public setOption(option: SolverOptionType, value: boolean|number) {
this.verifyOptionalInArray(option, 'option', [
'capacitySpread',
'minimizeDriverWaitTime',
'minimizeUseOfVehicles',
'vehicleSetupCost',
'minimumMinutesWorked'
]);
this.options[option] = value;
}
public getRoute(success?: Function, error?: Function) {
return HttpClient.post(this.getEndpointUrl(), this.getRouteRequestParams(), success, error);
}
public getJobResult(jobId: string, success?: Function, error?: Function) {
return HttpClient.get(this.getJobsEndpointUrl(jobId), success, error);
}
public getRouteRequestParams(): any {
return {
locations: this.locations,
orders: this.orders,
fleet: this.fleet,
solverType: this.getSolverType(),
options: this.options
};
}
protected getSolverType() {
return "";
}
protected verifyLocation(location: ILocation) : void {
this.verifyExist(location, 'location');
this.verifyExist(location.latitude, 'latitude');
this.verifyExist(location.longitude, 'longitude');
this.verifyExist(location.name, 'name');
}
protected verifyOrder(order: IOrder) : void {
this.verifyExist(order, 'order');
this.verifyExist(order.name, 'name');
this.verifyExist(order.location, 'location');
this.verifyOptionalFieldType(order.demand, 'demand', 'number');
this.verifyOptionalFieldType(order.duration, 'duration', 'number');
}
protected verifyFleetUnit(fleetUnit: IFleetUnit) : void {
this.verifyExist(fleetUnit, 'fleetUnit');
this.verifyExist(fleetUnit.name, 'name');
this.verifyExist(fleetUnit.startlocation, 'startlocation');
this.verifyOptionalFieldType(fleetUnit.endlocation, 'endlocation', 'string');
this.verifyOptionalFieldType(fleetUnit.capacity, 'capacity', 'number');
this.verifyOptionalFieldType(fleetUnit.shiftstart, 'shiftstart', 'number');
this.verifyOptionalFieldType(fleetUnit.shiftend, 'shiftend', 'number');
this.verifyOptionalFieldType(fleetUnit.breakstart, 'breakstart', 'number');
this.verifyOptionalFieldType(fleetUnit.breakend, 'breakend', 'number');
this.verifyOptionalFieldType(fleetUnit.breakduration, 'breakduration', 'number');
this.verifyOptionalFieldType(fleetUnit.maxminutes, 'maxminutes', 'number');
this.verifyOptionalFieldType(fleetUnit.category, 'category', 'string');
this.verifyOptionalFieldType(fleetUnit.type, 'type', 'string');
}
protected verifyExist(field: any, fieldName: string): void {
if (!field) {
throw new TypeError(`MISSING_FIELD: ${fieldName}`);
}
}
protected verifyOptionalFieldType(field: any, fieldName: string, type: string): void {
if (type === 'array') {
if (field && (typeof field !== 'object' || !field.hasOwnProperty('length'))) {
throw new TypeError(`${fieldName} should be an array`);
}
}
else if (field && typeof field !== type) {
throw new TypeError(`${fieldName} should be of type ${type}`);
}
}
protected verifyOptionalInArray(field: string, fieldName: string, options: string[]) {
const regex = new RegExp('('+options.join('|')+')', 'i');
if (field && !regex.test(field)) {
throw new TypeError(`Invalid value for ${fieldName}. Possible values are: ` + options.join(', '))
}
}
private getEndpointUrl() : string {
return `${this.clientOptions.apiUrl}/solve`;
}
private getJobsEndpointUrl(jobId: string) : string {
return `${this.clientOptions.apiUrl}/jobs/${jobId}`;
}
}