Reputation: 8616
I need to get invoices for a contact by contact Id, therefore I wrote Query 1 similar to Qusery 3 (which is working for payments). My objective is to query invoices from a field belongs to it's associated object Contact. But Query 1 returns 0 results.
Then I tried the way I querying for invoices, to query by a field belongs to Invoices. I was referring to the Xero C# code samples in GitHub. It's working and returns 10 results as expected.
Why can't I query from a ContactId field belongs to contact in an invoice?
QUERY 1 (NOT WORKING - Return 0 results, expecting 10 results)
var contact = _api.Contacts.Find().FirstOrDefault(c => c.AccountNumber == accountNumber);
returnInvoiceList =
_api.Invoices.Find()
.Where(c => c.Contact.Id == contact.Id)
.OrderBy(item => typeof(Invoice).GetProperty(
orderby, BindingFlags.Public | BindingFlags.Instance).GetValue(item))
.Skip(i * x)
.Take(x)
.ToList();
QUERY 2 (WORKING)
returnInvoiceList =
_api.Invoices.Where(string.Format("Reference == \"{0}\"", accountNumber)).Find()
.OrderBy(item => typeof(Invoice).GetProperty(
orderby, BindingFlags.Public | BindingFlags.Instance).GetValue(item))
.Skip(i * x)
.Take(x)
.ToList();
QUERY 3 (Similar pattern query to Query 1, working for payments)
returnPaymentList =
_api.Payments.Find()
.Where(c => c.Invoice.Contact.Id == contact.Id)
.OrderBy(item => typeof(Payment).GetProperty(
orderby, BindingFlags.Public | BindingFlags.Instance).GetValue(item))
.Skip(i * x)
.Take(x)
.ToList();
Upvotes: 1
Views: 1962
Reputation: 865
In your Query1, it looks like you are using a Linq .Where rather than the wrapper's open ended .Where clause. Using a Linq .Where will perform filtering on the clients side. Using the wrappers open ended .Where clause will allow filtering on the server side meaning that you will only be returned invoices that match your query.
I would suggest that you try replace this part of your query
_api.Invoices
.Find()
.Where(c => c.Contact.Id == contact.Id)
with
_api.Invoices
.Where("Contact.ContactID == Guid(\"" + contact.Id +"\")")
.Find()
to utilize server side filtering to ensure that you will only be rturened invoices that have the correct contactID.
It might also be worth your while doing something similar for how you find your contact in Query1 and how you find your payments in Query3.
It is also worth noting that you will only get back up to 100 records as the wrapper will page Invoices by default. If you expect to get back more than 100 records you will want to loop through the pages until you no longer receive any more records by also providing the method .Page(x) before .Find() where x is the page number you want.
This will be why your Query3 works but your Query1 does not. The Payments endpoint does not support paging yet in Xero's API and so you are receiving all the payments in your connected Organisation, and so filtering on the client side will be fine, but for Query1 you will only be reciving 100 invoices (because of the paging) and none of them will match your client side Linq .Where.
Cheers,
Matt
Upvotes: 5