diff --git a/package.json b/package.json
index 360ad5a3..9bf6ccc6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "uapi-json",
- "version": "0.9.3",
+ "version": "0.9.4",
"description": "Travelport Universal API",
"main": "build/",
"files": [
diff --git a/src/Services/Air/AirParser.js b/src/Services/Air/AirParser.js
index 71eb71f0..830c5e0f 100644
--- a/src/Services/Air/AirParser.js
+++ b/src/Services/Air/AirParser.js
@@ -354,10 +354,22 @@ const airGetTicket = function (obj) {
const taxes = (airPricingInfo && airPricingInfo['air:TaxInfo'])
? Object.keys(airPricingInfo['air:TaxInfo']).map(
- taxKey => ({
- type: airPricingInfo['air:TaxInfo'][taxKey].Category,
- value: airPricingInfo['air:TaxInfo'][taxKey].Amount,
- })
+ taxKey => Object.assign(
+ {
+ type: airPricingInfo['air:TaxInfo'][taxKey].Category,
+ value: airPricingInfo['air:TaxInfo'][taxKey].Amount,
+ },
+ airPricingInfo['air:TaxInfo'][taxKey][`common_${this.uapi_version}:TaxDetail`]
+ ? {
+ details: airPricingInfo['air:TaxInfo'][taxKey][`common_${this.uapi_version}:TaxDetail`].map(
+ taxDetail => ({
+ airport: taxDetail.OriginAirport,
+ value: taxDetail.Amount,
+ })
+ ),
+ }
+ : null,
+ )
)
: [];
const priceInfo = {
@@ -518,12 +530,25 @@ function extractBookings(obj) {
);
const taxesInfo = reservation['air:TaxInfo']
? Object.keys(reservation['air:TaxInfo']).map(
- taxKey => ({
- value: reservation['air:TaxInfo'][taxKey].Amount,
- type: reservation['air:TaxInfo'][taxKey].Category,
- })
+ taxKey => Object.assign(
+ {
+ value: reservation['air:TaxInfo'][taxKey].Amount,
+ type: reservation['air:TaxInfo'][taxKey].Category,
+ },
+ reservation['air:TaxInfo'][taxKey][`common_${this.uapi_version}:TaxDetail`]
+ ? {
+ details: reservation['air:TaxInfo'][taxKey][`common_${this.uapi_version}:TaxDetail`].map(
+ taxDetail => ({
+ airport: taxDetail.OriginAirport,
+ value: taxDetail.Amount,
+ })
+ ),
+ }
+ : null,
+ )
)
: [];
+
const modifierKey = reservation['air:TicketingModifiersRef']
? Object.keys(reservation['air:TicketingModifiersRef'])[0]
: null;
diff --git a/test/Air/AirParser.test.js b/test/Air/AirParser.test.js
index e68c83bb..8b3bd82e 100644
--- a/test/Air/AirParser.test.js
+++ b/test/Air/AirParser.test.js
@@ -186,7 +186,6 @@ describe('#AirParser', () => {
});
});
describe('getTicket', () => {
-
function testGetTicket(result) {
expect(result).to.be.an('object');
expect(result).to.have.all.keys([
@@ -224,6 +223,13 @@ describe('#AirParser', () => {
expect(priceInfo.taxes).to.match(/[A-Z]{3}(?:\d+\.)?\d+/i);
expect(priceInfo.taxesInfo).to.be.an('array');
expect(priceInfo.taxesInfo).to.have.length.above(0);
+ priceInfo.taxesInfo.forEach(
+ (tax) => {
+ expect(tax).to.be.an('object');
+ expect(tax.value).to.match(/^[A-Z]{3}(\d+\.)?\d+$/);
+ expect(tax.type).to.match(/^[A-Z]{2}$/);
+ }
+ );
// Passengers
expect(result.passengers).to.be.an('array');
expect(result.passengers).to.have.length.above(0);
@@ -343,6 +349,33 @@ describe('#AirParser', () => {
});
});
+ it('should parse ticket with XF and ZP taxes', () => {
+ const uParser = new ParserUapi('air:AirRetrieveDocumentRsp', 'v39_0', {});
+ const parseFunction = airParser.AIR_GET_TICKET;
+ const xml = fs.readFileSync(`${xmlFolder}/getTicket_XF_ZP.xml`).toString();
+ return uParser.parse(xml)
+ .then(json => parseFunction.call(uParser, json))
+ .then((result) => {
+ testGetTicket(result);
+ const detialedTaxes = result.priceInfo.taxesInfo.filter(
+ tax => ['XF', 'ZP'].indexOf(tax.type) !== -1
+ );
+ expect(detialedTaxes).to.have.lengthOf(2);
+ detialedTaxes.forEach(
+ (tax) => {
+ expect(tax.details).to.be.an('array').and.to.have.length.above(0);
+ tax.details.forEach(
+ (detailInfo) => {
+ expect(detailInfo).to.have.all.keys(['airport', 'value']);
+ expect(detailInfo.airport).to.match(/^[A-Z]{3}$/);
+ expect(detailInfo.value).to.match(/^[A-Z]{3}(\d+\.)?\d+$/);
+ }
+ );
+ }
+ );
+ });
+ });
+
it('should parse incomplete data', () => {
const uParser = new ParserUapi('air:AirRetrieveDocumentRsp', 'v39_0', {});
const parseFunction = airParser.AIR_GET_TICKET;
@@ -742,6 +775,33 @@ describe('#AirParser', () => {
}
describe('AIR_CREATE_RESERVATION()', () => {
+ it('should parse booking with XF and ZP taxes in FQ', () => {
+ const uParser = new ParserUapi('universal:UniversalRecordImportRsp', 'v36_0', { });
+ const parseFunction = airParser.AIR_CREATE_RESERVATION_REQUEST;
+ const xml = fs.readFileSync(`${xmlFolder}/getPNR_XF_ZP.xml`).toString();
+ return uParser.parse(xml)
+ .then(json => parseFunction.call(uParser, json))
+ .then((result) => {
+ testBooking(result);
+ const detialedTaxes = result[0].reservations[0].priceInfo.taxesInfo.filter(
+ tax => ['XF', 'ZP'].indexOf(tax.type) !== -1
+ );
+ expect(detialedTaxes).to.have.lengthOf(2);
+ detialedTaxes.forEach(
+ (tax) => {
+ expect(tax.details).to.be.an('array').and.to.have.length.above(0);
+ tax.details.forEach(
+ (detailInfo) => {
+ expect(detailInfo).to.have.all.keys(['airport', 'value']);
+ expect(detailInfo.airport).to.match(/^[A-Z]{3}$/);
+ expect(detailInfo.value).to.match(/^[A-Z]{3}(\d+\.)?\d+$/);
+ }
+ );
+ }
+ );
+ });
+ });
+
it('should test parsing of create reservation 2ADT1CNN', () => {
const uParser = new ParserUapi('universal:AirCreateReservationRsp', 'v36_0', { });
const parseFunction = airParser.AIR_CREATE_RESERVATION_REQUEST;
diff --git a/test/FakeResponses/Air/getPNR_XF_ZP.xml b/test/FakeResponses/Air/getPNR_XF_ZP.xml
new file mode 100644
index 00000000..ef44d539
--- /dev/null
+++ b/test/FakeResponses/Air/getPNR_XF_ZP.xml
@@ -0,0 +1,106 @@
+
+
+
+ PNR already exists in Universal Record HAB2JQ
+
+
+
+
+
+
+
+
+
+
+
+
+ IEV 25MAY1444Z 34 AG
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AIR WISCONSIN AS AMERICAN EAGLE
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NYC AA WAS 242.79VUAHZNN1 AA DTT Q10.74 71.63NVAIZNN3 USD325.16END
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VIEWTRIPITIN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/FakeResponses/Air/getTicket_XF_ZP.xml b/test/FakeResponses/Air/getTicket_XF_ZP.xml
new file mode 100644
index 00000000..e3053e7d
--- /dev/null
+++ b/test/FakeResponses/Air/getTicket_XF_ZP.xml
@@ -0,0 +1,160 @@
+
+
+
+
+ 4HN6N9
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NYC AA WAS 242.79 AA DTT Q10.74 71.63 USD325.16END ZPLGADCA XT 216ZP238XF LGA4.5DCA4.5
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NYC AA WAS 242.79VUAHZNN1 AA DTT Q10.74 71.63NVAIZNN3 USD325.16END
+
+
+
+
+
+
+
+
+
+ MYTRIPANDMORE.COM/BAGGAGEDETAILSAA.BAGG
+
+
+ 0P
+ BAGGAGE DISCOUNTS MAY APPLY BASED ON FREQUENT FLYER STATUS/ ONLINE CHECKIN/FORM OF PAYMENT/MILITARY/ETC.
+
+
+
+
+ UPTO50LB/23KG AND UPTO62LI/158LCM
+
+
+
+
+
+
+ UPTO50LB/23KG AND UPTO62LI/158LCM
+
+
+
+
+
+
+ MYTRIPANDMORE.COM/BAGGAGEDETAILSAA.BAGG
+
+
+ 0P
+ BAGGAGE DISCOUNTS MAY APPLY BASED ON FREQUENT FLYER STATUS/ ONLINE CHECKIN/FORM OF PAYMENT/MILITARY/ETC.
+
+
+
+
+ UPTO50LB/23KG AND UPTO62LI/158LCM
+
+
+
+
+
+
+ UPTO50LB/23KG AND UPTO62LI/158LCM
+
+
+
+
+
+
+ 2P
+
+
+
+
+ UPTO45LI/115LCM
+
+
+
+
+
+
+ CARRYON HAND BAGGAGE ALLOWANCE
+
+
+
+
+
+
+ 2P
+
+
+
+
+ UPTO45LI/115LCM
+
+
+
+
+
+
+ CARRYON HAND BAGGAGE ALLOWANCE
+
+
+
+
+
+
+ MYTRIPANDMORE.COM/BAGGAGEDETAILSAA.BAGG
+
+
+
+
+ MYTRIPANDMORE.COM/BAGGAGEDETAILSAA.BAGG
+
+
+
+
+
+
+