UNPKG

occasion-sdk

Version:

An SDK library that enables access to Occasion's application, providing a rich DSL for creating and managing bookings.

155 lines (127 loc) 4.1 kB
// @todo Remove includes({ product: 'merchant' }) when AR supports owner assignment to has_many children // in non-load queries Occasion.__constructCalendar = function __constructCalendar(month, { calendar, monthlyTimeSlotDaysBatchSize, monthlyTimeSlotPreloadSize, preload, prevPagePromise, relation, status, timeZone } = {}) { var today = moment.tz(timeZone); status = status || 'bookable'; var lowerRange; if(month) { lowerRange = month.tz(timeZone); } else { lowerRange = today; } lowerRange = lowerRange.startOf('month'); var upperRange = lowerRange.clone().endOf('month'); var numRequests = Math.ceil(upperRange.diff(lowerRange, 'days') / monthlyTimeSlotDaysBatchSize); if(numRequests < 1) numRequests = 1; var i = 0; var requests = []; var lower = lowerRange.clone(); var upper = lowerRange.clone().add(monthlyTimeSlotDaysBatchSize, 'days'); while(i < numRequests) { if(i + 1 == numRequests) upper = upperRange.clone(); requests.push( relation .includes({ product: 'merchant' }) .where({ startsAt: { ge: lower.toDate(), le: upper.toDate() }, status }).all() ); lower.add(monthlyTimeSlotDaysBatchSize, 'days'); upper.add(monthlyTimeSlotDaysBatchSize, 'days'); i++; } calendar = calendar || {}; if(_.isUndefined(calendar.__currentPage)) calendar.__currentPage = 0; if(_.isUndefined(calendar.__preloadedPages)) calendar.__preloadedPages = 0; calendar.__preloading = true; var currentPromise = Promise.all(requests) .then(function(timeSlotsArray) { var allTimeSlots = ActiveResource.Collection .build(timeSlotsArray) .map(function(ts) { return ts.toArray() }) .flatten(); let startDate = moment(lowerRange).startOf('month'); let endDate = moment(lowerRange).endOf('month'); var response = ActiveResource.CollectionResponse.build(); let day = startDate; while(day.isSameOrBefore(endDate)) { response.push({ day, timeSlots: allTimeSlots.select((timeSlot) => { return timeSlot.startsAt.isSame(day, 'day'); }) }); day = day.clone().add(1, 'days'); } response.hasNextPage = function() { return true; }; let commonPaginationOptions = { calendar, monthlyTimeSlotDaysBatchSize, monthlyTimeSlotPreloadSize, relation, status, timeZone }; response.nextPage = function(preloadCount) { if(!this.nextPromise) { this.nextPromise = Occasion.__constructCalendar( moment(upperRange).add(1, 'days').startOf('month'), { ...commonPaginationOptions, preload: preloadCount, prevPagePromise: currentPromise, }, ); } if(_.isUndefined(preloadCount)) { calendar.__currentPage += 1; if(!calendar.__preloading && calendar.__preloadedPages <= calendar.__currentPage + monthlyTimeSlotPreloadSize / 2) { calendar.__lastPreloadedPage.nextPage(monthlyTimeSlotPreloadSize); } } return this.nextPromise; }; if(status !== 'bookable' || (month && !month.isSame(today, 'month'))) { response.hasPrevPage = function() { return true; }; response.prevPage = function() { this.prevPromise = this.prevPromise || prevPagePromise || Occasion.__constructCalendar( moment(lowerRange).subtract(1, 'months'), { ...commonPaginationOptions, preload: 0, } ); calendar.__currentPage -= 1; return this.prevPromise; }; } if(monthlyTimeSlotPreloadSize > 0) { if(_.isUndefined(preload)) { response.nextPage(monthlyTimeSlotPreloadSize - 1); } else if(preload > 0) { response.nextPage(--preload); } else { calendar.__preloading = false; } } calendar.__preloadedPages += 1; calendar.__lastPreloadedPage = response; return response; }); return currentPromise; };