C# Sample 2:
Booking an Air Reservation

This sample uses response data from the air availability request in Sample 1 to book an air reservation. Booking calls can be made through either the Reservation Builder eBL or a combination of transactions in the XML Select Web Service. In this example, the booking call is made through a call to the Reservation Builder eBL, using the  minimum data required to book an air reservation.

  1. Create a proxy of the XML Select Web Service, using a WSDL for your region or service level. For example:
    https://americas.copy-webservices.travelport.com/B2BGateway/service/ReservationBuilder?WSDL
    .

  2. Create a function, BWSController, which formats an XML template, retrieves the required data from the AirAvailability_6_5 response, and sets the parameters for the request, including a Booking Profile. The following code also contains proxy server credentials that are included with the request to bypass the firewall.

Notes:

Declares the required namespaces.

using System;

using System.Net;

Using System.XML;

 

namespace GettingStarted

   

{

Declares the BWSController class, which manages the Reservation Builder eBL request.

public class BWSController

{

 

public BWSController()

No constructor logic is required.

{

}

Selects the first air segment from a valid air availability response. Use a DOM to create the request.

public string CreateRequest(XmlElement xmlAirAvail)

 

   

{

Retrieve the required booking information from the availability.

XmlNode firstSegment = xmlAirAvail.SelectSingleNode
("AirAvail/AvailFlt[1]");

Gets the departure and arrival dates and times.

string dt = GetText(firstSegment, "StartDt");

string tm = GetText(firstSegment, "StartTm");

DateTime departDateTime = DateTime.ParseExact(dt+tm, "yyyyMMddHHmm", null);

tm = GetText(firstSegment,"EndTm");

DateTime arriveDateTime = DateTime.ParseExact(dt+tm, "yyyyMMddHHmm", null);

arriveDateTime.AddDays( double.Parse(GetText(firstSegment, "DayChg")));

Gets the flight number.

string flightNum = GetText(firstSegment, "FltNum");

Gets the departure airport.

string departAirport = GetText( firstSegment, "StartAirp");

Gets the destination airport.

string arriveAirport = GetText( firstSegment, "EndAirp");

Gets the airline vendor.

string airline = GetText(firstSegment, "AirV");

Gets tomorrow's date, then sets the Arrange Ticketing Date to the next day (TAU). The TAU typically defaults to Queue 10.

DateTime tomorrow = DateTime.Today.AddDays(1.0);

string ticketString = "TAU/" + tomorrow.ToString("ddMMM").ToUpper();

   

   

Makes a Minimal Trip request to the Reservation Builder eBL. See the Minimal Trip Sample for detailed parameters.

string req = "";

req += "<GWS_Trip";

The namespace of the schemas. ota: fields are defined by the Open Travel Alliance. The namespace is defined in the WSDL, whether ns.galileo.com or webservices.galileo.com

req += "    xmlns='http://
ns.galileo.com' xmlns:ota='http://www.opentravel.org/
OTA'";

If PaymentAuthorize is FALSE, credit card authorization is not required.

req += "    ReceivedFrom='GWSSample' Ticketing='" + ticketString + "' PaymentAuthorize='false'>\r\n";

Begins the travel request.

req += "    <InventoryItems>\r\n";

Begins the flight request.

req += "        <Flight>\r\n";

Begins the flight segment request.

req += "            <FlightSegment ";

The departure date.
The "T" value in ddTHH is a literal.

req += "DepartureDateTime='" + departDateTime.ToString("yyyy-MM-ddTHH:mm:ss-00:00") +"' ";

The arrival date.
The "T" value in ddTHH is a literal.

req += "ArrivalDateTime='" + arriveDateTime.ToString("yyyy-MM-ddTHH:mm:ss-00:00") +"' ";

The flight number.

req += "FlightNumber='" + flightNum +"' ";

 

req += ">\r\n";

The departure city.

req += "                <ota:DepartureAirport LocationCode='" + departAirport + "' />\r\n";

The arrival city.

req += "                <ota:ArrivalAirport LocationCode='" + arriveAirport + "' />\r\n";

The vendor code for the airline.

req += "                <ota:MarketingAirline Code='" + airline + "' />\r\n";

 

 

The booking class.
If the booking class is Requested, the Status element is required.  

For samples, 'Y' class is recommended, because it is typically  available for most flights.  

For actual production code, a Fare Quote would be required to find the booking code.

req += "                <BookingClass>
\r\n";

req += "                    <Requested Status='NN-Need Need' ResBookDesigCode='Y' /
>\r\n";

req += "                </BookingClass>\r\n";

Indicates the seating preferences.

A non-smoking is seat preferred.

req += "                <AirQualifiers>\r\n"

req += "                    <SeatPreference SmokingAllowed='false' />\r\n";

 req += "                </AirQualifiers>\r\n";

End of the flight segment request.

req += "            </FlightSegment>\r\n";

End of the flight request.

req += "        </Flight>\r\n";

End of the travel request.

req += "    </InventoryItems>\r\n";

End of the Reservation Builder eBL request.

req += "</GWS_Trip>\r\n";

 

 

 

XmlDocument doc = new XmlDocument();

 

doc.LoadXml(req);

 

return doc;

 

 

Finds the record locator in a Booking service response document.

public string GetRecordLocator (XmlNode bookingResponse)

{

return GetText(bookingResponse, "//g:Success/g:PnrID/g:RecordLocator", "g", "http://ns.galileo.com");

 

}

 

 

Creates a Booking Profile, which is required to book a segment. See the Profiles without TravelScreen sample.

public string BuildProfile()

{

string profile = "";

The namespace of the schemas.

profile +=
"<GWS_BookingProfile xmlns='http://ns.galileo.com' xmlns:ota='http://www.opentravel.org/
OTA' xmlns:xsi='http://www.w3.org/2001/
XMLSchema-instance' xsi:schemaLocation='http://
ns.galileo.com' >\r\n";

Personal information of the primary traveler.

 

profile +=
"    <Primary Gender='Female' BirthDate='1970-10-14' CurrencyCode='USD' PassengerIdentificationCode='' TicketingIdentificationCode='' xmlns='http://ns.galileo.com' xmlns:ota='http://www.opentravel.org/
OTA' xmlns:xsi='http://www.w3.org/2001/
XMLSchema-instance'>\r\n";

Primary traveler's name.

profile +=
"        <PersonName ShareSynchInd='Yes' ShareMarketInd='Yes' NameType='Former'>
\r\n";

profile += "            <ota:NamePrefix>MS</ota:NamePrefix>
\r\n";

profile += "            <ota:GivenName>PAM</ota:GivenName>
\r\n";

profile += "            <ota:Surname>TEST</ota:Surname>
\r\n";

profile += "        </PersonName>
\r\n";

Primary traveler's contact information.

The CityAbbr field is a reference-only field for the travel agents that is required by the CRS.

profile +=
"        <Telephone ShareSynchInd='Yes' ShareMarketInd='Yes' PhoneLocationType='Home' PhoneTechType='VOICE' CountryAccessCode='000' AreaCityCode='303' PhoneNumber='1234561' Extension='0' PIN='String' FormattedInd='false' CityAbbr='DEN'/>\r\n";

Primary traveler's address. Both the <Address> and <DeliveryAddress> elements are required, even if they are the same address.

Unneeded fields (e.g., ShareSynchInd, ShareMarketInd, FormattedInd) may be omitted.

profile +=
"        <Address FormattedInd='false' ShareSynchInd='Yes' ShareMarketInd='Yes' Type='Home' DefaultInd='false' UseType='Delivery'>\r\n";

profile +=
"            <ota:StreetNmbr PO_Box='String'>123</ota:StreetNmbr>
\r\n";

profile +=
"            <ota:AddressLine>YELLOW BRICK ROAD</ota:AddressLine>\r\n";

profile += "            <ota:CityName>GREENWOOD VILLAGE</ota:CityName>\r\n";

profile +=
"            <ota:PostalCode>80111</ota:PostalCode>
\r\n";

profile +=
"            <ota:County>DOUGLAS</ota:County>\r\n";

profile +=
"            <ota:StateProv StateCode='CO'>COLORADO</ota:StateProv>
\r\n";

profile +=
"            <ota:CountryName Code='US'>UNITED STATES OF AMERICA</ota:CountryName>\r\n";

profile += "        </Address>\r\n";

profile += "        <DeliveryAddress>\r\n";

profile += "            <ota:StreetNmbr PO_Box='String'>5350</ota:StreetNmbr>\r\n";

profile += "            <ota:AddressLine>S VALENCIA WAY</ota:AddressLine>\r\n";

profile += "            <ota:CityName>GREENWOOD VILLAGE</ota:CityName>\r\n";

profile += "            <ota:PostalCode>80111</ota:PostalCode>\r\n";

profile += "            <ota:County>DOUGLAS</ota:County>\r\n";

 profile += "            <ota:StateProv StateCode='CO'>COLORADO</ota:StateProv>\r\n";

profile += "            <ota:CountryName Code='US'>UNITED STATES OF AMERICA</ota:CountryName>\r\n";

profile += "        </DeliveryAddress>\r\n";

Credit card information that can be used to pay for travel.  

If the itinerary has at least one segment (air, car, or hotel), then your profile must have at least one form of payment.

For more information, see Form of Payment.

profile +=
"        <FormOfPayment ShareSynchInd='Yes' ShareMarketInd='Yes' CostCenterId='String'RPH='01'>\r\n";

profile +=
"            <ota:PaymentCard ShareSynchInd='Yes' ShareMarketInd='Yes' CardType='Credit' CardCode='AX-American Express' CardNumber='300000000000000' SeriesCode='0' EffectiveDate='0101' ExpireDate='1005'>
\r\n";

profile +=
"                <ota:CardHolderName>PAM TEST</ota:CardHolderName>\r\n";

profile +=
"                <ota:CardIssuerName BankId='String'/>\r\n";

profile +=
"                <ota:Address FormattedInd='false' ShareSynchInd='Yes' ShareMarketInd='Yes' Type='Home'>
\r\n";

profile += "                    <ota:StreetNmbr PO_Box='String'>123</ota:StreetNmbr>
\r\n";

profile +=
"                    <ota:AddressLine>
YELLOW BRICK ROAD</ota:AddressLine>\r\n";

profile += "                    <ota:CityName>GREENWOOD VILLAGE</ota:CityName>\r\n";

profile += "                    <ota:PostalCode>80111</ota:PostalCode>
\r\n";

profile += "                    <ota:County>DOUGLAS</ota:County>
\r\n";

profile += "                    <ota:StateProv StateCode='CO'>COLORADO</ota:
StateProv>\r\n";

profile += "                    <ota:CountryName Code='US'>UNITED STATES OF AMERICA</ota:CountryName>\r\n";

profile += "                </ota:Address>\r\n";

profile += "            </ota:PaymentCard>\r\n";

profile += "        </FormOfPayment>
\r\n";

End of the primary traveler information.

profile += "    </Primary>\r\n";

End of the profile.

profile += "</GWS_BookingProfile>
\r\n";

 

 

 

return profile;

 

}

 

 

The booking request. travelerProfile is the Booking Profile.

public XmlNode doBooking( string trip, string travelerProfile)

 

{

Creates and sets up the credentials for the Reservation Builder eBL.  User name and password are assigned by Galileo.

The Reservation Builder eBL uses Basic Authentication, however, Windows XP defaults to Digest Authentication.

gwsBooking bws = new gwsBooking();

string UserName = "UserName";

string Password = "Password";

NetworkCredential credentials = new NetworkCredential(UserName,Password);

CredentialCache cc = new CredentialCache();

cc.Add(new Uri(bws.Url), "Basic", credentials);

bws.Credentials = cc;

Sets up a WebProxy to get through the firewall, if necessary.

WebProxy wp = new WebProxy();

URL of the proxy server. Confirm that the appropriate port is included.

wp.Address = new Uri("http://yourproxy.company.com:80");

wp.BypassProxyOnLocal = true;

The User ID, password, and domain for the proxy server.

wp.Credentials = new NetworkCredential("userID","password",
"proxyDomain");

bws.Proxy = wp;

Specifies the Document (root) XML element for the request and filter. This example uses the BookTrip method.

A Host Access Profile is required to access Galileo Web Services.

XmlNode xmlResponse = bws.BookTrip("HostAccessProfile", false, travelerProfile, trip);

Returns the response data as an XML element.

return xmlResponse;

 

}

GetText is a utility class that gets the content of the node pointed to by an Xpath. Returns an empty string if there is no text or if the node does not exist.

private string GetText(XmlNode inNode,
string xPath)

{

XmlNode tempNode =
inNode.SelectSingleNode(xPath);

if (tempNode==null)

return "";

return tempNode.InnerText;

 

}

 

 

 

private string GetText(XmlNode inNode, string xPath, string prefix, string ns )

 

{

 

if (inNode==null)

 

return "";

 

XmlNamespaceManager nsmgr = new XmlNamespaceManager(inNode.OwnerDocument.NameTable);

 

nsmgr.AddNamespace(prefix, ns);

 

 

 

XmlNode tempNode = inNode.SelectSingleNode(xPath, nsmgr);

 

if (tempNode==null)

 

return "";

 

return tempNode.InnerText;

 

}

 

public string receivedFrom = "GWSSample";

 

}

 

}

 

  1. The Apollo or Galileo CRS returns the following minimum data in a response.

Booking response.

<Response Time="Wednesday, 25 September 2002 21:07:05" ServiceBuildVersion="1.0.39.0" xmlns="http://ns.galileo.com">

Information Context text fields are returned for each booked segment.

<Information Context="Selling Air">

Air segments include text responses with the departure and arrival times and locations, vendor messages, and agency-related prompts, such as offering additional travel services.

<Text>        CARRY ON CRITICAL FLIGHT *</Text>

<Text>                         ARRIVES ORD TERMINAL 1</Text>

<Text>DEN/0343CT/DPTS 1135A       OT       *</Text>

<Text>ORD/0343CT/ARVS  255P       OT       *</Text>

<Text>OFFER CAR/HOTEL    !CAL·     !CAQ·     !HOA·</Text>

 

</Information>

Information context for the stored fare quote includes rules for ticketing at the submitted fare.

<Information Context="Storing Farequote">

<Text>LAST DATE TO PURCHASE TICKET: 26SEP02</Text>

 

</Information>

The Success indicator contains the record locator for the PNR/BF.

<Success>LC97W0</Success>

 

</Response>

 

  1. In Step 3, flight information is obtained from the air availability response in Step 1.