intuit / QuickBooks-V3-PHP-SDK

Official PHP SDK for QuickBooks REST API v3.0: https://developer.intuit.com/
Apache License 2.0
246 stars 246 forks source link

Unable to create expense record with more than 1 ItemBasedExpenseLineDetail line #48

Closed markwoods241 closed 7 years ago

markwoods241 commented 7 years ago

Unclear whether this is an issue with the SDK, or with the API itself...

I am finding that when using the PurchaseFacade class, creating an expense with a single line with a DetailType of ItemBasedExpenseLineDetail works fine. As soon as I add a 2nd line of the same type (even with the exact same data), the API returns an error, as follows:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2017-07-21T05:49:29.312-07:00">
    <Fault type="ValidationFault">
        <Error code="6000" element="">
            <Message>A business validation error has occurred while processing your request</Message>
            <Detail>Business Validation Error: We're sorry, QuickBooks encountered an error while calculating tax. Try reselecting the tax rate or reentering the product/service item and saving the form again. &lt;a href='https://support.qbo.intuit.com/support/help-article.cfm?faq_id=5558&amp;locale=en_GB' target=&quot;_blank&quot; title=&quot;Help&quot;&gt;Please click here for more information&lt;/a&gt;</Detail>
        </Error>
    </Fault>
</IntuitResponse>

Prior to calling the Add function on the DataService, I've captured the state of the object returned by the PurchaseFacade::create function, as follows. in case it helps to debug:

QuickBooksOnline\API\Data\IPPPurchase Object
(
    [AccountRef] => QuickBooksOnline\API\Data\IPPReferenceType Object
        (
            [name] => 
            [type] => 
            [value] => 81
        )

    [PaymentMethodRef] => 
    [PaymentRefNum] => 
    [PaymentType] => QuickBooksOnline\API\Data\IPPPaymentTypeEnum Object
        (
            [value] => Cash
        )

    [CheckPayment] => 
    [CreditCardPayment] => 
    [EntityRef] => QuickBooksOnline\API\Data\IPPReferenceType Object
        (
            [name] => 
            [type] => 
            [value] => 23
        )

    [Credit] => 
    [RemitToAddr] => 
    [TotalAmt] => 
    [Memo] => 
    [PrintStatus] => 
    [GlobalTaxCalculation] => QuickBooksOnline\API\Data\IPPGlobalTaxCalculationEnum Object
        (
            [value] => TaxExcluded
        )

    [PurchaseEx] => 
    [DocNumber] => 
    [TxnDate] => 2017-07-21
    [DepartmentRef] => 
    [CurrencyRef] => 
    [ExchangeRate] => 
    [PrivateNote] => 
    [TxnStatus] => 
    [LinkedTxn] => 
    [Line] => Array
        (
            [0] => QuickBooksOnline\API\Data\IPPLine Object
                (
                    [Id] => 
                    [LineNum] => 
                    [Description] => Employee training off site
                    [Amount] => 10
                    [LinkedTxn] => 
                    [DetailType] => QuickBooksOnline\API\Data\IPPLineDetailTypeEnum Object
                        (
                            [value] => ItemBasedExpenseLineDetail
                        )

                    [PaymentLineDetail] => 
                    [DiscountLineDetail] => 
                    [TaxLineDetail] => 
                    [SalesItemLineDetail] => 
                    [DescriptionLineDetail] => 
                    [ItemBasedExpenseLineDetail] => QuickBooksOnline\API\Data\IPPItemBasedExpenseLineDetail Object
                        (
                            [CustomerRef] => 
                            [BillableStatus] => 
                            [TaxInclusiveAmt] => 
                            [ItemBasedExpenseLineDetailEx] => 
                            [ItemRef] => QuickBooksOnline\API\Data\IPPReferenceType Object
                                (
                                    [name] => 
                                    [type] => 
                                    [value] => 5
                                )

                            [ClassRef] => 
                            [UnitPrice] => 10
                            [RatePercent] => 
                            [PriceLevelRef] => 
                            [MarkupInfo] => 
                            [Qty] => 1
                            [UOMRef] => 
                            [ItemAccountRef] => 
                            [InventorySiteRef] => 
                            [TaxCodeRef] => QuickBooksOnline\API\Data\IPPReferenceType Object
                                (
                                    [name] => 
                                    [type] => 
                                    [value] => 3
                                )

                        )

                    [AccountBasedExpenseLineDetail] => 
                    [DepositLineDetail] => 
                    [PurchaseOrderItemLineDetail] => 
                    [SalesOrderItemLineDetail] => 
                    [ItemReceiptLineDetail] => 
                    [JournalEntryLineDetail] => 
                    [GroupLineDetail] => 
                    [SubTotalLineDetail] => 
                    [TDSLineDetail] => 
                    [CustomField] => 
                    [LineEx] => 
                )

            [1] => QuickBooksOnline\API\Data\IPPLine Object
                (
                    [Id] => 
                    [LineNum] => 
                    [Description] => Employee training off site
                    [Amount] => 10
                    [LinkedTxn] => 
                    [DetailType] => QuickBooksOnline\API\Data\IPPLineDetailTypeEnum Object
                        (
                            [value] => ItemBasedExpenseLineDetail
                        )

                    [PaymentLineDetail] => 
                    [DiscountLineDetail] => 
                    [TaxLineDetail] => 
                    [SalesItemLineDetail] => 
                    [DescriptionLineDetail] => 
                    [ItemBasedExpenseLineDetail] => QuickBooksOnline\API\Data\IPPItemBasedExpenseLineDetail Object
                        (
                            [CustomerRef] => 
                            [BillableStatus] => 
                            [TaxInclusiveAmt] => 
                            [ItemBasedExpenseLineDetailEx] => 
                            [ItemRef] => QuickBooksOnline\API\Data\IPPReferenceType Object
                                (
                                    [name] => 
                                    [type] => 
                                    [value] => 5
                                )

                            [ClassRef] => 
                            [UnitPrice] => 10
                            [RatePercent] => 
                            [PriceLevelRef] => 
                            [MarkupInfo] => 
                            [Qty] => 1
                            [UOMRef] => 
                            [ItemAccountRef] => 
                            [InventorySiteRef] => 
                            [TaxCodeRef] => QuickBooksOnline\API\Data\IPPReferenceType Object
                                (
                                    [name] => 
                                    [type] => 
                                    [value] => 3
                                )

                        )

                    [AccountBasedExpenseLineDetail] => 
                    [DepositLineDetail] => 
                    [PurchaseOrderItemLineDetail] => 
                    [SalesOrderItemLineDetail] => 
                    [ItemReceiptLineDetail] => 
                    [JournalEntryLineDetail] => 
                    [GroupLineDetail] => 
                    [SubTotalLineDetail] => 
                    [TDSLineDetail] => 
                    [CustomField] => 
                    [LineEx] => 
                )

        )

    [TxnTaxDetail] => 
    [TxnSource] => 
    [TaxFormType] => 
    [TaxFormNum] => 
    [TransactionLocationType] => 
    [Id] => 
    [SyncToken] => 
    [MetaData] => 
    [CustomField] => 
    [AttachableRef] => 
    [domain] => 
    [status] => 
    [sparse] => 
)

