I have JSON file in Blob Storage that looks like this:
{
"Id": "****************************",
"Status": "OK",
"ProviderName": "Xero API Previewer",
"DateTimeUTC": "\/Date(1576561543598)\/",
"Invoices": [
{
"Type": "ACCPAY",
"InvoiceID": "*****************************",
"InvoiceNumber": "457489",
"Reference": "",
"Payments": [],
"CreditNotes": [],
"Prepayments": [],
"Overpayments": [],
"AmountDue": 0.00,
"AmountPaid": 0.00,
"AmountCredited": 0.00,
"CurrencyRate": 1.000000,
"IsDiscounted": false,
"HasAttachments": false,
"HasErrors": false,
"Contact": {
"ContactID": "************************************",
"Name": "********************",
"Addresses": [],
"Phones": [],
"ContactGroups": [],
"ContactPersons": [],
"HasValidationErrors": false
},
"DateString": "2102-11-26T00:00:00",
"Date": "\/Date(4193942400000+0000)\/",
"DueDateString": "2012-11-28T00:00:00",
"DueDate": "\/Date(1354060800000+0000)\/",
"Status": "VOIDED",
"LineAmountTypes": "Inclusive",
"LineItems": [
{
"Description": "Parking ",
"UnitAmount": 465.01,
"TaxType": "INPUT2",
"TaxAmount": 60.65,
"LineAmount": 465.01,
"AccountCode": "274",
"Tracking": [
{
"Name": "Region",
"Option": "New Zealand",
"TrackingCategoryID": "****************************************",
"Options": []
},
{
"Name": "Owner",
"Option": "Head Office",
"TrackingCategoryID": "***************************************",
"Options": []
}
],
"Quantity": 1.0000,
"LineItemID": "**************************************"
}
],
"SubTotal": 404.36,
"TotalTax": 60.65,
"Total": 465.01,
"UpdatedDateUTC": "\/Date(1355876228590+0000)\/",
"CurrencyCode": "NZD"
},
{
"Type": "ACCPAY",
"InvoiceID": "**************************************",
"InvoiceNumber": "176295-01",
"Reference": "",
"Payments": [
{
"PaymentID": "********************************************",
"Date": "\/Date(1576454400000+0000)\/",
"Amount": 137.43,
"Reference": "",
"CurrencyRate": 1.000000,
"HasAccount": false,
"HasValidationErrors": false
}
],
"CreditNotes": [],
"Prepayments": [],
"Overpayments": [],
"AmountDue": 0.00,
"AmountPaid": 137.43,
"AmountCredited": 0.00,
"CurrencyRate": 1.000000,
"IsDiscounted": false,
"HasAttachments": true,
"HasErrors": false,
"Contact": {
"ContactID": "************************************",
"Name": "InkWorks",
"Addresses": [],
"Phones": [],
"ContactGroups": [],
"ContactPersons": [],
"HasValidationErrors": false
},
"DateString": "2019-12-17T00:00:00",
"Date": "\/Date(1576540800000+0000)\/",
"DueDateString": "2020-01-20T00:00:00",
"DueDate": "\/Date(1579478400000+0000)\/",
"Status": "PAID",
"LineAmountTypes": "Inclusive",
"LineItems": [
{
"Description": "general stationery",
"UnitAmount": 137.43,
"TaxType": "INPUT2",
"TaxAmount": 17.93,
"LineAmount": 137.43,
"AccountCode": "273",
"Tracking": [
{
"Name": "Owner",
"Option": "Head Office",
"TrackingCategoryID": "******************************",
"Options": []
}
],
"Quantity": 1.0000,
"LineItemID": "****************************************"
}
],
"SubTotal": 119.50,
"TotalTax": 17.93,
"Total": 137.43,
"UpdatedDateUTC": "\/Date(1576524509820+0000)\/",
"CurrencyCode": "NZD",
"FullyPaidOnDate": "\/Date(1576454400000+0000)\/"
},
I want to store LineItems into a Table with columns as follows:
InvoiceID LineItemID Description LineAmount AccountCode Date
There can be multiple LineItems in a single invoice.
I managed to get the top level only with the following code.
WITH cte AS (
SELECT CAST (BulkColumn AS NVARCHAR(MAX)) AS jsonData
FROM
OPENROWSET(
BULK 'temp/XeroJson.json',
DATA_SOURCE = 'test'
-- FORMATFILE_DATA_SOURCE = 'test'
, SINGLE_CLOB
) AS blob
)
SELECT *
FROM cte
CROSS APPLY
OPENJSON(cte.jsonData) j
How can I make this work?
This is my test .json file, I placed it in my storage account :
{
"Id": "****************************",
"Status": "OK",
"ProviderName": "Xero API Previewer",
"DateTimeUTC": "\/Date(1576561543598)\/",
"Invoices":
[
{
"Type": "ACCPAY",
"InvoiceID": "123456",
"InvoiceNumber": "457489",
"Reference": "",
"Payments": [],
"CreditNotes": [],
"Prepayments": [],
"Overpayments": [],
"AmountDue": 0.00,
"AmountPaid": 0.00,
"AmountCredited": 0.00,
"CurrencyRate": 1.000000,
"IsDiscounted": false,
"HasAttachments": false,
"HasErrors": false,
"Contact": {
"ContactID": "************************************",
"Name": "********************",
"Addresses": [],
"Phones": [],
"ContactGroups": [],
"ContactPersons": [],
"HasValidationErrors": false
},
"DateString": "2102-11-26T00:00:00",
"Date": "\/Date(4193942400000+0000)\/",
"DueDateString": "2012-11-28T00:00:00",
"DueDate": "\/Date(1354060800000+0000)\/",
"Status": "VOIDED",
"LineAmountTypes": "Inclusive",
"LineItems": [{
"Description": "Parking ",
"UnitAmount": 465.01,
"TaxType": "INPUT2",
"TaxAmount": 60.65,
"LineAmount": 465.01,
"AccountCode": "274",
"Tracking": [{
"Name": "Region",
"Option": "New Zealand",
"TrackingCategoryID": "****************************************",
"Options": []
}, {
"Name": "Owner",
"Option": "Head Office",
"TrackingCategoryID": "***************************************",
"Options": []
}
],
"Quantity": 1.0000,
"LineItemID": "**************************************"
},
{
"Description": "Parking2 ",
"UnitAmount": 111.11,
"TaxType": "INPUT2",
"TaxAmount": 60.65,
"LineAmount": 465.01,
"AccountCode": "276",
"Tracking": [{
"Name": "Region",
"Option": "New Zealand",
"TrackingCategoryID": "****************************************",
"Options": []
}, {
"Name": "Owner",
"Option": "Head Office",
"TrackingCategoryID": "***************************************",
"Options": []
}
],
"Quantity": 1.0000,
"LineItemID": "**************************************"
}
],
"SubTotal": 404.36,
"TotalTax": 60.65,
"Total": 465.01,
"UpdatedDateUTC": "\/Date(1355876228590+0000)\/",
"CurrencyCode": "NZD"
},
{
"Type": "ACCPAY",
"InvoiceID": "1234567",
"InvoiceNumber": "176295-01",
"Reference": "",
"Payments": [{
"PaymentID": "********************************************",
"Date": "\/Date(1576454400000+0000)\/",
"Amount": 137.43,
"Reference": "",
"CurrencyRate": 1.000000,
"HasAccount": false,
"HasValidationErrors": false
}
],
"CreditNotes": [],
"Prepayments": [],
"Overpayments": [],
"AmountDue": 0.00,
"AmountPaid": 137.43,
"AmountCredited": 0.00,
"CurrencyRate": 1.000000,
"IsDiscounted": false,
"HasAttachments": true,
"HasErrors": false,
"Contact": {
"ContactID": "************************************",
"Name": "InkWorks",
"Addresses": [],
"Phones": [],
"ContactGroups": [],
"ContactPersons": [],
"HasValidationErrors": false
},
"DateString": "2019-12-17T00:00:00",
"Date": "\/Date(1576540800000+0000)\/",
"DueDateString": "2020-01-20T00:00:00",
"DueDate": "\/Date(1579478400000+0000)\/",
"Status": "PAID",
"LineAmountTypes": "Inclusive",
"LineItems": [{
"Description": "general stationery",
"UnitAmount": 137.43,
"TaxType": "INPUT2",
"TaxAmount": 17.93,
"LineAmount": 137.43,
"AccountCode": "273",
"Tracking": [{
"Name": "Owner",
"Option": "Head Office",
"TrackingCategoryID": "******************************",
"Options": []
}
],
"Quantity": 1.0000,
"LineItemID": "****************************************"
}
],
"SubTotal": 119.50,
"TotalTax": 17.93,
"Total": 137.43,
"UpdatedDateUTC": "\/Date(1576524509820+0000)\/",
"CurrencyCode": "NZD",
"FullyPaidOnDate": "\/Date(1576454400000+0000)\/"
}
]
}
As you can see the first invoice has two lineItems for demo here.
This is my sql script to exract from the json from storage :
CREATE DATABASE SCOPED CREDENTIAL AccessAzureInvoices
WITH
IDENTITY = 'SHARED ACCESS SIGNATURE'
-- REMOVE ? FROM THE BEGINNING OF THE SAS TOKEN
, SECRET = '<YOUR STORAGE SAS TOKEN>'
;
CREATE EXTERNAL DATA SOURCE MyAzureInvoices
WITH
( LOCATION = 'https://<YOUR STORAGE NAME>.blob.core.windows.net/<CONTAINER NAME WHERE YOUR JSON FILE IN>'
, CREDENTIAL = AccessAzureInvoices
, TYPE = BLOB_STORAGE
)
;
DECLARE #jsonVariable NVARCHAR(MAX);
set #jsonVariable = (select * from OPENROWSET(
BULK '<YOUR JSON FILE NAME>.json',
DATA_SOURCE = 'MyAzureInvoices',
SINGLE_CLOB
) AS blob)
select * from (
SELECT *
FROM OPENJSON(#jsonVariable,N'$.Invoices') WITH (
InvoiceID VARCHAR(200) N'$.InvoiceID',
Date VARCHAR(200) N'$.Date',
LineItems NVARCHAR(MAX) N'$.LineItems' as json
))as table1
CROSS APPLY OPENJSON(LineItems) with (
LineAmount VARCHAR(200) '$.LineAmount',
AccountCode VARCHAR(200)'$.AccountCode',
LineItemID VARCHAR(200) '$.LineItemID',
Description VARCHAR(200) '$.Description'
)
Result :
Hope it helps !
Related
From the documentation of the Get Route for the flight offers Api, I can add travelerClass as a filter to make a request. If I add say travelerClass as ECONOMY?
I expect to see only offers with ECONOMY. However I see that within the fareDetailsBySegment section in the result, I see that some Offers have their cabin values as other than ECONOMY. I see some with value of BUSINESS while others as PREMIUM_ECONOMY.
Is this proper?
My Concern
I want to be able to get all bookings that where ECONOMY based only. So I need to be sure that the flight offers returned in the first place are strictly limited by the travelerClass.
I will appreciate any clarity on the this issue. Also if there is a better way to go about this concern above, it will be most appreciated.
An example of my request is below:
Amadeus.shopping.flightOffersSearch.get({
originLocationCode: 'SYD',
destinationLocationCode: 'BKK',
departureDate: '2022-11-01',
adults: '1',
travelClass: 'ECONOMY'
}).then(...)
Offer with BUSINESS instead of ECONOMY
{
"type": "flight-offer",
"id": "22",
"source": "GDS",
"instantTicketingRequired": false,
"nonHomogeneous": false,
"oneWay": false,
"lastTicketingDate": "2022-11-01",
"numberOfBookableSeats": 6,
"itineraries": [
{
"duration": "PT28H20M",
"segments": [
{
"departure": {
"iataCode": "SYD",
"terminal": "1",
"at": "2022-11-01T12:00:00"
},
"arrival": {
"iataCode": "PVG",
"terminal": "2",
"at": "2022-11-01T19:30:00"
},
"carrierCode": "MU",
"number": "562",
"aircraft": {
"code": "77W"
},
"operating": {
"carrierCode": "MU"
},
"duration": "PT10H30M",
"id": "13",
"numberOfStops": 0,
"blacklistedInEU": false
},
{
"departure": {
"iataCode": "PVG",
"terminal": "1",
"at": "2022-11-02T08:45:00"
},
"arrival": {
"iataCode": "BKK",
"at": "2022-11-02T12:20:00"
},
"carrierCode": "MU",
"number": "541",
"aircraft": {
"code": "320"
},
"operating": {
"carrierCode": "MU"
},
"duration": "PT4H35M",
"id": "14",
"numberOfStops": 0,
"blacklistedInEU": false
}
]
}
],
"price": {
"currency": "EUR",
"total": "4048.84",
"base": "3858.00",
"fees": [
{
"amount": "0.00",
"type": "SUPPLIER"
},
{
"amount": "0.00",
"type": "TICKETING"
}
],
"grandTotal": "4048.84"
},
"pricingOptions": {
"fareType": [
"PUBLISHED"
],
"includedCheckedBagsOnly": true
},
"validatingAirlineCodes": [
"MU"
],
"travelerPricings": [
{
"travelerId": "1",
"fareOption": "STANDARD",
"travelerType": "ADULT",
"price": {
"currency": "EUR",
"total": "4048.84",
"base": "3858.00"
},
"fareDetailsBySegment": [
{
"segmentId": "13",
"cabin": "ECONOMY",
"fareBasis": "YSE0WDNQ",
"class": "Y",
"includedCheckedBags": {
"quantity": 2
}
},
{
"segmentId": "14",
"cabin": "BUSINESS",
"fareBasis": "QSE0WCNL",
"class": "Q",
"includedCheckedBags": {
"quantity": 2
}
}
]
}
]
}
in order to apply the filter for cabin class, I suggest you to try with POST method.
in POST method has more search criteria you can apply, below example is something that I have tried and it works: response only contains ECONOMY classes by updating values under cabinRestrictions.
details of the request model is available in API reference page
amadeus.shopping.flightOffersSearch.post(JSON.stringify({
"currencyCode": "USD",
"originDestinations": [
{
"id": "1",
"originLocationCode": "SYD",
"destinationLocationCode": "BKK",
"departureDateTimeRange": {
"date": "2022-11-01"
}
}
],
"travelers": [
{
"id": "1",
"travelerType": "ADULT"
}
],
"sources": [
"GDS"
],
"searchCriteria": {
"maxFlightOffers": 10,
"flightFilters": {
"cabinRestrictions": [
{
"cabin": "ECONOMY",
"coverage": "ALL_SEGMENTS",
"originDestinationIds": [
1
]
}
]
}
}
})).then(...)
I am on a test Account.
On printing the travelerPricings Object to console, I have this
[
{
travelerId: '1',
fareOption: 'STANDARD',
travelerType: 'ADULT',
price: {
currency: '',
total: '',
base: '',
taxes: [Array],
refundableTaxes: ''
},
fareDetailsBySegment: [ [Object], [Object], [Object], [Object] ]
},
{
travelerId: '2',
fareOption: 'STANDARD',
travelerType: 'CHILD',
price: {
currency: '',
total: '',
base: '',
taxes: [Array],
refundableTaxes: ''
},
fareDetailsBySegment: [ [Object], [Object], [Object], [Object] ]
}
]
Yet on the Api Response, I keep getting the error pointer as
/data/flightOffers[0]/travelerPricings[1]"
Which is not true. As seen in the log shared above,
travelerPricings[1].travelerId = '2'
Please Why could this error come up? Thanks
Based on the Request, Here is the sample payload
{"data":
{
"flightOffers": [
{
"type": "flight-offer",
"id": "1",
"source": "GDS",
"instantTicketingRequired": false,
"nonHomogeneous": false,
"paymentCardRequired": false,
"lastTicketingDate": "2022-08-01",
"itineraries": [
{
"segments": [
{
"departure": {
"iataCode": "SYD",
"terminal": "1",
"at": "2022-08-01T11:35:00"
},
"arrival": {
"iataCode": "MNL",
"terminal": "2",
"at": "2022-08-01T16:50:00"
},
"carrierCode": "PR",
"number": "212",
"aircraft": {
"code": "333"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT7H15M",
"id": "15",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 716,
"weightUnit": "KG",
"cabin": "BUSINESS"
}
]
},
{
"departure": {
"iataCode": "MNL",
"terminal": "1",
"at": "2022-08-01T19:20:00"
},
"arrival": {
"iataCode": "BKK",
"at": "2022-08-01T21:50:00"
},
"carrierCode": "PR",
"number": "732",
"aircraft": {
"code": "320"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT3H30M",
"id": "16",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 148,
"weightUnit": "KG",
"cabin": "BUSINESS"
}
]
}
]
},
{
"segments": [
{
"departure": {
"iataCode": "BKK",
"at": "2022-08-05T22:50:00"
},
"arrival": {
"iataCode": "MNL",
"terminal": "2",
"at": "2022-08-06T03:15:00"
},
"carrierCode": "PR",
"number": "733",
"aircraft": {
"code": "321"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT3H25M",
"id": "59",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 148,
"weightUnit": "KG",
"cabin": "ECONOMY"
}
]
},
{
"departure": {
"iataCode": "MNL",
"terminal": "1",
"at": "2022-08-06T22:10:00"
},
"arrival": {
"iataCode": "SYD",
"terminal": "1",
"at": "2022-08-07T09:45:00"
},
"carrierCode": "PR",
"number": "211",
"aircraft": {
"code": "333"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT9H35M",
"id": "60",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 358,
"weightUnit": "KG",
"cabin": "ECONOMY"
}
]
}
]
}
],
"price": {
"currency": "NGN",
"total": "1479460.00",
"base": "1298255.00",
"fees": [
{
"amount": "0.00",
"type": "SUPPLIER"
},
{
"amount": "0.00",
"type": "TICKETING"
},
{
"amount": "0.00",
"type": "FORM_OF_PAYMENT"
}
],
"grandTotal": "1479460.00",
"billingCurrency": "NGN"
},
"pricingOptions": {
"fareType": [
"PUBLISHED"
],
"includedCheckedBagsOnly": false
},
"validatingAirlineCodes": [
"PR"
],
"travelerPricings": [
{
"travelerId": "1",
"fareOption": "STANDARD",
"travelerType": "ADULT",
"price": {
"currency": "NGN",
"total": "840536",
"base": "740769",
"taxes": [
{
"amount": "384.00",
"code": "G8"
},
{
"amount": "19112.00",
"code": "WY"
},
{
"amount": "896.00",
"code": "E7"
},
{
"amount": "18329.00",
"code": "AU"
},
{
"amount": "42766.00",
"code": "YQ"
},
{
"amount": "9320.00",
"code": "LI"
},
{
"amount": "8960.00",
"code": "TS"
}
],
"refundableTaxes": "108123"
},
"fareDetailsBySegment": [
{
"segmentId": "15",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "16",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "59",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
},
{
"segmentId": "60",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
}
]
},
{
"travelerId": "2",
"fareOption": "STANDARD",
"travelerType": "CHILD",
"price": {
"currency": "NGN",
"total": "638924",
"base": "557486",
"taxes": [
{
"amount": "384.00",
"code": "G8"
},
{
"amount": "19112.00",
"code": "WY"
},
{
"amount": "896.00",
"code": "E7"
},
{
"amount": "42766.00",
"code": "YQ"
},
{
"amount": "9320.00",
"code": "LI"
},
{
"amount": "8960.00",
"code": "TS"
}
],
"refundableTaxes": "89794"
},
"fareDetailsBySegment": [
{
"segmentId": "15",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "16",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "59",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
},
{
"segmentId": "60",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
}
]
}
]
}
],
"travelers": [ {
"id": "1",
"dateOfBirth": "1982-01-16",
"name": {
"firstName": "JORGE",
"lastName": "GONZALES"
},
"gender": "MALE",
"contact": {
"emailAddress": "jorge.gonzales833#telefonica.es",
"phones": [ {
"deviceType": "MOBILE",
"countryCallingCode": "34",
"number": "480080076"
} ]
},
"documents": [ {
"documentType": "PASSPORT",
"birthPlace": "Madrid",
"issuanceLocation": "Madrid",
"issuanceDate": "2015-04-14",
"number": "00000000",
"expiryDate": "2025-04-14",
"issuanceCountry": "ES",
"validityCountry": "ES",
"nationality": "ES",
"holder": true
} ]
} ]
}
MY Request using the NodeSDK
const {data:{flightOffers}} = req.body;
const {result} = await Amadeus.booking.flightOrders.post(
JSON.stringify({
'data': {
'type': 'flight-order',
'flightOffers': [ flightOffers[ 0 ] ],
'travelers': travelers
}
})
);
This is quite lengthy, but I did this so it is easy to just re-create the exact Scenario in case the issue is somewhere in the payload I am sending.
When you request Flight Create Order API, you have only put 1 traveler's information at the end that's why the error comes. you are requesting for flight order for 2 persons (1 adult and 1 child) so both information should be attached at the end.
below is a node example for the entire flow from Flight offer search, pricing, and create order. you may get a different error if some segments are not available, but the issue that you faced regarding travelers is resolved.
amadeus.shopping.flightOffersSearch.get({
originLocationCode: 'SYD',
destinationLocationCode: 'BKK',
departureDate: '2022-08-01',
adults: '1',
children: '1'
}).then(function (flightOffersResponse) {
return amadeus.shopping.flightOffers.pricing.post(
JSON.stringify({
'data': {
'type': 'flight-offers-pricing',
'flightOffers': [flightOffersResponse.data[0]]
}
})
)
}).then(function (pricingResponse) {
return amadeus.booking.flightOrders.post(
JSON.stringify({
'data': {
'type': 'flight-order',
'flightOffers': [pricingResponse.data.flightOffers[0]],
'travelers': [{
"id": "1",
"dateOfBirth": "1982-01-16",
"name": {
"firstName": "JORGE",
"lastName": "GONZALES"
},
"gender": "MALE",
"contact": {
"emailAddress": "jorge.gonzales833#telefonica.es",
"phones": [{
"deviceType": "MOBILE",
"countryCallingCode": "34",
"number": "480080076"
}]
},
"documents": [{
"documentType": "PASSPORT",
"birthPlace": "Madrid",
"issuanceLocation": "Madrid",
"issuanceDate": "2015-04-14",
"number": "00000000",
"expiryDate": "2025-04-14",
"issuanceCountry": "ES",
"validityCountry": "ES",
"nationality": "ES",
"holder": true
}]
},
{
"id": "2",
"dateOfBirth": "2012-10-11",
"gender": "FEMALE",
"contact": {
"emailAddress": "jorge.gonzales833#telefonica.es",
"phones": [
{
"deviceType": "MOBILE",
"countryCallingCode": "34",
"number": "480080076"
}
]
},
"name": {
"firstName": "ADRIANA",
"lastName": "GONZALES"
}
}]
}
})
);
}).then(function (response) {
console.log(response);
}).catch(function (response) {
console.error(response);
});
I am needing to unnest a multidimensional array with multiple items.
My data looks like this (two rows):
Each order in this table has a fulfillments column which is a multidimensional array.
fulfilments has multiple line_items. Some orders only have 1 line_items, some orders have multiple line_items.
My goal is to get each product name and the quantity from each line_items and do a running sum/tally.
Here's a JSON export of the fulfillments column data:
"{
"fulfillments": [{
"value": {
"id": "6575674745",
"tracking_number": null,
"line_items": [{
"value": {
"properties": [{
"value": {
"name": "shipping_interval_unit_type",
"value": "Months"
}
}, {
"value": {
"name": "shipping_interval_frequency",
"value": "1"
}
}, {
"value": {
"name": "ch_item_id",
"value": "77321530"
}
}],
"product_id": "4790985097351",
"total_discount_set": {
"shop_money": {
"amount": "0.00",
"currency_code": "USD"
},
"presentment_money": {
"amount": "0.00",
"currency_code": "USD"
}
},
"sku": “10101”,
"name": “Product1”,
"variant_id": "33433213108359",
"quantity": "1",
"taxable": "true",
"total_discount": "0",
"title": "Product1 Title",
"price_set": {
"shop_money": {
"amount": "12.00",
"currency_code": "USD"
},
"presentment_money": {
"amount": "12.00",
"currency_code": "USD"
}
},
"product_exists": "true"
}
}],
"service": "manual",
"tracking_urls": []
}
}, {
"value": {
"tracking_url": null,
"id": "3555531128967",
"tracking_company": null,
"tracking_number": null,
"name": "#3129472402.2",
"tracking_numbers": [],
"line_items": [{
"value": {
"properties": [{
"value": {
"name": "shipping_interval_frequency",
"value": "1"
}
}, {
"value": {
"name": "shipping_interval_unit_type",
"value": "Months"
}
}, {
"value": {
"name": "ch_item_id",
"value": "77321529"
}
}],
"product_id": "5216409780359",
"total_discount_set": {
"shop_money": {
"amount": "0.00",
"currency_code": "USD"
},
"presentment_money": {
"amount": "0.00",
"currency_code": "USD"
}
},
"sku": "9005",
"name": “Product2”,
"quantity": "1",
"title": “Product2 Title”,
"price_set": {
"shop_money": {
"amount": "0.00",
"currency_code": "USD"
},
"presentment_money": {
"amount": "0.00",
"currency_code": "USD"
}
},
"product_exists": "true"
}
}],
"service": "manual",
"tracking_urls": []
}
}]
}"
SELECT
fulfillments[ safe_OFFSET (0)].value.line_items[ safe_OFFSET (0)].value.name AS name,
fulfillments[ safe_OFFSET (0)].value.line_items[ safe_OFFSET (0)].value.quantity AS quantity
FROM
`mydatabase`
isn't ideal in the event the order has more than one array in line_items
How can I unnest a multidimensional array when I don't know how large each array is?
SELECT
*
FROM
`mydatabase`,
UNNEST(fulfillments) as a
Only gives me another array to flatten
Given your scenario, you may try to use this query to unnest line_items with product name and the quantity:
SELECT
line_items.value.name,
line_items.value.quantity,
line_items.value.product_id
from `mydatabase`,
unnest(fulfillments) fulfillments,
unnest(fulfillments.value.line_items) line_items
Output:
I'm using Azure's cosmos DB, and testing via the sqlquery in the Azure portal. Some points in my collection are valid, some are not. I am unable to tell from the GeoJSON spec if I am missing requirements. All my points pass the geojsonlint test: https://geojsonlint.com/
What could be causing invalid points? The locations are setup the same as far as I can tell.
My Query:
SELECT *
FROM events1 e
WHERE ST_ISVALID(e.location)
Running the query returns that these are valid:
[
{
"id": "b4b49b65-dfad-40f3-943b-753553507d2c",
"name": "OG Olympics",
"location": {
"type": "Point",
"coordinates": [
41.900697426935544,
12.480266913771628
]
},
"events": "Hockey",
"time": "00:00:00",
"recurring": null,
"date": null,
"difficulty": "Expert",
"ages": "Senior",
"admin": null,
"private": null,
"_rid": "Maw1AIaRiRoHAAAAAAAAAA==",
"_self": "dbs/Maw1AA==/colls/Maw1AIaRiRo=/docs/Maw1AIaRiRoHAAAAAAAAAA==/",
"_etag": "\"11003fb9-0000-0700-0000-5f2f15cf0000\"",
"_attachments": "attachments/",
"_ts": 1596921295
},
{
"id": "f2d063e3-5654-475d-8e97-7412dc77fcfb",
"name": "Test Event DenverCC",
"location": {
"type": "Point",
"coordinates": [
100.2093,
-15.868
]
},
"events": "Basketball",
"time": "18:00:00",
"recurring": null,
"date": null,
"difficulty": "Intermediate",
"ages": "Senior",
"admin": null,
"private": null,
"_rid": "Maw1AIaRiRoJAAAAAAAAAA==",
"_self": "dbs/Maw1AA==/colls/Maw1AIaRiRo=/docs/Maw1AIaRiRoJAAAAAAAAAA==/",
"_etag": "\"1300a79d-0000-0700-0000-5f304fc80000\"",
"_attachments": "attachments/",
"_ts": 1597001672
},
{
"id": "10000",
"name": "OG Olympics 2",
"location": {
"type": "Point",
"coordinates": [
41.000697426935545,
-12.080266913771627
]
},
"events": "Hockey",
"time": "00:00:00",
"recurring": null,
"date": null,
"difficulty": "Expert",
"ages": "Senior",
"admin": null,
"private": null,
"_rid": "Maw1AIaRiRoKAAAAAAAAAA==",
"_self": "dbs/Maw1AA==/colls/Maw1AIaRiRo=/docs/Maw1AIaRiRoKAAAAAAAAAA==/",
"_etag": "\"13003499-0000-0700-0000-5f304d580000\"",
"_attachments": "attachments/",
"_ts": 1597001048
}
]
But it returns that these are invalid:
{
"id": "1000",
"name": "Sunday Morning Hockey",
"location": {
"type": "Point",
"coordinates": [
39,
-105
]
},
"events": "hockey",
"time": "09:00",
"recurring": "true",
"date": "2020-08-02",
"difficulty": "all levels",
"ages": "all ages",
"admin": "1000",
"private": "false",
"_rid": "Maw1AIaRiRoBAAAAAAAAAA==",
"_self": "dbs/Maw1AA==/colls/Maw1AIaRiRo=/docs/Maw1AIaRiRoBAAAAAAAAAA==/",
"_etag": "\"13008c9f-0000-0700-0000-5f3050d70000\"",
"_attachments": "attachments/",
"_ts": 1597001943
}
{
"id": "9f373e04-0cfc-4121-927d-a6256dbe06c6",
"name": "test1",
"location": {
"type": "Point",
"coordinates": [
39.731441899363105,
-104.98381230980158
]
},
"events": "Basketball",
"time": "00:00:00",
"recurring": null,
"date": null,
"difficulty": "Expert",
"ages": "Adult",
"admin": null,
"private": null,
"_rid": "Maw1AIaRiRoLAAAAAAAAAA==",
"_self": "dbs/Maw1AA==/colls/Maw1AIaRiRo=/docs/Maw1AIaRiRoLAAAAAAAAAA==/",
"_etag": "\"13005999-0000-0700-0000-5f304d760000\"",
"_attachments": "attachments/",
"_ts": 1597001078
}
{
"id": "be01bc12-d28e-4368-b6de-0f3e84dbe13c",
"name": "test2",
"location": {
"type": "Point",
"coordinates": [
39.72082849205111,
-104.98461395502092
]
},
"events": "Hockey",
"time": "00:00:00",
"recurring": null,
"date": null,
"difficulty": "Expert",
"ages": "Adult",
"admin": null,
"private": null,
"_rid": "Maw1AIaRiRoMAAAAAAAAAA==",
"_self": "dbs/Maw1AA==/colls/Maw1AIaRiRo=/docs/Maw1AIaRiRoMAAAAAAAAAA==/",
"_etag": "\"1300219a-0000-0700-0000-5f304de10000\"",
"_attachments": "attachments/",
"_ts": 1597001185
}
Took a while to realize, but GeoJSON expects flipped coordinates in the Point.
So while Maps return me a point type with [ latitude, longitude ]. GeoJSON expects [longitude, latitude]
I'm testing self-service APIs. I wonder if this is a bug:
I make a search request, and the response contains the extra bag information in the flight-offer/price/additionalServices
Then I make the offer price request by adding include=bags parameter in the path of Flight Offers Price API.
However there is no any bags information in the response, neither in the offer/price/additionalServices, nor in the included/.
I still try to create order by adding the extra bag. So I use the extra bag information that I got at step 1 (search response). And the order is created successfully.
It seems that the extra bag information is missing in step 2 (response of flight offer price), is it a bug?
Here is an example of my test to reproduce the issue:
search request
{
"currencyCode": "EUR",
"originDestinations": [
{
"id": "1",
"originLocationCode": "PAR",
"destinationLocationCode": "NYC",
"departureDateTimeRange": {
"date": "2020-08-20",
"time": "10:00:00"
}
}
],
"travelers": [
{
"id": "1",
"travelerType": "ADULT"
}
],
"sources": [
"GDS"
],
"searchCriteria": {
"maxFlightOffers": 3
}
}
Then I select the second offer in the response to make a offer price request using include=bags parameter
{
"type": "flight-offer",
"id": "2",
"source": "GDS",
"instantTicketingRequired": false,
"nonHomogeneous": false,
"oneWay": false,
"lastTicketingDate": "2020-08-13",
"numberOfBookableSeats": 8,
"itineraries": [
{
"duration": "PT8H15M",
"segments": [
{
"departure": {
"iataCode": "ORY",
"terminal": "4",
"at": "2020-08-20T19:45:00"
},
"arrival": {
"iataCode": "EWR",
"terminal": "B",
"at": "2020-08-20T22:00:00"
},
"carrierCode": "TX",
"number": "6720",
"aircraft": {
"code": "359"
},
"operating": {
"carrierCode": "BF"
},
"duration": "PT8H15M",
"id": "3",
"numberOfStops": 0,
"blacklistedInEU": false
}
]
}
],
"price": {
"currency": "EUR",
"total": "149.44",
"base": "41.00",
"fees": [
{
"amount": "0.00",
"type": "SUPPLIER"
},
{
"amount": "0.00",
"type": "TICKETING"
}
],
"grandTotal": "149.44",
"additionalServices": [
{
"amount": "70.00",
"type": "CHECKED_BAGS"
}
]
},
"pricingOptions": {
"fareType": [
"PUBLISHED"
],
"includedCheckedBagsOnly": false
},
"validatingAirlineCodes": [
"TX"
],
"travelerPricings": [
{
"travelerId": "1",
"fareOption": "STANDARD",
"travelerType": "ADULT",
"price": {
"currency": "EUR",
"total": "149.44",
"base": "41.00"
},
"fareDetailsBySegment": [
{
"segmentId": "3",
"cabin": "ECONOMY",
"fareBasis": "ULBCOWFR",
"brandedFare": "EBASIC",
"class": "U",
"includedCheckedBags": {
"quantity": 0
}
}
]
}
]
}
There is no extra bag in the response.
Thanks