Closed ok200paul closed 2 years ago
I don't think you can set the line item IDs. You'll have to get the line item IDs from the response and handle on your end. That's at least how I manage it in my apps.
Thanks @rodjsta yeah the more I test the more it's looking like this. I'll keep banging my head off it. While I have you, how do you locate the local DB items when iterating back through the items in the response?
@ok200paul I asked a similar question to your original question a couple of years ago here.
My use case is for Invoices, but it would be the same for purchase orders.
The way I handle allocating the remote LineItemIDs to my local line items is not 100% fool proof, but I'm not sure how it could be done otherwise.
Basically, when I have the response, I iterate through all response elements and then use the invoice ContactID
+ total
to match it with the local invoice I had in the exportable batch. The first problem here is if I have more than one invoice for the same ContactID
with the exact same total
(but, this is extremely unlikely in our app for the same exportable batch).
Once I know which local invoice the response element is for, I then do a similar matching for the line items (scoped the that exact local invoice. I look for a local line item on that invoice that matches the same description
, unit_qty
and unit_amount
. Again, we wouldn't have two line items exactly the same on a single invoice.
We then use webhooks to keep everything in sync, but Xero is our source of truth.
I hope this helps.
My app is a Laravel app. Shout out if you have any other questions.
I've included a screenshot of my export job.
Nice. Thanks for taking the time on a Saturday the comprehensive response. I see how you're updating external_id_xero
locally for the LineItemIDs coming back from Xero, I've implemented this on our side to track the LineItems.
Our use case is trying to "send" local line_items
data to a draft Purchase Order on Xero, then when the sale details for a line item (a sale item) is updated locally, try to update the PO on Xero.
However, it all seems a little futile as it looks like Xero's API doesn't allow individual LineItem PUT, even if we know the LineItemId (or: I haven't discovered how to do this yet). All attempts to use loadByGUID(LineItem::class, $knownLineItemId)
return Resource Not Found
Aha! Turns out we can push new data to line items within a foreach loop, but we can't individually PUT to the LineItem API (man, Xero's API sucks..):
$lineItems = $purchaseOrderFromXero->getLineItems();
foreach ($lineItems as $xeroPOLineItem) {
$xeroPOLineItem->setQuantity($updatedQuantity)
->setUnitAmount($updateUnitAmount);
$xeroApp->save($xeroPOLineItem, true); // Save the LineItem, true means update data. LineItemID is an attribute of the object so it updates the correct Xero resource.
}
Hope this helps someone - thanks for your response here @rodjsta, it helped sort me out. Have a great weekend!
Nice work Paul. Yep, I agree the API is not always the best. I'd love to see the ability to add metadata to objects.
I was looking at my screen earlier saying this aloud!! Metadata would solve so much here.
We need to generate our own LineItemID so that we can reference them down the line, but
$lineItem->setLineItemID()
doesn't seem to work. Example:Then to test, we re-retrieve the PurchaseOrder
Is it something I'm doing, or is setLineItemID problematic as the Xero API api.xro/2.0 doesn't seem to allow individual PO line item management?
Thanks for this package, it's solid! Let me know if I can provide any more details here.