Skip to content

Commit

Permalink
TOP-202
Browse files Browse the repository at this point in the history
  • Loading branch information
apricot13 committed Sep 17, 2024
1 parent baba4a7 commit b02717a
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 1 deletion.
28 changes: 28 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"isomorphic-unfetch": "^4.0.2",
"mongodb": "^6.5.0",
"morgan": "^1.10.0",
"rrule": "^2.8.1",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"winston": "^3.13.0"
Expand Down
5 changes: 5 additions & 0 deletions src/controllers/v1/services/routes/get-services.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ module.exports = {
let endTime = queryParams?.end_time ? [].concat(queryParams.end_time) : []
let day = queryParams?.day ? [].concat(queryParams.day) : []

const startDate = queryParams.start_date || undefined
const endDate = queryParams.end_date || undefined

// not a param but we want to save on requests
let interpreted_location

Expand Down Expand Up @@ -112,6 +115,8 @@ module.exports = {
startTime,
endTime,
day,
startDate,
endDate,
accessibilities,
only,
minAge,
Expand Down
119 changes: 118 additions & 1 deletion src/lib/filters.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { db } = require("../db")
const logger = require("../../utils/logger")
const { RRule, RRuleSet, rrulestr } = require("rrule")

module.exports = {
const filters = {
visibleNow: () => {
let query = []
query.push({
Expand Down Expand Up @@ -233,4 +234,120 @@ module.exports = {

return query
},

/**
* Filter for services that have events that occur between two dates
* @param {*} startDate
* @param {*} endDate
* @returns
*/
filterStartDateEndDate: async (startDate, endDate) => {
if (startDate && endDate) {
logger.debug("filterStartDateEndDate")
// find services with regularSchedules
const visibleNow = filters.visibleNow()
const rs_query = {
regular_schedules: {
$elemMatch: {
dtstart: { $exists: true, $ne: null },
},
},
$and: [...visibleNow],
}

logger.debug("\n\nℹ️ filterStartDateEndDate query")
logger.debug(rs_query)
logger.debug(JSON.stringify(rs_query))

const Service = db().collection("indexed_services")
const regularSchedules = await Service.find(rs_query).toArray()

const singleEventRegularScheduleIds = []
const recurringEventRegularScheduleIds = []
regularSchedules.forEach(service => {
service.regular_schedules.forEach(schedule => {
// find single events that occur between the start and end date
if (
schedule.freq === null &&
new Date(schedule.dtstart) >= new Date(startDate) &&
new Date(schedule.dtstart) <= new Date(endDate)
) {
singleEventRegularScheduleIds.push(schedule.id)
}
// find recurring events that occur between the start and end date

const { freq, interval, byday, bymonthday, dtstart, until, count } =
schedule

if (freq !== null) {
const freqMapping = {
week: "WEEKLY",
month: "MONTHLY",
}

let options = {
dtstart: new Date(dtstart),
freq: RRule[freqMapping[freq]],
interval: interval,
until: until ? new Date(until) : null,
count: count,
}

// weekly repeating events can have MO or TU,WE
if (freq === "week") {
options = {
byweekday: byday
? byday.split(",").map(day => RRule[day])
: null,
...options,
}
}

// monthly repeating can have bymonthday = 1[st day of the month]
// or byweekday in format -1MO [Last Monday of the month], 2TU [Second Tuesday of the month] etc which uses bysetpos
if (freq === "month") {
if (bymonthday) {
options = {
bymonthday: bymonthday ? bymonthday : null,
...options,
}
} else if (byday) {
const bysetpos = byday.split(",").map(day => {
const match = day.match(/(-?\d+)([A-Z]+)/)
return [match[1], match[2]]
})
options = {
bysetpos: bysetpos[0][0],
byweekday: RRule[bysetpos[0][1]],
...options,
}
}
}
const rule = new RRule(options)
const dates = rule.between(
new Date(startDate),
new Date(endDate),
true
)

if (dates.length > 0) {
recurringEventRegularScheduleIds.push(schedule.id)
}
}
})
})

return {
"regular_schedules.id": {
$in: [
...singleEventRegularScheduleIds,
...recurringEventRegularScheduleIds,
],
},
}
}
return {}
},
}

module.exports = filters
4 changes: 4 additions & 0 deletions src/lib/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ module.exports = {
parameters.startTime,
parameters.endTime,
parameters.day
),
await filters.filterStartDateEndDate(
parameters.startDate,
parameters.endDate
)
)

Expand Down
20 changes: 20 additions & 0 deletions src/routes/parameters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,23 @@ parameters:
schema:
type: string
# example: "Monday"

start_date:
name: start_date
in: query
description: Start date of the event. eg/ 2020-01-01
required: false
schema:
type: string
format: date
# example: "2020-01-01"

end_date:
name: end_date
in: query
description: End date of the event. eg/ 2020-01-31
required: false
schema:
type: string
format: date
# example: "2020-01-31"
2 changes: 2 additions & 0 deletions src/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ module.exports.setup = app => {
* - $ref: '#/parameters/start_time'
* - $ref: '#/parameters/end_time'
* - $ref: '#/parameters/day'
* - $ref: '#/parameters/start_date'
* - $ref: '#/parameters/end_date'
* responses:
* '200':
* description: successful operation
Expand Down

0 comments on commit b02717a

Please sign in to comment.