XeroAPI / xero-php-oauth2

Xero PHP SDK for oAuth 2 generated from Xero API OpenAPI Spec 3.0
MIT License
91 stars 65 forks source link

Array of Tracking IDs breaks LineItems (400 response) #228

Closed veloeye closed 3 years ago

veloeye commented 3 years ago

I'm using v2.5.3 and experiencing an odd occurence when trying to use different TrackingOptionIDs in a loop (forgive me this may not be the correct usage of the API but I'm getting invoices created via API calls using the example code.

In my App History console I'm pushing this request into the Xero API

{ "Invoices": [ { "Type": "ACCREC", "Contact": { "ContactID": "dfb955cf-e481-437d-aa65-58e21735118b", "HasAttachments": false, "HasValidationErrors": false }, "LineItems": [ { "Description": "EVENT PAYMENT", "Quantity": 1, "UnitAmount": "162.25", "AccountCode": "004", "TaxType": "NONE", "Tracking": [ { "TrackingCategoryID": "a7eba0ea-c5eb-402e-be57-71394ca3adfe", "TrackingOptionID": "4ec1e59b-60c0-4b5c-b173-e53e46c3" } ] } ], "Date": "2021-05-05T00:00:00+01:00", "DueDate": "2021-05-31T00:00:00+01:00", "InvoiceNumber": "TEST-1792", "Reference": "reference ch_1IL4QkCrAnjl8eUYRZZul19g", "Status": "AUTHORISED", "HasAttachments": false, "HasErrors": false } ] }

Which validates fine, but elicits the API response

{ "ErrorNumber": 14, "Type": "PostDataInvalidException", "Message": "JSON request body could not be read, Error converting value \"4ec1e59b-60c0-4b5c-b173-e53e46c3\" to type 'System.Nullable`1[System.Guid]'. Path 'Invoices[0].LineItems[0].Tracking[0].TrackingOptionID', line 1, position 398." }

My code is simply

set arrays

database loop

$lineItemTracking = new XeroAPI\XeroPHP\Models\Accounting\LineItemTracking; $lineItemTracking->setTrackingCategoryID($trackingcat); $lineItemTracking->setTrackingOptionID($trackingid);

array_push($lineItemTrackings, $lineItemTracking);

$lineItem = new XeroAPI\XeroPHP\Models\Accounting\LineItem; $lineItem->setDescription($paymentline); $lineItem->setQuantity(1.0); $lineItem->setUnitAmount($payamount); $lineItem->setTaxType($payment_taxtype); $lineItem->setAccountCode($paymentcode); $lineItem->setTracking($lineItemTrackings);

array_push($lineItems, $lineItem);

loop

with the arrays being declared outside of the parent loop (I'm reading the variables from a database lookup)

Seems to be a foible of the setTracking function as when I comment that out, the two lines that I'm pulling then write themselves into a new invoice with 2 lines, codes/amounts/tax etc all correct, just seems to be adding the Tracking Options to the lineItems

If you need any further information please do let me know, this has puzzled me for best part of a day

btw if I assemble the code as a single example with the static entries using the above code, the tracking IDs do get sent, so if it's something screwy with my database loop, I apologise in advance!

Many thanks

veloeye commented 3 years ago

OK looks like a problem with the API as when I send the option name using the setOption function within the tracking array it works...

For others looking to do this the suggested format of

"Tracking": [ { "TrackingCategoryID": "a7eba0ea-c5eb-402e-be57-71394ca3adfe", "TrackingOptionID": "4ec1e59b-60c0-4b5c-b173-e53e46c3" } ]

when creating an invoice is not recognised by the API endpoint, the response elicited is:

{ "ErrorNumber": 14, "Type": "PostDataInvalidException", "Message": "JSON request body could not be read, Error converting value \"4ec1e59b-60c0-4b5c-b173-e53e46c3\" to type 'System.Nullable`1[System.Guid]'. Path 'Invoices[0].LineItems[0].Tracking[0].TrackingOptionID', line 1, position 409." }

I've had to modify the internal loop to read the actual name of the Tracking Option rather than the ID, thus:

"Tracking": [ { "TrackingCategoryID": "a7eba0ea-c5eb-402e-be57-71394ca3adfe", "Option": "----name of tracking option redacted-----" } ]

in the PHP code that I use I've modified it thus:

$lineItemTracking = new XeroAPI\XeroPHP\Models\Accounting\LineItemTracking; $lineItemTracking->setTrackingCategoryID($trackingcat); //$lineItemTracking->setTrackingOptionID($trackingid); //original code not working :S $lineItemTracking->setOption($trackingidname); $lineItemTrackings = [$lineItemTracking];

$lineItem = new XeroAPI\XeroPHP\Models\Accounting\LineItem; $lineItem->setDescription($paymentline); $lineItem->setQuantity(1.0); $lineItem->setUnitAmount($payamount); $lineItem->setTaxType($payment_taxtype); $lineItem->setAccountCode($paymentcode); $lineItem->setTracking($lineItemTrackings);

Stumbled across a post on Xero Community forum which pointed towards this, so it'd definitely a config issue with Xero API

geesh that was a painful 2 days....

rodjsta commented 3 years ago

I experienced a similar problem think that I should supply the IDs. I worked out that they had to be supplied using the names. image

veloeye commented 3 years ago

@rodjsta yeah shame it isn't documented fully that this is a requirement for multi-line invoice, it isn't clear that the format of

"Tracking": [ { "TrackingCategoryID": "a7eba0ea-c5eb-402e-be57-71394ca3adfe", "TrackingOptionID": "4ec1e59b-60c0-4b5c-b173-e53e46c3" } ]

ia NOT the correct way to add tracking categories/tracking options to a createInvoice call

ho-hum...

rodjsta commented 3 years ago

I use the Calcinai library and it doesn't matter if it's a single or multiple line item invoice... you need the names supplied. I worry that somebody may update the category/option names in the UI and my integration most likely won't work.

Fun times.