Creating Bookings Resources using Velo

In Wix Bookings, resources are anything you need to provide a service. It can be a staff member, a room, or a piece of equipment.

This tutorial focuses on creating staff resources, but apart from the “staff” tag, there is very little difference between types of resources. For the first part of this tutorial, we’ll create a staff resource with availability during the business's appointment hours. In the second part, we’ll create a staff resource with its own set of available hours. The available hours for a resource are the hours during which they can be booked for a service.

A resource is a simple object that has an ID, basic contact details, its schedule ID and a tags array.

You can use the tags array for grouping resource types. The Bookings app uses the tag "staff" to mark the resource as a staff member. This will make it show up in the Staff section of the Bookings app in the dashboard. The Bookings app creates a special resource with "business" in the tag and name properties. This special resource has a schedule that defines the business's appointment hours. Use the business resource's schedule to set up a staff or other resource's available hours to match the business's appointment hours.

A resource object looks like this:

Copy Code
{
"_id": "6235c808-c3c6-49f2-a000-bc8eded9f106",
"name": "John Doe",
"email": "john@doe.com",
"phone": "555 4567",
"description": "Fitness Instructor",
"tags": [
"staff"
],
"scheduleIds": [
"a5d20a3a-eb25-497a-9fc1-f546ac8422fc"
],
"status": "CREATED"
}

Resources have schedules, which define when the resource is available. A basic resource schedule looks like this:

Copy Code
{
"_id": "a5d20a3a-eb25-497a-9fc1-f546ac8422fc",
"scheduleOwnerId": "6235c808-c3c6-49f2-a000-bc8eded9f106"
"availability": {
"linkedSchedules": [
"scheduleId": "48ed1477-443b-40f4-bd71-7a04e863cafd"
],
"start": "Mon May 01 2021 09:00:00"
},
}
  • _id is the unique schedule ID.
  • scheduleOwnerID is the ID of the entity that owns the schedule, in this case a resource.
  • The availability object has the start time from which the schedule begins, and an array of linked schedules.
  • The linkedSchedules array contains a list of other schedules that add to this schedule’s availability. In this case we have the business's appointment hours that are stored in the bookings app as a schedule. By linking the business's appointment hours schedule to this resource’s schedule we are making the resource available during the business's appointment hours.

Not all schedules have linked schedules. You can define custom hours for a resource by creating sessions. More on sessions later.

Install the Bookings App

Before you try the code below, make sure to install the Bookings app if you haven't already. You can learn more about installing apps here (Wix Studio) or here (Wix Editor).

Creating a Staff Resource that uses the Business's Appointment Hours

To create a staff resource that uses the business's appointment hours, we need to collect the following information:

  • The resource’s name, email, and phone number.
  • The business schedule ID.

For resource details, let's assume that we have a page containing a form. The form has fields for resource name, email, phone number, and a brief description.

The form also has  a submit button that calls our backend function to create a resource, and passes the form details in an object.

The following frontend page code collects the input data from the form when the submit button is clicked and calls the createStaffWithBusinessHours function defined in the backend file "resources.jsw" that we will create.

Copy Code
import { createStaffWithBusinessHours } from 'backend/resources'
export function buttonSubmit_click(event) {
const resourceInfo = {
name: $w('#inputName').value,
email: $w('#inputEmail').value,
phone: $w('#inputPhone').value,
description: $w('#textBoxDescription').value
}
createStaffWithBusinessHours(resourceInfo)
.then((resource) => {
console.log("Resource:", resource);
})
.catch((error) => {
console.error("Failed to create the resource:", error)
});
}

Create a file called resources.jsw in the backend file section of your site.  This file will contain all of the backend code used in this tutorial.

The code below has 2 functions:

  • Get the business resource's schedule ID. 
  • Create the resource.

The business's scheduleId is the ID of the schedule that contains the business's appointment hours. These hours can be set in the dashboard under Settings, Bookings, Appointment Hours.  

To create a resource that uses the business's appointment hours, add the business resource's  scheduleId to the linkedSchedules array of the new resource's schedule.

Copy Code
import { resources } from "wix-bookings-backend";
// Get the business resource's schedule that contains the business's appointment hours.
export function getBusinessSchedule() {
return resources.queryResourceCatalog()
.eq("slugs.name", "business")
.find()
.then((results) => {
const businessResource = results.items[0].resource;
const businessResourceScheduleId = businessResource.scheduleIds[0];
return businessResourceScheduleId;
});
}
export async function createStaffWithBusinessHours(staffInfo) {
// Get the schedule ID for the business resource.
const businessResourceScheduleId = await getBusinessSchedule();
// Add the business schedule ID to the linkedSchedules array.
const scheduleInfo = [{
availability: {
linkedSchedules: [{
scheduleId: businessResourceScheduleId
}, ],
start: new Date(),
}
}];
const resourceInfo = {
name: staffInfo.name,
email: staffInfo.email,
phone: staffInfo.phone,
description: staffInfo.description,
tags: ['staff'],
};
const options = { suppressAuth: true }
// Create the resource and return the result.
return resources.createResource(resourceInfo, scheduleInfo, options)
.then((resource) => {
return resource;
})
.catch((error) => {
console.error('Failed to create resource: ', error);
return error;
});
}

