For each dimension that a reservation can be related to (through either a lookup or a junction), this class supports two approaches:
Simple - The exact related record(s) are already known. So for example the resource lookup has already been populated with the id of room one.
Complex - The exact related record(s) still need to be selected after this method has been called. So for example we have a pool of resources (let’s say all rooms in building one), for which we want to know all the possible time slots, so the user (or other process) can select which resource and/or time slot is best suited.
Example use cases for lookups
Simple use case
The reservation I want to make has to be in room one, with staff Alex. I pass this reservation to the method, with the resource and staff lookups populated. The method result gives me a simple list of time slots when both the room and the staff are available.
Complex use case
The reservation I want to make has to be in building one (so in any of the rooms there), with any of the staff that work at building one. I pass the reservation to the method, without the resource and staff lookups populated. I separately pass the allowed room ids and staff ids. The method result gives me a more complex list of time slots, each with all the possible room and staff combinations available at that time.
We have some handy utilities for finding the ids to pass to this method!
To get all the room ids in a specific building, use the DimensionHierarchy global class.
To get all the staff that work in building one (defined through availability records), use the MdaLinkedDimensions global class.
Example use cases for junctions
Simple use case
The reservation I want to make has to have two reservation contacts: John and Alex. I pass this reservation to the method, with two reservation contact records (one for John, one for Alex) in the separate junctions property. The method result gives me a simple list of time slots when both John and Alex are available.
Complex use case
The reservation I want to make has to have two participants (reservation contacts) out of five possible participants. I pass five reservation contact records (one for each possible participant) in the junctions property. In the requestedNumberOfJunctions property, I specify that I need two reservation contacts to be available. The method result gives me a complex list of time slots, each with all the possible combinations of participants available at that time.
Methods
Inner Classes
Example
Simple use case
This example shows the simple use case (both for lookups and junctions).
B25.TimeSlotFinder.Context context = new B25.TimeSlotFinder.Context(); // set the reservation to find time slots for context.reservation = new B25__Reservation__c( // make sure to populate all fields that are relevant for conflict checking // and link this reservation to all dimensions that need to be available B25__Resource__c = someResourceId // note that start and end times are not necessary ); // if you need any junctions to be available, map them by relationship name context.junctions = new Map<String, List<SObject>>{ 'B25__Reservation_Contacts__r' => new List<SObject>{ new B25__ReservationContact__c( B25__Contact__c = someContactId // note that a reservation id is not necessary ) } }; // the time slot context defines what the resulting series of slots should look like context.timeSlotContext = new B25.TimeSlotGenerator.Context(); context.timeSlotContext.startOfRange = System.now(); context.timeSlotContext.endOfRange = System.now().addDays(7); context.timeSlotContext.duration = 60; context.timeSlotContext.interval = 15; // call the method and do something with the result B25.TimeSlotFinder.Result result = B25.TimeSlotFinder.findTimeSlots(context); for (B25.TimeSlot timeSlot : result.timeSlots) { System.debug('available time slot from ' + timeSlot.startDatetime + ' until ' + timeSlot.endDatetime); }
Complex use case
This example shows the complex use case for lookups:
B25.TimeSlotFinder.Context context = new B25.TimeSlotFinder.Context(); // the time slot context defines what the resulting series of slots should look like context.timeSlotContext = new B25.TimeSlotGenerator.Context(); context.timeSlotContext.startOfRange = System.now(); context.timeSlotContext.endOfRange = System.now().addHours(2); context.timeSlotContext.duration = 60; context.timeSlotContext.interval = 15; // specify all the potential resource ids // NOTE: replace these with resource ids that exist in your org! context.fieldIds = new Map<String, List<Id>>{ 'B25__Resource__c' => new List<Id>{'a0eJX000000hnL7YAI', 'a0eJX000000hnL8YAI'} }; // call the method and do something with the result B25.TimeSlotFinder.Result result = B25.TimeSlotFinder.findTimeSlots(context); for (B25.TimeSlot timeSlot : result.timeSlots) { System.debug('available time slot from ' + timeSlot.startDatetime + ' until ' + timeSlot.endDatetime); B25.TimeSlotWithReservations timeSlotWithReservations = (B25.TimeSlotWithReservations) timeSlot; System.debug(timeSlotWithReservations.reservations); }