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 + + + + + + +