Understanding the code.

Get the business resource's schedule ID.

Line 1: Import the resource APIs from the wix-bookings-backend module.
Line 5: Using queryResourceCatalog get the resource where the slugs name is "business".
Line 9: The query returns an array of items, each item containing a resource, schedule and slug object. We want the resource object from the first and only item in the array.
Line 10: From the resource, take the first ID in the scheduleIds array.
Line 11: Return the schedule ID to the calling function.

Create the resource

Line 17: Call getBusinessSchedule() to get the schedule ID for the business's appointment hours.
Line 20: Create the scheduleInfo object using the business schedule ID in the linkedSchedules array. This gives the resource the same available hours as defined for the business.
Line 25: Set the date for this schedule to start, in this case immediately.
Line 28: Create the resourceInfo object using the values from the front-end form, and adding the tag "staff" to the tags array.
Line 36: Configure the options object to set supressAuth to true. This will suppress the checking of user permissions and let anyone execute the createResource function.
Line 39: Call createResource using the resourceInfo, scheduleInfo and options objects.
Line 40: If the promise resolves, return the created resource to the front end.
Line 43: If the promise is rejected, log the error to the console, and return it to the front end.

See if it worked by looking at your site's dashboard.

Creating a Resource with Custom Hours

In this part of the tutorial, we will create a resource that has its own custom working hours. We will make the resource  available on Mondays, Wednesdays, and Fridays between 10 AM and 4 PM. 

To create resource with its own custom hours, we need to do the following:

  1. Create a resource and its schedule.
  2. Add sessions to the resource's schedule to define its availability.

A session is a defined period of time on a schedule and is one of the following:

  • "EVENT": Reserved period of time on any schedule. For example, an appointment, class, or course. Events are visible in the Dashboard on the Bookings app's Booking Calendar page.
  • "WORKING_HOURS" : Placeholder for available time on a resource’s schedule.

In this tutorial we will create "WORKING_HOURS" sessions to define the resource's availability.

A session can be an individual session or a recurring session. An individual session has a discrete start and end date, while a recurring session defines a series of repeating sessions. In this tutorial, when adding the sessions to the schedule, we will create recurring sessions using recurrence rules to specify how often each session repeats.

Create a function to manage the process.

First we need a function that will manage the process for us. This function will call the createStaffMember function to create the resource, then use the new resource's scheduleId to add sessions to the schedule.

Copy Code
import { resources, sessions } from "wix-bookings-backend";
// A function that creates a resource and adds recurring sessions to its schedule.
export async function createStaffWithCustomHours(staffInfo) {
// Create a resource with no linked schedules.
try {
var resource = await createStaffMember(staffInfo)
} catch (error) {
console.error("Failed to create a resource", error);
return error;
}
// Using the schedule ID of the resource created above, create recurring sessions.
return createRecurringSessions(resource.scheduleIds[0])
.then((sessions) => {
//create an object with the resource and a list of sessions.
const resourceSessions = {
resource: resource,
sessions: sessions
}
return resourceSessions;
})
.catch((error) => {
console.error("Failed to create a session", error);
return error;
})
}

Understanding the code.

Line 1: Import both resources and sessions from, wix-bookings-backend.
Line 5: createStaffWithCustomHours takes staff information from the page form, and creates a resource. It then uses the new resource’s scheduleId to create recurring sessions.
Line 9: Call createStaffMember to create a new resource. Note that the resource variable is defined with var so that it is visible outside the try/catch scope.
Line 16: Call createRecurringSessions using the resource’s scheduleId.
Line 19: Create resourceSessions as a return object consisting of the resource and an array of its sessions.
Line 23: Return the resourceSessions object to the front end.

Create the resource

Creating the resource is the same as creating a resource with the business's appointment hours, but in this case we leave out the business schedule from the linkedSchedules array in the scheduleInfo object.

Copy Code
// A function that creates staff resources with no linkedShedules in its schedule.
export async function createStaffMember(staffInfo) {
// Create resource information with a "staff" tag.
const resourceInfo = {
name: staffInfo.name,
email: staffInfo.email,
phone: staffInfo.phone,
description: staffInfo.description,
tags: ['staff'],
};
// Schedule information with no linked schedules.
const scheduleInfo = [{
availability: {
linkedSchedules: [],
start: new Date(),
}
}];
// Set the option to suppress permissions checking.
const options = { suppressAuth: true }
// Create the resource and return it to the calling function.
return resources.createResource(resourceInfo, scheduleInfo, options)
.then((resource) => {
return resource;
})
.catch((error) => {
console.error('Failed to create resource: ', error);
return error;
});
}

