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.




No comments: