Friday, January 7, 2022

#895 OIC --> Oracle Hospitality from Reservation to Check In - Part II

 


Part II covers the CheckIn process - previously, we got so far as the reservation - ending up with a reservationId. Now, from my extensive experience as SPG Titanium guest, I know that the next steps are provide payment method e.g. my credit card and then get a room assigned to me. That's what happens when I arrive at the hotel.

So how do we achieve this thru the api?


Assign Payment Method to Reservation



 












AddPaymentMethod is configured as follows - 


This, again, based on the OHIP Postman collection - 



Assign Room to Reservation

let's look at what happens when one checks in at the front desk. I gave the staff member my credit card and then I get a room assigned. The latter involves the person checking which rooms are available in my booking class and then assigning one of these to me. So how can we achieve such with the OHIP apis?

























GetAvailableRooms4Guest is configured as follows - 



/fof/ refers to Front Office.

The Response is copied from the OHIP Postman Collection - 

























The integration response returns the room numbers (roomId). All I need to do now is pick a room number and use it in the following integration - 

























AddRoom2Reservation is configured as follows - 






CheckIn the Guest

Yes, we're finally there - 

























Checkin configured as follows - 




Granted I could have included all of this orchestration in one integration, but I broke it down, just for clarity. Now let's look at testing all of this. 

One thing to note, it may seem very obvious, but you can only checking on the day of arrival. Opera Cloud refers to the current date aa the "business" date. There is an OHIP api available to retrieve the current business date - 



As you can see, my environment is somewhat behind the times - 



So let's test the whole process, beginning with the initial check for room availability - 





I think I'll take a Superior room. 

Next Step - CreateReservation

























Note the ReservationId 63400.

Note a profile has also been created for the guest - 



Next step - AddPaymentMethod to reservation - 


























Now to assigning a room to the reservation - 
Remember, here I'm looking for 

HotelRoomStatus = Inspected and FrontOfficeStatus = Vacant.



Room 307 is free - Inspected and Vacant.


























Here is the roomAssignment - 























Final step - Check In - 



















Only problem is today is not the arrival date - 

Here we see the error surfaced in OIC - 


Let's catch the error and return a more business like error message - 

























More in Part III

Thursday, January 6, 2022

#894 OIC --> Oracle Hospitality from Reservation to Check In - Part I




 I am starting the new working year with a more in-depth look at the Oracle hospitality Integration Platform (OHIP) apis. I begin by looking at the whole reservation process - this post, the first of 2 - will cover steps 1 and 2.

1. Initial inquiry to check for room availability

2. Room Reservation

3. Pre-checkin steps 

3.1. Assign Payment Method to reservation

3.2. Assign room to reservation

4. Checkin

The goal here is to look in detail at the steps involved and the individual api calls, also, how it all hangs together to provide the business solution. Room reservation, for example, includes the creation of guest profiles.  


Initial inquiry to check for room availability

Here I create an integration that leverages the Oracle Hospitality adapter to invoke the following OHIP api - /par/v0/hotels/{HotelId}/availability - par refers to Price Availability and Revenue Services.



The request parameters are listed in the OHIP portal -


 There are a plethora of parameters available including startDate, endDate, number of guests (adults/children), number of rooms required, whether points can be used etc. 

One of the parameters is includeClosedRates - this refers to the following Opera functionality - room type DBL is Closed for Arrival from 08-23-22  to 09- 23-22. Apparently certain Opera users can override this unavailability.

Back to my settings -







limit, limits the number of results returned. I set this to 20 for test purposes only. limit is mandatory.
ratePlanCode, in my case, can be one of the following values - 


 

















The OHIP Postman package includes LOV apis you can use the retrieve these values - You could, of course, put these in an OIC Lookup to save the extra invoke.


























The structure of the response I receive from the /availability invoke in OIC is as follows - 


























As you can see, I have different rates for room types - e.g. 2 rates for ECO rooms - each with a different rate plan code. Daily Best Available Rate is $100, while the Corporate rate is $75.


























So now, if you are exposing this api via OIC, what sort of a response structure should you be returning? This can be made more complicated by the fact you may have different rates for the various nights of the stay.



We are also missing the actual hotel name - this can be retrieved as follows - 


























This can be added to an OIC Lookup, to avoid the extra invoke. Also what about the room types? I can create an OIC Lookup to handle these.













I also create a Lookup for the Rate Plan Codes - 











