TimetableAPI-Upgrade #64
8
package-lock.json
generated
8
package-lock.json
generated
@ -24,7 +24,7 @@
|
|||||||
"zlib": "^1.0.5"
|
"zlib": "^1.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@owlboard/ts-types": "^0.1.3",
|
"@owlboard/ts-types": "^0.1.5",
|
||||||
"@types/jest": "^29.5.3",
|
"@types/jest": "^29.5.3",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.39.0",
|
||||||
"jest": "^29.6.2",
|
"jest": "^29.6.2",
|
||||||
@ -1983,9 +1983,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@owlboard/ts-types": {
|
"node_modules/@owlboard/ts-types": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.5",
|
||||||
"resolved": "https://git.fjla.uk/api/packages/OwlBoard/npm/%40owlboard%2Fts-types/-/0.1.3/ts-types-0.1.3.tgz",
|
"resolved": "https://git.fjla.uk/api/packages/OwlBoard/npm/%40owlboard%2Fts-types/-/0.1.5/ts-types-0.1.5.tgz",
|
||||||
"integrity": "sha512-BKi/tWvA0SN2rgt2GnFnSXEXzG3DNjeTm0ojVuMElnok9MJ9IniTXRjdAdjm+fe5ShebH6EKacO5f1MDAD3qJw==",
|
"integrity": "sha512-bbCSDpwAJSUKFHcT3QwXAutlBp02QqAXvobg/wGm8zoaAeWNozWeJSdceMzgse6Ywc1aGamP4w20hlTREl7f8g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GPL-3.0-or-later"
|
"license": "GPL-3.0-or-later"
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
"zlib": "^1.0.5"
|
"zlib": "^1.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@owlboard/ts-types": "^0.1.3",
|
"@owlboard/ts-types": "^0.1.5",
|
||||||
"@types/jest": "^29.5.3",
|
"@types/jest": "^29.5.3",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.39.0",
|
||||||
"jest": "^29.6.2",
|
"jest": "^29.6.2",
|
||||||
|
128
src/services/trainService.services2.ts
Normal file
128
src/services/trainService.services2.ts
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import { logger } from "../utils/logger.utils";
|
||||||
|
import { findByTiplocArray } from "../services/pis.services"
|
||||||
|
import { queryAggregate } from "./dbAccess.services";
|
||||||
|
import { getFindByHeadcodePipeline, getFindByTrainUidPipeline } from "../utils/trainService.utils"
|
||||||
|
import { removeNonAlphanumeric } from "../utils/sanitizer.utils"
|
||||||
|
|
||||||
|
import type { TrainServices, Service, Stop, SimpleService } from "@owlboard/ts-types";
|
||||||
|
|
||||||
|
export async function findByHeadcode(headcode: string, date: Date | string): Promise<SimpleService[]> {
|
||||||
|
const sanitizedHeadcode = removeNonAlphanumeric(headcode);
|
||||||
|
logger.debug(`trainServices.findByHeadcode: Searching for trains by headcode: ${headcode}`)
|
||||||
|
|
||||||
|
// If 'now' then generate a new Date now, else use the provided date, then set time to 1200.
|
||||||
|
const searchDate = (date === "now") ? new Date() : new Date(date);
|
||||||
|
searchDate.setHours(12, 0, 0);
|
||||||
|
|
||||||
|
// Get the 'shortDay'
|
||||||
|
const shortDay = getShortDay(searchDate)
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
headcode: sanitizedHeadcode,
|
||||||
|
scheduleStartDate: { $lte: searchDate },
|
||||||
|
scheduleEndDate: { $gte: searchDate },
|
||||||
|
daysRun: { $in: [shortDay] },
|
||||||
|
};
|
||||||
|
const pipeline = getFindByHeadcodePipeline(query)
|
||||||
|
|
||||||
|
const result: SimpleService[] = await queryAggregate("timetable", pipeline) as SimpleService[]
|
||||||
|
|
||||||
|
const services = filterServices(result);
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function findByTrainUid(uid: string, date: Date | string = new Date()) {
|
||||||
|
// Set the correct date - whether a date or "now" was passed to function
|
||||||
|
let queryDate: Date;
|
||||||
|
if (date instanceof Date) {
|
||||||
|
queryDate = date;
|
||||||
|
} else {
|
||||||
|
queryDate = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build query
|
||||||
|
const query = {
|
||||||
|
trainUid: uid,
|
||||||
|
scheduleStartDate: { $lte: queryDate },
|
||||||
|
scheduleEndDate: { $gte: queryDate },
|
||||||
|
daysRun: { $in: [getShortDay(queryDate)] }
|
||||||
|
}
|
||||||
|
const pipeline = getFindByTrainUidPipeline(query)
|
||||||
|
|
||||||
|
const result = await queryAggregate("timetable", pipeline) as Service[]
|
||||||
|
|
||||||
|
let services = filterServices(result) as Service[]
|
||||||
|
|
||||||
|
// Next up is the public stops filter, followed by the PIS filter.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal Functions:
|
||||||
|
|
||||||
|
// Outputs the standard 'shortday' string from a Date.
|
||||||
|
function getShortDay(day: Date): string {
|
||||||
|
const dayMap = ["su", "m", "t", "w", "th", "f", "s"];
|
||||||
|
const shortDay = dayMap[day.getDay()];
|
||||||
|
return shortDay
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters services using their STP indicator so that over-riding entries are returned correctly
|
||||||
|
function filterServices(services: SimpleService[]): (SimpleService[]) {
|
||||||
|
let stpIndicators: Record<string, { hasC: boolean; hasN: boolean; hasO: boolean; hasP: boolean }> = {};
|
||||||
|
let filteredServices: SimpleService[] = []
|
||||||
|
|
||||||
|
for (const service of services) {
|
||||||
|
const trainUid = service["trainUid"], stpIndicator = service["stpIndicator"]
|
||||||
|
|
||||||
|
// Creates the stpIndicators array:
|
||||||
|
if (!stpIndicators[trainUid]) {
|
||||||
|
stpIndicators[trainUid] = {
|
||||||
|
hasC: false, hasN: false, hasO: false, hasP: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stpIndicator === "C") {
|
||||||
|
stpIndicators[trainUid].hasC = true;
|
||||||
|
}
|
||||||
|
if (stpIndicator === "N") {
|
||||||
|
stpIndicators[trainUid].hasN = true;
|
||||||
|
}
|
||||||
|
if (stpIndicator === "O") {
|
||||||
|
stpIndicators[trainUid].hasO = true;
|
||||||
|
}
|
||||||
|
if (stpIndicator === "P") {
|
||||||
|
stpIndicators[trainUid].hasP = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate each service, and only output one service matching each trainUid,
|
||||||
|
// C > N > O > P is the order, with C being prioritised over other STP types.
|
||||||
|
for (const service of services) {
|
||||||
|
const trainUid = service["trainUid"]
|
||||||
|
const thisStpIndicators = stpIndicators[trainUid];
|
||||||
|
const stpIndicator = service["stpIndicator"];
|
||||||
|
|
||||||
|
if (stpIndicator === "C") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (stpIndicator === "N" && !thisStpIndicators.hasC) {
|
||||||
|
filteredServices.push(service);
|
||||||
|
} else if (
|
||||||
|
stpIndicator === "O" &&
|
||||||
|
!thisStpIndicators.hasC &&
|
||||||
|
!thisStpIndicators.hasN
|
||||||
|
) {
|
||||||
|
filteredServices.push(service);
|
||||||
|
} else if (
|
||||||
|
stpIndicator === "P" &&
|
||||||
|
!thisStpIndicators.hasC &&
|
||||||
|
!thisStpIndicators.hasN &&
|
||||||
|
!thisStpIndicators.hasO
|
||||||
|
) {
|
||||||
|
filteredServices.push(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local Types:
|
@ -1,40 +0,0 @@
|
|||||||
import { logger } from "../utils/logger.utils";
|
|
||||||
import { findByTiplocArray } from "../services/pis.services"
|
|
||||||
import { queryAggregate } from "./dbAccess.services";
|
|
||||||
import { getFindByHeadcodePipeline } from "../utils/trainService.utils"
|
|
||||||
import { removeNonAlphanumeric } from "../utils/sanitizer.utils"
|
|
||||||
|
|
||||||
import type { TrainServices, Service, Stop } from "@owlboard/ts-types";
|
|
||||||
import type { Document } from "mongodb";
|
|
||||||
|
|
||||||
export async function findByHeadcode(headcode: string, date: Date | string): Promise<TrainServices[]> {
|
|
||||||
const sanitizedHeadcode = removeNonAlphanumeric(headcode);
|
|
||||||
logger.debug(`trainServices.findByHeadcode: Searching for trains by headcode: ${headcode}`)
|
|
||||||
|
|
||||||
// If 'now' then generate a new Date now, else use the provided date, then set time to 1200.
|
|
||||||
const searchDate = (date === "now") ? new Date() : new Date(date);
|
|
||||||
searchDate.setHours(12, 0, 0);
|
|
||||||
|
|
||||||
// Get the 'shortDay'
|
|
||||||
const shortDay = getShortDay(searchDate)
|
|
||||||
|
|
||||||
const query = {
|
|
||||||
headcode: sanitizedHeadcode,
|
|
||||||
scheduleStartDate: { $lte: searchDate },
|
|
||||||
scheduleEndDate: { $gte: searchDate },
|
|
||||||
daysRun: { $in: [shortDay] },
|
|
||||||
};
|
|
||||||
const pipeline = getFindByHeadcodePipeline(query)
|
|
||||||
// Before proceeding, I need to check the return from the database to ensure that it
|
|
||||||
// is of type Service[] - for this use the Aggregate function in Compass.
|
|
||||||
const result: Service[] = await queryAggregate("timetable", pipeline) as Service[]
|
|
||||||
|
|
||||||
// The Filter Services function needs writing - possibly moving to utils as it is long.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outputs the standard 'shortday' string from a Date.
|
|
||||||
function getShortDay(day: Date): string {
|
|
||||||
const dayMap = ["su", "m", "t", "w", "th", "f", "s"];
|
|
||||||
const shortDay = dayMap[day.getDay()];
|
|
||||||
return shortDay
|
|
||||||
}
|
|
@ -17,4 +17,10 @@ export function getFindByHeadcodePipeline(query: any) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFindByTrainUidPipeline(query: any) {
|
||||||
|
return [{
|
||||||
|
'$match': query,
|
||||||
|
},{'$project': {'_id': 0}}]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user