ruckus / quickbooks-ruby

Quickbooks Online REST API V3 - Ruby
MIT License
374 stars 302 forks source link

Canadian Tax Line Error #529

Open vanboom opened 4 years ago

vanboom commented 4 years ago

This is probably user error but I think worth mentioning as an issue for posterity.

I am building an invoice in Canadian Quickbooks and assigning the TransactionTaxDetail like this...

  txn_tax_detail = Quickbooks::Model::TransactionTaxDetail.new
  code = @tax_code_service.find_by(:name, tc).entries.first
  tld = Quickbooks::Model::TaxLineDetail.new(:tax_rate_ref=>code)
  txn_tax_detail.lines << tld

Adding the TaxLine like this results in a Quickbooks Business Validation Error: TxnTaxDetail.TaxLine.DetailTypeEnum is missing in the request

It appears that quickbooks-ruby is creating the TaxLine wrapper automatically but the TaxLine element is missing the detail type attribute.

<TxnTaxDetail>
<TaxLine>
<NetAmountTaxable>0.0</NetAmountTaxable>
<TaxInclusiveAmount>0.0</TaxInclusiveAmount>
<OverrideDeltaAmount>0.0</OverrideDeltaAmount>
<TaxPercent>0.0</TaxPercent>
<TaxRateRef>
<Id>3</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2016-01-27T21:58:46-0800</CreateTime>
<LastUpdatedTime>2016-01-27T21:58:46-0800</LastUpdatedTime>
</MetaData>
<Name>Zero-rated</Name>
<Description>Zero-rated</Description>
<Active>true</Active>
<Taxable>true</Taxable>
<TaxGroup>true</TaxGroup>
<SalesTaxRateList>
<TaxRateDetail>
<TaxRateRef name="GST/HST ZR">4</TaxRateRef>
<TaxTypeApplicable>TaxOnAmount</TaxTypeApplicable>
<TaxOrder>0</TaxOrder>
</TaxRateDetail>
</SalesTaxRateList>
<PurchaseTaxRateList>
<TaxRateDetail>
<TaxRateRef name="GST/HST (ITC) ZR">3</TaxRateRef>
<TaxTypeApplicable>TaxOnAmount</TaxTypeApplicable>
<TaxOrder>0</TaxOrder>
</TaxRateDetail>
</PurchaseTaxRateList>
</TaxRateRef>
</TaxLine>
<TaxLine>
<NetAmountTaxable>0.0</NetAmountTaxable>
<TaxInclusiveAmount>0.0</TaxInclusiveAmount>
<OverrideDeltaAmount>0.0</OverrideDeltaAmount>
<TaxPercent>0.0</TaxPercent>
<TaxRateRef>
<Id>5</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2016-01-27T21:58:46-0800</CreateTime>
<LastUpdatedTime>2016-01-27T21:58:46-0800</LastUpdatedTime>
</MetaData>
<Name>HST ON</Name>
<Description>Harmonized federal and provincial tax (Ontario)</Description>
<Active>true</Active>
<Taxable>true</Taxable>
<TaxGroup>true</TaxGroup>
<SalesTaxRateList>
<TaxRateDetail>
<TaxRateRef name="HST ON">12</TaxRateRef>
<TaxTypeApplicable>TaxOnAmount</TaxTypeApplicable>
<TaxOrder>0</TaxOrder>
</TaxRateDetail>
</SalesTaxRateList>
<PurchaseTaxRateList>
<TaxRateDetail>
<TaxRateRef name="HST (ITC) ON">11</TaxRateRef>
<TaxTypeApplicable>TaxOnAmount</TaxTypeApplicable>
<TaxOrder>0</TaxOrder>
</TaxRateDetail>
</PurchaseTaxRateList>
</TaxRateRef>
</TaxLine>
</TxnTaxDetail>

Notice the TaxLine entries are missing the DetailType attribute, which should be TaxLineDetail.

ruckus commented 4 years ago

Thanks for the feedback. Yes it does look like the library is not auto-inserting the DetailType. I pulled up some of my own code which uses taxes and it looks like this:

          tax_detail = Quickbooks::Model::TransactionTaxDetail.new
          tax_detail.txn_tax_code_ref = Quickbooks::Model::BaseReference.new(invoice_transaction_tax_code_rate_ref())
          tax_detail.total_tax = supplier_order.total_tax

          tax_line = Quickbooks::Model::TaxLine.new
          tax_line.amount = tax_detail.total_tax
          tax_line.detail_type = 'TaxLineDetail'

          tax_line_detail = Quickbooks::Model::TaxLineDetail.new
          tax_line_detail.percent_based = true
          tax_line_detail.net_amount_taxable = supplier_order.total_excluding_taxes_cents
          tax_line_detail.tax_percent = supplier_order.tax_percent_rate.to_f
          tax_line_detail.tax_rate_ref = Quickbooks::Model::BaseReference.new(invoice_transaction_tax_detail_rate_ref())
          tax_line.tax_line_detail = tax_line_detail

          tax_detail.lines = [tax_line]
          invoice.txn_tax_detail = tax_detail

So yeah I am doing it pretty manually.

vanboom commented 4 years ago

Thanks @ruckus, oddly this just started happening with no code changes on our end.

When I use your method above to build the TaxLine manually, I get a different error...

Required param missing, need to supply the required value for the API: Required parameter TxnTaxDetail.TaxLineDetail.TaxLine.TaxRateRef is missing in the request

This is very odd, when I specify the TaxRateRef by setting .tax_rate_id, the invoice is accepted without error.

        tl = Quickbooks::Model::TaxLine.new(detail_type: "TaxLineDetail")
        tld = Quickbooks::Model::TaxLineDetail.new
        tld.percent_based = true
        #tld.tax_rate_ref = code  <-- this causes an error
        tld.tax_rate_id = code.id
        tl.tax_line_detail = tld
        txn_tax_detail.lines ||= []
        txn_tax_detail.lines << tl

The generated XML is different (working version on the right)... diff

I am not sure why things stopped working, possibly a change on the QBO side so I am trying to post as much debug info as possible if that helps.

ruckus commented 4 years ago

I am using a numeric reference to the tax_rate_ref (which is not clear from your right hand value of code). So to clarify that code from my end:


def invoice_transaction_tax_detail_rate_ref
  184
end

...
tax_line_detail.tax_rate_ref = Quickbooks::Model::BaseReference.new(invoice_transaction_tax_detail_rate_ref())
...

What is the value of your code in

#tld.tax_rate_ref = code <-- this causes an error

?

averydev commented 2 years ago

I had an issue when creating new QB invoices that were untaxed for QB Canada. Ultimately I needed to set global_tax_calculation to "NotApplicable". Hope this saves someone some pain.