Regards,

Mark

markwoods241 commented 7 years ago

Just to add to this...issue is not restricted to ItemBasedExpenseLineDetail lines. The same error appears if submitting multiple AccountBasedExpenseLineDetail lines, or even 1 ItemBasedExpenseLineDetail and 1 AccountBasedExpenseLineDetail in the same expense.

hlu2 commented 7 years ago

@markwoods241 Let me test on it, I want to what the actual cause may be. Will get back to you at a later time.

markwoods241 commented 7 years ago

FYI - after playing with this further today, it appears that the issue only occurs with selected tax rates. Unfortunately, one of those tax rates is the standard 20%, which will be most commonly used.

The tax code and tax rate details are as follows:

20% Standard Tax Code

      {
        "Name": "20.0% S",
        "Description": "Standard",
        "Active": true,
        "Taxable": true,
        "TaxGroup": true,
        "SalesTaxRateList": {
          "TaxRateDetail": [
            {
              "TaxRateRef": {
                "value": "4",
                "name": "SS-20.0"
              },
              "TaxTypeApplicable": "TaxOnAmount",
              "TaxOrder": 0
            }
          ]
        },
        "PurchaseTaxRateList": {
          "TaxRateDetail": [
            {
              "TaxRateRef": {
                "value": "3",
                "name": "SP-20.0"
              },
              "TaxTypeApplicable": "TaxOnAmount",
              "TaxOrder": 0
            }
          ]
        },
        "domain": "QBO",
        "sparse": false,
        "Id": "3",
        "SyncToken": "0",
        "MetaData": {
          "CreateTime": "2016-12-30T14:12:44-08:00",
          "LastUpdatedTime": "2016-12-30T14:12:44-08:00"
        }
      }

Associated Tax Rate ID 3 for Purchases

      {
        "Name": "SP-20.0",
        "Description": "VAT",
        "Active": true,
        "RateValue": 20,
        "AgencyRef": {
          "value": "1"
        },
        "TaxReturnLineRef": {
          "value": "4"
        },
        "SpecialTaxType": "NONE",
        "domain": "QBO",
        "sparse": false,
        "Id": "3",
        "SyncToken": "0",
        "MetaData": {
          "CreateTime": "2016-12-30T14:12:43-08:00",
          "LastUpdatedTime": "2016-12-30T14:12:43-08:00"
        }
      }

In case it's important...this is running on a UK sandbox account.

markwoods241 commented 7 years ago

I think I've stumbled over a blog post that outlines this same problem. The API has a known bug relating to non-US transactions that have more than one line with the same tax code (in my experience, it only seems to affect when that tax code is positive, i.e. 20%, 5%, non-EC type). It appears it was reported early last year (https://support.transactionpro.com/kb/a246/business-validation-error-were-sorry-quickbooks-encountered-an-error-while-calculating.aspx), through seems the bug is still at large.

The workaround mentioned on that page seems to be to avoid having the API calculate the tax to be applied on the Bill/Purchase/Check/etc, by sending TxnTaxDetail data...in other words, calculate the tax client side to prevent the QBO API from trying to calculate the tax and running into the bug.

I'll try and amend my client application to take this approach now, though this certainly isn't ideal...18 months and counting for what seems like a pretty fundamental bug in the API is a bit concerning!

I have raised a support ticket on the intuit developer site (case number 00050250), so I guess this can be tracked on there now, with this bug closed, unless you would rather take the approach of "patching" this in the PHP SDK somehow, and injecting the TxnTaxDetail workaround for a non-US Bill/Purchase/Check with multiple lines with the same tax code applied?

Kind Regards,

Mark

hlu2 commented 7 years ago

@markwoods241 Mark, this is a QBO bug due to GLOBALTAX_TAXAMOUNTS_MISMATCH, an internal validation error for global companies. It has been fixed for production server after v1706.734 release. However, for Sandbox, it is not fixed yet. Currently the sandbox server version is a bit outdated compared with the production server.

I will send the team an E-mail to sync the Sandbox server with production version; However, I am not sure when they will do it. For now, create your own version of "20.0% S" TaxCode and it should resolve the error.

Thanks for the detailed analysis. It also takes me a while to confirm it is a bug. Kind of sad knowing it is fixed in production but not sandbox. I will respond your support ticket as well. Have a good day.

Hao