1 Room Reservation to Calendar Tool 2.0 Shared by Sharee Bryant, Colorado Community Church 15 days ago 15.0 Event Intermediate This recipe requires the Room Management plugin from the Rock Shop. This recipe is LARGELY based on Luke Bennett's original recipe. "If you use the Room Management plugin in Rock, your admin team is probably (mildly?) annoyed with the fact that the plugin doesn't sync to the event calendar when edits are made to the schedule, you have to remember to make the change in two places. Not fun, and things can quickly get out of sync. This recipe aims to streamline that process by providing a set of tools to help keep your room reservations and calendar in sync." I updated the original recipe to work with the built in room management event linkage feature that has been implemented in plugin updates. This recipe will put a visual alert on the room reservation page so that your staff can see if there is a conflict with the linked calendar event or if there is no event linked at all. You can also sync the room reservation information to the calendar event using a workflow and/or create a new event at the push of a button. Here's how it works: Use the native Room Reservation Linkage to notate if a linkage exists between the Room Reservation and Calendar event, and notate if the schedules match between those items. Create a workflow to sync Room Reservation information to the linked Calendar Event. Add buttons to the Room Reservation page to trigger the "change" workflow, create a new calendar event, or create a linkage to an existing calendar event. Step 1 - Create the "Change" Workflow: Import the attached workflow to push Reservation changes to the Calendar. The workflow includes options to push changes for the schedule, location, and/or contact person. We only use the schedule option, but I have left the other parts available for you to use if you want. You should not need to make any changes to the workflow, but please note the workflow type Id for use in a future step. Step 2 - Add the Details PanelThe goal of this step is to add an HTML block to the Room Reservation Detail page to indicate whether a reservation linkage is missing or out of sync with the Rock calendar. The buttons on this block will trigger the workflow you created in step 1. Go to the Room Reservation Details page. (Visit the Room Reservation page and click on any reservation to see its details). Add a new HTML block to the main zone between the Reservation Detail block and the Reservation Tabs. I called mine "Reservation Changes." Edit the Block Properties and select both Rock Entity and Sql in the Enabled Lava Commands section. Paste the following into the HTML block. With the following changes: a. Change the "assign changeWorkflowId = 676" in the first line to the workflow type Id you created in step 1. b. Verify your Event Occurrence Page. This is page 402 for us and 402 from the original recipe, but verify this is the same in your instance. (Around line 58 in the code.) c. You will need to change the URL link for the "Create" button near lines 20 and 90 in the code. The easiest way to find the correct link is to navigate to the reservation detail page and select the "Event Tab" at the bottom of the page. Click the "+" button and copy the link for the new page that opens. Format the link as: https://rock.yourdomain.org/page/796?LinkageId=0&ReservationId={{reservation.Id}} swapping out the "yourdomain.org" and "796" to the details from your link. After setting the URL, clicking the create button will use the native linkage feature from the Room Reservation Plugin. However, it does need to be configured for the plugin. You can choose a default calendar, whether to allow creating of new events, or just linking to existing events. You can find information about that process from Bema's documentation HERE. {% assign changeWorkflowId = 676 %} <!-- Enter your workflow type Id from Step 1 here -->{% if Context.Reservation %}<div class="panel panel-default" style="margin-bottom: 25px;"><div class="panel-heading"> <h3 class="panel-title">Calendar Occurrence</h3> </div> <div class="panel-body"> {% assign reservation = Context.Reservation %} {% sql %} SELECT EventItemOccurrenceId FROM [_com_bemaservices_RoomManagement_ReservationLinkage] WHERE ReservationId = {{ reservation.Id }} {% endsql %} {% assign calendarId = results[0].EventItemOccurrenceId %} {% if calendarId == null or calendarId == "" %} <div class="alert alert-warning">There is no linked calendar event for this item</div> <!-- Enter your URL link here for the CREATE button --> <a class="btn btn-default btn-primary pull-right" href="https://rock.yourdomain.org/page/796?LinkageId=0&ReservationId={{reservation.Id}}">Create</a> {% else %} {% eventitemoccurrence id:'{{calendarId}}' %} {% if eventitemoccurrence %} {% assign calendarScheduleText = eventitemoccurrence.Schedule.FriendlyScheduleText %} {% assign iCalUid = eventitemoccurrence.Schedule.iCalendarContent | RegExMatchValue:'UID:\\S*' %} {% assign iCalDTStamp = eventitemoccurrence.Schedule.iCalendarContent | RegExMatchValue:'DTSTAMP:\\S*' %} {% assign calendarTrimmedIcal = eventitemoccurrence.Schedule.iCalendarContent | Remove:iCalUid | Remove:iCalDTStamp %} {% assign iCalUid = reservation.Schedule.iCalendarContent | RegExMatchValue:'UID:\\S*' %} {% assign iCalDTStamp = reservation.Schedule.iCalendarContent | RegExMatchValue:'DTSTAMP:\\S*' %} {% assign reservationTrimmedIcal = reservation.Schedule.iCalendarContent | Remove:iCalUid | Remove:iCalDTStamp %} {% assign locations = reservation.ReservationLocations | Select:'Location' | Select:'Name' | Join:', ' %} <!-- Schedule difference alert --> <div class="alerts" style="margin-top: 25px"> {% if calendarTrimmedIcal != reservationTrimmedIcal %} <div class="alert alert-danger">The calendar schedule for this event is different from the reservation. <a onclick="if (confirm('Are you sure you want to push the schedule to the calendar?')) { $(this).hide();$.post('/api/Workflows/WorkflowEntry/{{changeWorkflowId}}?Reservation={{reservation.Guid}}&Change=Schedule', function () { location.reload(); }); }" href="#" style="margin-left: 15px;">Push changes to Calendar</a></div> {% endif %} {% comment %} <!-- Location difference alert --> {% if locations != eventitemoccurrence.Location %} <div class="alert alert-warning">The locations on the calendar and reservation may not match. <a onclick="if (confirm('Are you sure you want to push the locations to the calendar?')) { $(this).hide();$.post('/api/Workflows/WorkflowEntry/{{changeWorkflowId}}?Reservation={{reservation.Guid}}&Change=Location', function () { location.reload(); }); }" href="#" style="margin-left: 15px;">Push changes to Calendar</a></div> {% endif %} <!-- Contact difference alert --> {% if reservation.EventContactEmail != eventitemoccurrence.ContactEmail or reservation.EventContactPhone != eventitemoccurrence.ContactPhone or reservation.EventContactPersonAliasId != eventitemoccurrence.ContactPersonAliasId %} <div class="alert alert-warning">The contact info on the calendar and reservation do not match. <a onclick="if (confirm('Are you sure you want to push the event contact to the calendar?')) { $(this).hide();$.post('/api/Workflows/WorkflowEntry/{{changeWorkflowId}}?Reservation={{reservation.Guid}}&Change=Contact', function () { location.reload(); }); }" href="#" style="margin-left: 15px;">Push changes to Calendar</a></div> {% endif %}{% endcomment %} </div> <div class="row"> <div class="col-xs-12 col-md-6"> <div class="control-label">Calendar Item:</div> <!-- Verify your Event Occurrence Page Here --> <a href="/page/402?EventItemOccurrenceId={{calendarId}}">{{ eventitemoccurrence.EventItem.Name }}</a><br> <div class="control-label" style="margin-top: 15px;">Calendar Location:</div> {{ eventitemoccurrence.Location }} </div> <div class="col-xs-12 col-md-6"> <div class="control-label" style="margin-top: 25px;">Calendar Schedule:</div> {{ calendarScheduleText }}<br> <div class="control-label" style="margin-top: 15px;">Calendar Contact:</div> {% if eventitemoccurrence.ContactPersonAliasId %} {% assign eventContact = eventitemoccurrence.ContactPersonAliasId | PersonByAliasId %} {{ eventContact.NickName }} {{ eventContact.LastName }} {% else %} No name {% endif %}<br> {% if eventitemoccurrence.ContactEmail != '' %} {{ eventitemoccurrence.ContactEmail }} {% else %} No email {% endif %}<br> {% if eventitemoccurrence.ContactPhone != '' %} {{ eventitemoccurrence.ContactPhone }} {% else %} No phone number {% endif %} </div> </div> {% else %} <div class="alert alert-warning">There is no linked calendar event for this item</div><!-- Enter your URL link here for the CREATE button --> <a class="btn btn-default btn-primary pull-right" href="https://rock.yourdomain.org/page/796?LinkageId=0&ReservationId={{reservation.Id}}">Create</a> {% endif %} {% endeventitemoccurrence %} {% endif %} </div></div>{% endif %} I also commented out the location difference and contact difference alerts, around lines 43-47. You can remove the comment tags to add these options back in if you want to use them. You should now see something like one of the pictures below on your page: When a linkage doesn't exist between the reservation and an event, clicking the create button will direct you to the native room reservation process to create a new event or link the reservation to an existing event. When the schedules don't match exactly, clicking "Push changes to Calendar" will launch the workflow we created to make the calendar event match the reservation. If the schedules match you will see the Calendar event details. Note: You may want to change the security on this block so that only Room Management Admins can see it. Otherwise, whoever can see the block will be able to make changes to your calendar. That's it! Feel free to reach out on Rocket chat if you run into any issues. Download File