Naturally, I could have combined these 2 lookups into one, but have kept them apart for readability purposes.

Here is an XSD representation of the integration response - 


I just need to JSONise this.

Here's what I end up with - 
{
  "hotelAvailability" : [ {
    "roomAvailability" : [ {
      "roomRates" : [ {
        "rates" : {
          "rate" : [ {
            "effectiveRate" : {
              "amountBeforeTax" : 75,
              "currencyCode" : "USD"
            },
            "start" : "2022-02-01",
            "end" : "2022-02-01"
          } ]
        },
        "roomType" : "ECO",
        "roomDescription" : "Economy",
        "ratePlanCode" : "CORP",
        "ratePlanCodeDescription" : "CORPORATE RATE",
        "start" : "2022-02-01",
        "end" : "2022-02-01",
        "numberOfUnits" : 1,
        "marketCode" : "LEISURE"
      }, {
        "rates" : {
          "rate" : [ {
            "effectiveRate" : {
              "amountBeforeTax" : 75,
              "currencyCode" : "USD"
            },
            "start" : "2022-02-01",
            "end" : "2022-02-01"
          } ]
        },
        "roomType" : "KING",
        "roomDescription" : "Economy",
        "ratePlanCode" : "CORP",
        "ratePlanCodeDescription" : "CORP",
        "start" : "2022-02-01",
        "end" : "2022-02-01",
        "numberOfUnits" : 1,
        "marketCode" : "LEISURE"
      }, {
        "rates" : {
          "rate" : [ {
            "effectiveRate" : {
              "amountBeforeTax" : 600,
              "currencyCode" : "USD"
            },
            "start" : "2022-02-01",
            "end" : "2022-02-01"
          } ]
        },
        "roomType" : "SUI",
        "roomDescription" : "Economy",
        "ratePlanCode" : "RACK",
        "ratePlanCodeDescription" : "CORP",
        "start" : "2022-02-01",
        "end" : "2022-02-01",
        "marketCode" : "LEISURE",
        "numberOfUnits" : 1
      }, {
        "rates" : {
          "rate" : [ {
            "effectiveRate" : {
              "amountBeforeTax" : 2500,
              "currencyCode" : "USD"
            },
            "start" : "2022-02-01",
            "end" : "2022-02-01"
          } ]
        },
        "roomType" : "ROYAL",
        "roomDescription" : "Economy",
        "ratePlanCode" : "RACK-VAT",
        "ratePlanCodeDescription" : "CORP",
        "start" : "2022-02-01",
        "end" : "2022-02-01",
        "marketCode" : "LEISURE",
        "numberOfUnits" : 1
      } ]
    } ],
    "hotelId" : "SAND04",
    "hotelName" : "Commiskey Towers",
    "start" : "2022-02-01",
    "end" : "2022-02-01",
    "numberOfUnits" : 1,
    "numberOfAdults" : 1,
    "numberOfChildren" : 0
  } ]
}

The final integration flow is as follows - 














Room Reservation

The request body for the OHIP reservation api has many fields - here is an example from the OHIP Postman collection - 





Quite a lot of data here - however, the Postman collection also includes a minimal version of this - 






Ok, that's a somewhat smaller payload. Still quite a bit of stuff though! Let's go thru it quickly - 

sourceType -  allowed values include - PMS (Property Management System) or CRO (Central Reservations Office)

sourceCode - defaults to the HotelId

The next section is roomStay which includes room rates - the price of the room etc. The other fields are self explanatory - the reservationGuests section includes the guest details. As you an see, these are included in a {profile} section. It is a good idea to check whether a profile already exists for the guest, if not, create it. Then the profile id is all that one needs to provide in the reservation request payload. 

That's what I'll do in the implementation of my integration. The integration request payload is as follows - 


























First step will be to check if a profile already exists for the prospective guest. I use the following api call - {{HostName}}/crm/v0/profiles?profileName=Commiskey&communication=niallc@commiskey.com


I create a scope for Profile processing - 







Check4Profile configuration - 




The Response payload is simply copied and pasted from the OHIP Postman collection - 






Note the profileIdList, which contains the profile id.
The SWITCH logic is simple - check whether the {total} returned is > 0. If so, copy the profileId to a flow variable for later use. If not, create a new profile. 

CreateGuestProfile configuration - 


 
The request / response payloads for this api call are copied from the OHIP Postman collection - 



Reservation creation is the final step in this integration - 




Note the reservationId returned.