diff --git a/src/services/trainService.services.ts b/src/services/trainService.services.ts index 647b9b3..413416f 100644 --- a/src/services/trainService.services.ts +++ b/src/services/trainService.services.ts @@ -4,6 +4,8 @@ const pis = require("../services/pis.services"); import { logger } from "../utils/logger.utils"; +import type { TrainServices, Service, Stop } from "@owlboard/ts-types"; + // This function is deprecated and should no longer be used. // It will be removed in a later version async function findByHeadcodeToday(headcode: string) { @@ -42,7 +44,7 @@ async function findByHeadcodeToday(headcode: string) { } // Finds a train by its headcode value -async function findByHeadcode(date: string | Date, headcode: string) { +async function findByHeadcode(date: string | Date, headcode: string): Promise { const sanitizedHeadcode = clean.removeNonAlphanumeric(headcode).toUpperCase(); logger.debug( `trainServiceServices.findByHeadcode: Searching for headcode ${sanitizedHeadcode}` @@ -80,13 +82,13 @@ async function findByHeadcode(date: string | Date, headcode: string) { }, }, ]; - const queryData = await db.queryAggregate("timetable", pipeline); + const queryData: Service[] = await db.queryAggregate("timetable", pipeline); let filteredData = filterServices(queryData); return await filteredData; } // Finds a train by its trainUid value -async function findByTrainUid(uid: string, date: Date | string = new Date()) { +async function findByTrainUid(uid: string, date: Date | string = new Date()): Promise { let queryDate; if (date === "now") { queryDate = new Date(); @@ -100,7 +102,7 @@ async function findByTrainUid(uid: string, date: Date | string = new Date()) { }; const queryData = await db.query("timetable", query); if (queryData.length === 0) { - return []; + return queryData; } let services; services = await filterServices(queryData); @@ -128,7 +130,7 @@ module.exports = { /* Accepts the 'stops' array from a db query and produces an array of only public stops as TIPLOCs. */ -async function getPublicStops(data) { +async function getPublicStops(data: Stop[]): Promise { let tiplocList = []; for (const publicStop in data) { if (data[publicStop]["isPublic"]) { @@ -141,24 +143,26 @@ async function getPublicStops(data) { /* Takes a single days data from a headcode query and requeries using the trainUid, required to ensure any cancellations are accounted for */ -async function parseTrains(data) { - let trainUids = []; +async function parseTrains(data: TrainServices[]): Promise { + let trainUids: string[] = []; for (const i of data) { const trainUid = i["trainUid"]; if (!trainUids.includes(trainUid)) { trainUids.push(trainUid); } } - let parsedData = []; + let parsedData: TrainServices[] = []; for (const i in trainUids) { - const result = await findByTrainUid(trainUids[i]); - parsedData.push(result); + const result: TrainServices | null = await findByTrainUid(trainUids[i]); + if (result) { + parsedData.push(result); + } } return parsedData; } // Filters services based on their STP Indicator -async function filterServices(data) { +async function filterServices(data: Service[]): Promise { let stpIndicators = {}, filteredServices = []; for (const serviceDetail of data) { diff --git a/src/services/trainService.services2ts b/src/services/trainService.services2ts new file mode 100644 index 0000000..6c66bb1 --- /dev/null +++ b/src/services/trainService.services2ts @@ -0,0 +1,40 @@ +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 { + 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 +} \ No newline at end of file diff --git a/src/utils/trainService.utils.ts b/src/utils/trainService.utils.ts new file mode 100644 index 0000000..7cef600 --- /dev/null +++ b/src/utils/trainService.utils.ts @@ -0,0 +1,20 @@ +export function getFindByHeadcodePipeline(query: any) { + return [ + { + $match: query, + }, + { + $project: { + operator: 1, + stops: { + $concatArrays: [ + [{ $first: "$stops" }], + [{ $arrayElemAt: ["$stops", -1] }], + ], + }, + trainUid: 1, + stpIndicator: 1, + }, + }, + ]; +} \ No newline at end of file