intuit / QuickBooks-V3-DotNET-SDK

.Net SDK for QuickBooks REST API v3 services
Apache License 2.0
107 stars 140 forks source link

DataService - Unable to use TaxService API to create new TaxCode or TaxRate #161

Closed jnlon closed 4 years ago

jnlon commented 4 years ago

Hello! I am trying to create a new Tax Code and associated Tax Rate using DataService from the SDK. According to API documentation for TaxCode and TaxRate, we should use the TaxService API resource to create these entities. I tried using DataService to create a new 'GST' tax code like so:

dataservice.Add<Q.TaxService>(new Q.TaxService
{
    TaxCode = "GST",
    TaxRateDetails = new Q.TaxRateDetails[]
    {
        new Q.TaxRateDetails
        {
            TaxRateName = "GST",
            RateValue = 5.0m,
            TaxApplicableOn = Q.TaxRateApplicableOnEnum.Sales,
            TaxAgencyId = craId // TaxAgency ID of the Canada Revenue Agency
        }
    }
});

Running this code gives me the following exception:

IdsException: BadRequest. Details: Operation Could not find resource for relative : /v3/company/.../taxservice of full path: https://c51.sandbox.qbo.intuit.com/qbo51/v3/company/.../taxservice?minorversion=52&requestid=d6b495206d634ffe8dce3b7fe20176f6 is not supported. ,
at void Intuit.Ipp.Exception.IdsExceptionManager.HandleException (IdsException idsException)
at T Intuit.Ipp.DataService.DataService.Add<T> (T entity)
ValidationException: Validation Exception was thrown.Details:Operation Could not find resource for relative : /v3/company/.../taxservice of full path: https://c51.sandbox.qbo.intuit.com/qbo51/v3/company/.../taxservice?minorversion=52&requestid=d6b495206d634ffe8dce3b7fe20176f6 is not supported..

(Note: I have replaced my actual Realm ID with '...')

It looks like DataService is POSTing to the wrong URL, it should be /v3/company/(REALM_ID)/taxservice/taxcode instead of /v3/company/(REALM_ID)/taxservice according to the API documentation. I can successfully create a new TaxCode and TaxRate using HttpClient like so:

string craId = "...";        // "Canada Revenue Agency" ID retrieved from querying TaxAgency resource
string realmId = "...";      // Realm ID retrieved from Intuit page "Manage Sandbox Companies"
string accessToken = "..."   // Access token retrieved from Intuit page "OAuth 2.0 Playground"

using (var client = new HttpClient()) {
    // Set access token
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    // Some fields do not serialize correctly with newtonsoft using QB types, use anonymous objects instead
    var json = JsonConvert.SerializeObject(
        new // Q.TaxService
        {
            TaxCode = "GST",
            TaxRateDetails = new object[] // Q.TaxRateDetails[]
            {
                new // Q.TaxRateDetails
                {
                    TaxRateName = "GST",
                    RateValue = 5.0m,
                    TaxApplicableOn = Q.TaxRateApplicableOnEnum.Sales,
                    TaxAgencyId = craId
                }
            }
        });

    // Set endpoint path correctly
    UriBuilder endpoint = new UriBuilder("https://sandbox-quickbooks.api.intuit.com/");
    endpoint.Path = $"/v3/company/{realmId}/taxservice/taxcode";
    endpoint.Query = "minorversion=55";

    // Execute the POST
    var data = new StringContent(json, Encoding.UTF8, "application/json");
    var response = await client.PostAsync(endpoint.Uri, data);
    string result = await response.Content.ReadAsStringAsync();
}

It would be nice if I could avoid HttpClient and use only DataService for this.

Thanks!

Other Details

rkasaraneni20 commented 4 years ago

@jnlon Can you please use GlobalTaxService instead of dataservice for TaxService entity. One such example is here