calcinai / xero-php

A php library for the Xero API, with a cleaner OAuth interface and ORM-like abstraction.
MIT License
359 stars 261 forks source link

Best way to update Inventory Items #678

Open glaing opened 4 years ago

glaing commented 4 years ago

Hi,

I have built a plugin for my WooCommerce site which creates a queue of products that are either missing or need updating (pricing, etc) in my Xero Inventory.

It detects if the product is new or updating and executes one of two sets of code. It then adds this to an array, so I can upload it all with one saveall() command at the end of the batch.

The new product works fine, but when updating I am using loadByGUID to connect to the product, which is creating extra inefficient API calls (and is making me hit the rate-limits).

New Product:

  $new_item = new XeroPHP\Models\Accounting\Item($xero);

                $salesdetails = new XeroPHP\Models\Accounting\Item\Sale($xero);
                    $salesdetails->setAccountCode($product->xero_item_SalesDetails_AccountCode)
                    ->setUnitPrice($product->xero_item_SalesDetails_UnitPrice)
                    ->setTaxType($product->xero_item_SalesDetails_TaxType);

                $purchasedetails = new XeroPHP\Models\Accounting\Item\Purchase($xero);
                    $purchasedetails->setUnitPrice($product->xero_item_PurchaseDetails_UnitPrice)
                    ->setCOGSAccountCode($product->xero_item_PurchaseDetails_COGSAccountCode)
                    ->setAccountCode($product->xero_item_PurchaseDetails_AccountCode)
                    ->setTaxType($product->xero_item_PurchaseDetails_TaxType);

                $new_item->setCode($product->xero_item_Code)
                    ->setName($product->xero_item_Name)
                    ->setPurchaseDescription($product->xero_item_PurchaseDescription)
                    ->setDescription($product->xero_item_Description)
                    ->setIsSold($product->xero_item_IsSold)
                    ->setIsPurchased($product->xero_item_IsPurchased)
                    ->setIsTrackedAsInventory($product->xero_item_IsTrackedAsInventory)
                    ->setInventoryAssetAccountCode($product->xero_item_InventoryAssetAccountCode)
                    ->setSalesDetails($salesdetails)
                    ->setPurchaseDetails($purchasedetails);

            $sendItems[] = $new_item;

Updating Product

           $update_item = $xero->loadByGUID('Accounting\\Item', $product->xero_item_ItemID);

                $salesdetails = new XeroPHP\Models\Accounting\Item\Sale($xero);
                    $salesdetails->setAccountCode($product->xero_item_SalesDetails_AccountCode)
                    ->setUnitPrice($product->xero_item_SalesDetails_UnitPrice)
                    ->setTaxType($product->xero_item_SalesDetails_TaxType);

                $purchasedetails = new XeroPHP\Models\Accounting\Item\Purchase($xero);
                    $purchasedetails->setUnitPrice($product->xero_item_PurchaseDetails_UnitPrice)
                    ->setCOGSAccountCode($product->xero_item_PurchaseDetails_COGSAccountCode)
                    ->setAccountCode($product->xero_item_PurchaseDetails_AccountCode)
                    ->setTaxType($product->xero_item_PurchaseDetails_TaxType);

                $update_item->setDirty('Code')
                    ->setName($product->xero_item_Name)
                    ->setPurchaseDescription($product->xero_item_PurchaseDescription)
                    ->setDescription($product->xero_item_Description)
                    ->setIsSold($product->xero_item_IsSold)
                    ->setIsPurchased($product->xero_item_IsPurchased)
                    ->setIsTrackedAsInventory($product->xero_item_IsTrackedAsInventory)
                    ->setInventoryAssetAccountCode($product->xero_item_InventoryAssetAccountCode)
                    ->setSalesDetails($salesdetails)
                    ->setPurchaseDetails($purchasedetails);

            $sendItems[] = $update_item;

Which is finished off by:

$responses = $xero->saveAll($sendItems);

I already have the GUID of the inventory item stored as metadata on my WooCommerce products, so do I need to use a separate loadByGUID call each time? Or us there a better way to do this?

Thanks, George

Healyhatman commented 4 years ago

Taking Timesheets as an example

$query = $xero->load(Timesheet::class);
foreach ($array_of_employee_guids as $employee_id) {
   $query->orWhere(sprintf('EmployeeID=GUID("%s")', $employee_id));
}

$timesheets = $query->execute()