> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Creating Bookings Resources Using Velo ## Article: Creating Bookings Resources using Velo ## Article Link: https://dev.wix.com/docs/develop-websites/articles/code-tutorials/wix-bookings/creating-bookings-resources-using-velo.md ## Article Content: # 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**](https://www.wix.com/my-account/site-selector/?buttonText=Select%20Site&title=Select%20a%20Site&autoSelectOnSingleSite=true&actionUrl=https:%2F%2Fwww.wix.com%2Fdashboard%2F%7B%7BmetaSiteId%7D%7D%2Fbookings/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](https://www.wix.com/my-account/site-selector/?buttonText=Select%20Site&title=Select%20a%20Site&autoSelectOnSingleSite=true&actionUrl=https:%2F%2Fwww.wix.com%2Fdashboard%2F%7B%7BmetaSiteId%7D%7D%2Fbookings/scheduler/owner/calendar-settings). 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: ```json { "_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: ```json { "_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](https://support.wix.com/en/article/studio-editor-adding-apps) (Wix Studio) or [here](https://support.wix.com/en/article/adding-an-app-to-your-site) (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.web.js" that we will create. ```javascript import { createStaffWithBusinessHours } from 'backend/resources.web' 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.web.js 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](https://www.wix.com/my-account/site-selector/?buttonText=Select%20Site&title=Select%20a%20Site&autoSelectOnSingleSite=true&actionUrl=https://www.wix.com/dashboard/{{metaSiteId}}/bookings/scheduler/owner/bookings-options/calendar-settings). 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. ```javascript import { Permissions, webMethod } from "wix-web-module"; import { resources } from "wix-bookings-backend"; // Get the business resource's schedule that contains the business's appointment hours. export const getBusinessSchedule = webMethod(Permissions.Anyone, () => { return resources .queryResourceCatalog() .eq("slugs.name", "business") .find() .then((results) => { const businessResource = results.items[0].resource; const businessResourceScheduleId = businessResource.scheduleIds[0]; return businessResourceScheduleId; }); }); // Get the schedule ID for the business resource. export const createStaffWithBusinessHours = webMethod(Permissions.Anyone, async (staffInfo) => { 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 `Permissions` enum and `webMethod` function from `wix-web-module`. **Line 2:** Import the resource APIs from the `wix-bookings-backend module`. **Line 7:** Using `queryResourceCatalog` get the resource where the slugs name is "business". **Line 11:** 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 12:** From the resource, take the first ID in the `scheduleIds` array. **Line 13:** Return the schedule ID to the calling function. **Create the resource** **Line 19:** Call `getBusinessSchedule()` to get the schedule ID for the business's appointment hours. **Line 22:** 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 30:** Set the date for this schedule to start, in this case immediately. **Line 34:** Create the `resourceInfo` object using the values from the front-end form, and adding the tag `"staff"` to the `tags` array. **Line 42:** 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 45:** Call `createResource` using the `resourceInfo`, `scheduleInfo` and `options` objects. **Line 47:** If the promise resolves, return the created resource to the front end. **Line 50:** If the promise is rejected, log the error to the console, and return it to the front end. [See if it worked](https://support.wix.com/en/#check-that-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](https://www.wix.com/velo/reference/wix-bookings-backend/sessions/introduction) is a defined period of time on a schedule and is one of the following: * `"EVENT"`: Reserved period of time on any [schedule](https://www.wix.com/velo/reference/wix-bookings-backend/sessions/introduction#wix-bookings-backend_sessions_introduction_schedules). For example, an appointment, class, or course. Events are visible in the Dashboard on the Bookings app's [**Booking Calendar**](https://support.wix.com/en/article/wix-bookings-about-the-wix-bookings-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. ```javascript import { Permissions, webMethod } from "wix-web-module"; import { resources, sessions } from "wix-bookings-backend"; // A function that creates a resource and adds recurring sessions to its schedule. export const createStaffWithCustomHours = webMethod(Permissions.Anyone, async (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 `Permissions` enum and `webMethod` function from `wix-web-module`. **Line 2:** Import both resources and sessions from `wix-bookings-backend module`. **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 8:** 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. ```javascript // A function that creates staff resources with no linkedShedules in its schedule. export const createStaffMember = webMethod(Permissions.Anyone, async (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. ```javascript // A function that creates recurring sessions for a given schedule ID. export const createRecurringSessions = webMethod(Permissions.Anyone, async (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(sessionInfo, 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 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](https://www.wix.com/my-account/site-selector/?buttonText=Select%20Site&title=Select%20a%20Site&autoSelectOnSingleSite=true&actionUrl=https:%2F%2Fwww.wix.com%2Fdashboard%2F%7B%7BmetaSiteId%7D%7D%2Fbookings/staff) page of the Bookings app in your site's dashboard. You can also use the [queyResourceCatalog()](https://www.wix.com/velo/reference/wix-bookings-backend/resources/queryresourcecatalog) and use the resourceId or the resource's scheduleId in [querySessions().](https://www.wix.com/velo/reference/wix-bookings-backend/sessions/querysessions) The Staff page in the dashboard.  