Understanding the code.

Line 5: Create the resourceInfo object using the values from the front-end form, adding the tag "staff" to the tags array.
Line 14: Create the scheduleInfo object with an empty linkedSchedules array and the current date and time for the start date.
Line 22: Configure the options object to set supressAuth to true. This will suppress the checking of user permissions and let anyone execute the createResource function.
Line 25: Call createResource using the resourceInfo, scheduleInfo and options objects and return the result to the calling function.

Create recurring sessions.

Now that we have a resource and its schedule, we can add sessions to the schedule. 

We are going to add recurring sessions that occur on Mondays Wednesdays and Fridays between 10 AM and 4 PM.

The recurrence rule for this as follows:

'FREQ=WEEKLY;INTERVAL=1;BYDAY=MO;UNTIL=20220101T000000Z'

  • FREQ=WEEKLY: Repeat the sessions on a weekly basis
  • INTERVAL=1: Repeat the sessions every week. If you want to repeat every second week, set the interval to "2"
  • BYDAY=MO: The session occurs on Mondays.
  • UNTIL=20220101T000000Z: Repeat the sessions until midnight, January 1 2021

We will have 3 recurrence rules. One for Monday, BYDAY=MO, one for Wednesday, BYDAY=WE, and one for Friday, BYDAY=FR.

The session type is set to 'WORKING_HOURS' to tell the bookings backend that these sessions set the resource’s availability.

Copy Code
// A function that creates recurring sessions for a given schedule ID.
export async function createRecurringSessions(resourceScheduleId) {
// Set the option to suppress permissions checking.
const options = { suppressAuth: true }
// Create the recurring session object, leaving the recurrence rule to be populated later.
let sessionInfo = {
scheduleId: resourceScheduleId,
start: {
localDateTime: {
year: 2021,
monthOfYear: 5,
dayOfMonth: 1,
hourOfDay: 10,
minutesOfHour: 0
}
},
end: {
localDateTime: {
year: 2021,
monthOfYear: 5,
dayOfMonth: 1,
hourOfDay: 16,
minutesOfHour: 0
}
},
// Set the session type to "WORKING_HOURS" to define the session as a resource availability session.
type: 'WORKING_HOURS',
recurrence: 'recurrence rule placeholder'
};
let resourceSessions = [];
try {
// Populate the recurrence rule in the recurringSession object for Monday, Wednesday, and Friday, then call createSession for each rule.
// Add each session the resourceSessions array
sessionInfo.recurrence = 'FREQ=WEEKLY;INTERVAL=1;BYDAY=MO;UNTIL=20220101T000000Z';
resourceSessions.push(await sessions.createSession(sessionInfo, options))
sessionInfo.recurrence = 'FREQ=WEEKLY;INTERVAL=1;BYDAY=WE;UNTIL=20220101T000000Z';
resourceSessions.push(await sessions.createSession(sessionInfo, options))
sessionInfo.recurrence = 'FREQ=WEEKLY;INTERVAL=1;BYDAY=FR;UNTIL=20220101T000000Z';
resourceSessions.push(await sessions.createSession(sessionInfoC, options))
return resourceSessions
} catch (error) {
console.error("Failed to create a session", error);
return error;
}
}

Understanding the code.

Line 8: Create the sessionInfo object using the scheduleId from the resource we created earlier.
Lines 10 and 19: Set the duration of the session by setting the start.locatDateTime and end.localDateTime properties.
Line 29: Set the session type to ”WORKING_HOURS”. This tells the bookings app that these sessions set the resource’s availability.
Line 30: Define the recurrence rule as a placeholder. We will populate this property with a set of recurrence rules.
Line 33: Declare an array to hold the sessions that we are going to create.
Line 37: Set the the recurrence rule for the first recurring session to 'FREQ=WEEKLY;INTERVAL=1;BYDAY=MO;UNTIL=20220101T000000Z'
The rule defines sessions that will recur on a weekly basis, on a Monday, repeating until midnight, January 1, 2021.
Line 38: Call createSession with the sessionInfo and options objects, storing the result in the resourceSessions array that we created earlier.
Lines 40 to 44: Repeat the session creation, changing the recurrence rule each time to repeat on Wednesdays, then Fridays.
Line 46: Return the resourceSessions array, containing three recurring sessions, to the createStaffWithCustomHours function.

Check that it worked.

How do we check that this worked ? The easiest way is to go to the Staff page of the Bookings app in your site's dashboard.

You can also use the queyResourceCatalog() and use the resourceId  or the resource's scheduleId in querySessions().

The Staff page in the dashboard.

Hover over a staff member and hit edit to see their available hours.

Click Edit Staff Availability. You can see if the staff member uses default or custom appointment hours. 

Was this helpful?
Yes
No