forked from MapComplete/MapComplete
Fix opening hours input element
This commit is contained in:
parent
94f9a0de56
commit
64ec06bfc8
19 changed files with 643 additions and 599 deletions
|
@ -8,6 +8,9 @@ export interface OpeningHour {
|
|||
endMinutes: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Various utilities manipulating opening hours
|
||||
*/
|
||||
export class OH {
|
||||
|
||||
|
||||
|
@ -163,6 +166,12 @@ export class OH {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the number of hours since the start of day.
|
||||
* E.g.
|
||||
* startTime({startHour: 9, startMinuts: 15}) == 9.25
|
||||
* @param oh
|
||||
*/
|
||||
public static startTime(oh: OpeningHour): number {
|
||||
return oh.startHour + oh.startMinutes / 60;
|
||||
}
|
||||
|
@ -348,5 +357,125 @@ export class OH {
|
|||
|
||||
return ohs;
|
||||
}
|
||||
|
||||
/*
|
||||
This function converts a number of ranges (generated by OpeningHours.js) into all the hours of day that a change occurs.
|
||||
E.g.
|
||||
Monday, some business is opended from 9:00 till 17:00
|
||||
Tuesday from 9:30 till 18:00
|
||||
Wednesday from 9:30 till 12:30
|
||||
This function will extract all those moments of change and will return 9:00, 9:30, 12:30, 17:00 and 18:00
|
||||
This list will be sorted
|
||||
*/
|
||||
public static allChangeMoments(ranges: {
|
||||
isOpen: boolean,
|
||||
isSpecial: boolean,
|
||||
comment: string,
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
}[][]): [number[], string[]] {
|
||||
const changeHours: number[] = []
|
||||
const changeHourText: string[] = [];
|
||||
|
||||
const extrachangeHours: number[] = []
|
||||
const extrachangeHourText: string[] = [];
|
||||
|
||||
for (const weekday of ranges) {
|
||||
for (const range of weekday) {
|
||||
if (!range.isOpen && !range.isSpecial) {
|
||||
continue;
|
||||
}
|
||||
const startOfDay: Date = new Date(range.startDate);
|
||||
startOfDay.setHours(0, 0, 0, 0);
|
||||
|
||||
// The number of seconds since the start of the day
|
||||
// @ts-ignore
|
||||
const changeMoment: number = (range.startDate - startOfDay) / 1000;
|
||||
if (changeHours.indexOf(changeMoment) < 0) {
|
||||
changeHours.push(changeMoment);
|
||||
changeHourText.push(OH.hhmm(range.startDate.getHours(), range.startDate.getMinutes()))
|
||||
}
|
||||
|
||||
// The number of seconds till between the start of the day and closing
|
||||
// @ts-ignore
|
||||
let changeMomentEnd: number = (range.endDate - startOfDay) / 1000;
|
||||
if (changeMomentEnd >= 24 * 60 * 60) {
|
||||
if (extrachangeHours.indexOf(changeMomentEnd) < 0) {
|
||||
extrachangeHours.push(changeMomentEnd);
|
||||
extrachangeHourText.push(OH.hhmm(range.endDate.getHours(), range.endDate.getMinutes()))
|
||||
}
|
||||
} else if (changeHours.indexOf(changeMomentEnd) < 0) {
|
||||
changeHours.push(changeMomentEnd);
|
||||
changeHourText.push(OH.hhmm(range.endDate.getHours(), range.endDate.getMinutes()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that 'changeHours' and 'changeHourText' will be more or less in sync - one is in numbers, the other in 'HH:MM' format.
|
||||
// But both can be sorted without problem; they'll stay in sync
|
||||
changeHourText.sort();
|
||||
changeHours.sort();
|
||||
extrachangeHourText.sort();
|
||||
extrachangeHours.sort();
|
||||
|
||||
changeHourText.push(...extrachangeHourText);
|
||||
changeHours.push(...extrachangeHours);
|
||||
|
||||
return [changeHours, changeHourText]
|
||||
}
|
||||
|
||||
/*
|
||||
Calculates when the business is opened (or on holiday) between two dates.
|
||||
Returns a matrix of ranges, where [0] is a list of ranges when it is opened on monday, [1] is a list of ranges for tuesday, ...
|
||||
*/
|
||||
public static GetRanges(oh: any, from: Date, to: Date): ({
|
||||
isOpen: boolean,
|
||||
isSpecial: boolean,
|
||||
comment: string,
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
}[])[] {
|
||||
|
||||
|
||||
const values = [[], [], [], [], [], [], []];
|
||||
|
||||
const start = new Date(from);
|
||||
// We go one day more into the past, in order to force rendering of holidays in the start of the period
|
||||
start.setDate(from.getDate() - 1);
|
||||
|
||||
const iterator = oh.getIterator(start);
|
||||
|
||||
let prevValue = undefined;
|
||||
while (iterator.advance(to)) {
|
||||
|
||||
if (prevValue) {
|
||||
prevValue.endDate = iterator.getDate() as Date
|
||||
}
|
||||
const endDate = new Date(iterator.getDate()) as Date;
|
||||
endDate.setHours(0, 0, 0, 0)
|
||||
endDate.setDate(endDate.getDate() + 1);
|
||||
const value = {
|
||||
isSpecial: iterator.getUnknown(),
|
||||
isOpen: iterator.getState(),
|
||||
comment: iterator.getComment(),
|
||||
startDate: iterator.getDate() as Date,
|
||||
endDate: endDate // Should be overwritten by the next iteration
|
||||
}
|
||||
prevValue = value;
|
||||
|
||||
if (value.comment === undefined && !value.isOpen && !value.isSpecial) {
|
||||
// simply closed, nothing special here
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.startDate < from) {
|
||||
continue;
|
||||
}
|
||||
// Get day: sunday is 0, monday is 1. We move everything so that monday == 0
|
||||
values[(value.startDate.getDay() + 6) % 7].push(value);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue