also get booked days from calendar

This commit is contained in:
Thomas Ruoff
2022-04-01 00:12:40 +02:00
parent cd58a535cb
commit c31448ff9c
5 changed files with 43 additions and 9 deletions

View File

@@ -5,7 +5,6 @@ import { createCalendarEvent, deleteCalendarEvent } from '../lib/googlecalendar'
import { Bill } from './bill' import { Bill } from './bill'
import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums' import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums'
import { getBookedDays } from './index'
export type Booking = { export type Booking = {
uuid: string uuid: string
@@ -76,7 +75,7 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
validator: async function (days: string[]): Promise<boolean> { validator: async function (days: string[]): Promise<boolean> {
const booking = this as Booking const booking = this as Booking
const uuid = booking.uuid && [booking.uuid] const uuid = booking.uuid && [booking.uuid]
const bookedDays = await getBookedDays(uuid) const bookedDays = await BookingModel.findBookedDays(uuid)
const doubleBookedDays = days.filter((day: string): boolean => const doubleBookedDays = days.filter((day: string): boolean =>
bookedDays.includes(day) bookedDays.includes(day)
@@ -155,8 +154,10 @@ BookingSchema.static(
} }
) )
export default (mongoose.models.Booking || const BookingModel = (mongoose.models.Booking ||
mongoose.model<BookingDocument, BookingModel>( mongoose.model<BookingDocument, BookingModel>(
'Booking', 'Booking',
BookingSchema BookingSchema
)) as BookingModel )) as BookingModel
export default BookingModel;

View File

@@ -1,7 +1,9 @@
import * as mongoose from 'mongoose' import * as mongoose from 'mongoose'
import BookingModel, { Booking, BookingDocument } from './booking' import BookingModel, { Booking, BookingDocument } from './booking'
import BillModel, { Bill } from './bill' import BillModel, { Bill } from './bill'
import { getBookedDays as calendarGetBookedDays } from '../lib/googlecalendar'
import { BOOKING_STATUS } from './enums' import { BOOKING_STATUS } from './enums'
import { uniqueFilter } from '../helpers/array'
let connectedPromise: Promise<mongoose.Mongoose> let connectedPromise: Promise<mongoose.Mongoose>
@@ -21,7 +23,12 @@ export async function getBookedDays(
uuidsToIngore?: string[] uuidsToIngore?: string[]
): Promise<string[]> { ): Promise<string[]> {
await connect() await connect()
return BookingModel.findBookedDays(uuidsToIngore) const bookedInDatabase = await BookingModel.findBookedDays(uuidsToIngore);
const bookedInCalendar = await calendarGetBookedDays();
return [ ...bookedInDatabase, ...bookedInCalendar]
.filter(uniqueFilter)
.sort();
} }
export async function getBookingByUUID(uuid: string): Promise<BookingDocument> { export async function getBookingByUUID(uuid: string): Promise<BookingDocument> {

View File

@@ -16,3 +16,7 @@ export function getNextBigger<T>(array: T[], pivot: T): T {
return array.sort().find((day) => day > pivot) return array.sort().find((day) => day > pivot)
} }
export function uniqueFilter(value, index, self) {
return self.indexOf(value) === index;
}

View File

@@ -1,4 +1,4 @@
import { parse, format, addDays } from 'date-fns' import { parse, format, addDays, subDays } from 'date-fns'
import { utcToZonedTime } from 'date-fns-tz' import { utcToZonedTime } from 'date-fns-tz'
const FRONTEND_FORMAT = 'dd.MM.yyyy' const FRONTEND_FORMAT = 'dd.MM.yyyy'
@@ -21,9 +21,11 @@ export function daysFormatFrontend(days: string[]): string {
export function getDays({ export function getDays({
startDate, startDate,
endDate, endDate,
endDateExclusive = false,
}: { }: {
startDate: Date startDate: Date
endDate: Date endDate: Date
endDateExclusive?: boolean
}): string[] { }): string[] {
let currentDay = new Date(startDate.getTime()) let currentDay = new Date(startDate.getTime())
const days = [dateFormatBackend(currentDay)] const days = [dateFormatBackend(currentDay)]
@@ -32,7 +34,9 @@ export function getDays({
return days return days
} }
while (currentDay < endDate) { const inclusiveEndDate = endDateExclusive ? subDays(endDate, 1) : endDate;
while (currentDay < inclusiveEndDate) {
currentDay = addDays(currentDay, 1) currentDay = addDays(currentDay, 1)
days.push(dateFormatBackend(currentDay)) days.push(dateFormatBackend(currentDay))
} }

View File

@@ -1,5 +1,7 @@
import { google } from 'googleapis' import { google } from 'googleapis'
import { getBaseURL } from '../helpers/url';
import { Booking } from '../db/booking' import { Booking } from '../db/booking'
import { getDays } from '../helpers/date';
const calendarId = process.env.GOOGLE_CALENDAR_ID const calendarId = process.env.GOOGLE_CALENDAR_ID
let credentials: object let credentials: object
@@ -23,13 +25,21 @@ const calendar = google.calendar({
auth, auth,
}) })
export async function getNewEvents() { export async function getBookedDays() {
const { data } = await calendar.events.list({ const { data } = await calendar.events.list({
calendarId, calendarId,
timeMin: new Date().toISOString(), timeMin: new Date().toISOString(),
timeZone: 'utc',
}) })
return data.items return data.items
// ignore non all-day events
.filter(event => !!event.start.date)
.flatMap(event => getDays({
startDate: new Date(event.start.date),
endDate: new Date(event.end.date),
endDateExclusive: true
}))
} }
function getSummary(booking: Partial<Booking>): string { function getSummary(booking: Partial<Booking>): string {
@@ -44,12 +54,18 @@ function getSummary(booking: Partial<Booking>): string {
return summary return summary
} }
function getDescription(booking: Booking): string {
const bookingUrl = `${getBaseURL()}/admin/booking/${booking.uuid}`;
return `Managelink ${bookingUrl}`;
}
export async function createCalendarEvent(booking: Booking): Promise<Booking> { export async function createCalendarEvent(booking: Booking): Promise<Booking> {
const response = await calendar.events.insert({ const response = await calendar.events.insert({
calendarId, calendarId,
requestBody: { requestBody: {
summary: getSummary(booking), summary: getSummary(booking),
// TODO: description, description: getDescription(booking),
start: { date: booking.startDate }, start: { date: booking.startDate },
end: { date: booking.endDate }, end: { date: booking.endDate },
}, },
@@ -64,7 +80,9 @@ export async function deleteCalendarEvent(booking: Booking) {
await calendar.events.delete({ await calendar.events.delete({
calendarId, calendarId,
eventId: booking.calendarEventId, eventId: booking.calendarEventId,
}) // TODO: really useful?
sendNotifications: true,
});
booking.calendarEventId = null booking.calendarEventId = null
} }