intuit / QuickBooks-V3-DotNET-SDK

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

Batch operation throws when creating Customer with a ParentRef #197

Closed pablo-martinez closed 3 years ago

pablo-martinez commented 3 years ago

Even though I am specifying a ParentRef, the batch.Execute() operation keeps throwing "Validation Exception was thrown.Details:ParentRef is either required or not if Job is true or false.."

var customer = new Customer();
customer.DisplayName = "Aything";
customer.IsProject = true;
customer.BillWithParent = true;
customer.Job = true;
customer.ParentRef = new ReferenceType { Value = "123" };

batch.Add(customer, "bID1", OperationEnum.create);

What is wrong here? The Value specified in the ReferenceType is of an existing Customer in QuickBooks.

nimisha84 commented 3 years ago

I think there is a JobSpecified too, right? The .Net SDK was built long back when Nullable types was not used as a part of this SDK. So, you need to set the corresponding property ending in specified for the value to be picked in. You can enable logs to see that and confirm too.

pablo-martinez commented 3 years ago

This is all there is. I am trying to create a sub-customer so it can be imported as a Project. What am I missing here? How should I be setting this customer object?

nimisha84 commented 3 years ago

Oh, I forgot to add that Project create is not yet supported via API. So, SDK does not supports it either. You still need to create it via QBO product and can then read it to check if it is a project or a sub customer

pablo-martinez commented 3 years ago

I know Project is not supported. I am trying to create a Sub Customer with a parent Customer.

nimisha84 commented 3 years ago

Then isProject should be false. Can you generate the log files and share here?

pablo-martinez commented 3 years ago

I was able to get it working through the REST API. The only difference I see is the Value property in ParentRef is PascalCase, while the API expects camelCase. I have no idea if this is causing the issue, but batch.Execute() has no problem.. It's the API who is returning the error.

nimisha84 commented 3 years ago

ok, I will test it and create a bug but this will be fixed only in the next qtr release(arnd Aug) if at all it is a bug. I would suggest try using the dataservice call too to test this out and then compare logs of both Batch n dataservice call to see if something is amiss.

pablo-martinez commented 3 years ago

var result = service.Add(customer) as Customer;

Giving the same result (an exception).

nimisha84 commented 3 years ago

Is this the right Id for parent customer? 123 ?

Again, I do need the full logs - request and exception response. Steps are in the readme.

pablo-martinez commented 3 years ago

As I said in my first post, "The Value specified in the ReferenceType is of an existing Customer in QuickBooks."

It's not 123, it really is 121... but for the case it's irrelevant because you will not have access to my same company data. It was an example but the ID exists.

Here are the logs (I just hid the company Id for privacy purposes):

2021-05-24 17:52:09.496 -04:00 [INF] Logger is initialized
2021-05-24 17:52:09.793 -04:00 [VRB]  RequestUrl: https://quickbooks.api.intuit.com/v3/company/****************/customer?minorversion=57&requestid=8242f30c15ab4ec9a5b1d1baf5be3dd4
2021-05-24 17:52:09.808 -04:00 [VRB] Logging all headers in the request:
2021-05-24 17:52:09.818 -04:00 [VRB] Content-Type-application/xml
2021-05-24 17:52:09.829 -04:00 [VRB] Request Payload:<?xml version="1.0"?>
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.intuit.com/finance/v3">
  <DisplayName>Prueba</DisplayName>
  <ParentRef>121</ParentRef>
</Customer>
2021-05-24 17:52:10.680 -04:00 [VRB]  Response Intuit_Tid header: 1-60ac200a-3d2f4777288d2fce1967deb1, Response Payload: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2021-05-24T14:52:11.007-07:00"><Fault type="ValidationFault"><Error code="6150" element="Job"><Message>ParentRef Required Error</Message><Detail>ParentRef is either required or not if Job is true or false.</Detail></Error></Fault></IntuitResponse>
2021-05-24 17:52:11.389 -04:00 [VRB] Intuit.Ipp.Exception.IdsException: BadRequest. Details: ParentRef is either required or not if Job is true or false. , 
 ---> Intuit.Ipp.Exception.ValidationException: Validation Exception was thrown.Details:ParentRef is either required or not if Job is true or false..
   --- End of inner exception stack trace ---
pablo-martinez commented 3 years ago

This case is very simple to reproduce:

Batch batch = service.CreateNewBatch();

var customer = new Customer();
customer.DisplayName = "Aything";
customer.IsProject = true;
customer.BillWithParent = true;
customer.Job = true;
customer.ParentRef = new ReferenceType { Value = "123" };

batch.Add(customer, "bID1", OperationEnum.create);

batch.Execute();
nimisha84 commented 3 years ago

set IsProject to false and then try. If that does not work, I will try out tonight as I need to log in into another machine and update you.

nimisha84 commented 3 years ago

check this- internal static Customer CreateCustomer(ServiceContext context) (https://github.com/IntuitDeveloper/SampleApp-CRUD_.Net_Oauth2/blob/master/SampleApp_CRUD_.Net/SampleApp_CRUD_.Net/Helper/QBOHelper.cs) It does have specified fields set which you are missing too.

nimisha84 commented 3 years ago

The above repo has samples for all entities. You can use it to validate your code.

nimisha84 commented 3 years ago

but make sure to read the docs to see which fields are supported vs not

pablo-martinez commented 3 years ago

I already tried with IsProject set to false and it still didn't work. Just to be clear, I was able to create a Customer entity with no problems. The issue is when specifying ParentRef, as I showed in my example. It is a very simple example, please give it a try, I already tried a thousand different ways.

MatthewSteeples commented 3 years ago

I think there is a JobSpecified too, right?

@pablo-martinez your sample code is not setting JobSpecified to true (in addition to Job)

pablo-martinez commented 3 years ago

I think there is a JobSpecified too, right?

@pablo-martinez your sample code is not setting JobSpecified to true (in addition to Job)

Like that, it gets created, but the problem is it doesn't show up when you want to create a project with the "Convert from sub-customer" functionality.

pablo-martinez commented 3 years ago

FYI, when I do this from Node, it works perfectly using the REST API and I can import the sub-customer as a project:

{
    "BatchItemRequest": [{
        "bId": "bid1",
        "Customer": {
            DisplayName: "Anything",
            ParentRef: { Value: "123" },
            BillWithParent: true,
            Job: true,
            IsProject: true
        } // Projects are really created as sub-customers in Quickbooks
        "operation": "create"
    }]
}
nimisha84 commented 3 years ago

Are you using any minorversion in the node js rest api call?

pablo-martinez commented 3 years ago

No

nimisha84 commented 3 years ago

RequestUrl: https://sandbox-quickbooks.api.intuit.com/v3/company/123146090856284/batch?minorversion=57&requestid=2491d7e22d9a4fa0a7cc82cb3e0ab192 2021-05-25 01:01:19.030 -07:00 [Verbose] Request Payload:{"BatchItemRequest":[{"Customer":{"ParentRef":{"value":"123"},"DisplayName":"Aything"},"bId":"bID1","operation":"create"}]} [01:01:19 VRB] Request Payload:{"BatchItemRequest":[{"Customer":{"ParentRef":{"value":"123"},"DisplayName":"Aything"},"bId":"bID1","operation":"create"}]} 2021-05-25 01:01:19.601 -07:00 [Verbose] Response Intuit_Tid header: 1-60acaea0-5255be84716cd9cb38290cf2, Response Payload: {"BatchItemResponse":[{"Fault":{"Error":[{"Message":"ParentRef Required Error","Detail":"ParentRef is either required or not if Job is true or false.","code":"6150","element":"Job"}],"type":"ValidationFault"},"bId":"bID1"}],"time":"2021-05-25T01:00:33.024-07:00"} [01:01:19 VRB] Response Intuit_Tid header: 1-60acaea0-5255be84716cd9cb38290cf2, Response Payload: {"BatchItemResponse":[{"Fault":{"Error":[{"Message":"ParentRef Required Error","Detail":"ParentRef is either required or not if Job is true or false.","code":"6150","element":"Job"}],"type":"ValidationFault"},"bId":"bID1"}],"time":"2021-05-25T01:00:33.024-07:00"} 2021-05-25 01:01:19.613 -07:00 [Verbose] Got the response from service.

Logs generated from your code.

You can clearly see the properties are not setting fine as the corresponding properties ending in specified are not set. Here is the same code in .Net for your node js code- DataService dataService = new DataService(context); Batch batch = dataService.CreateNewBatch();

        var customer1 = new Customer();
        customer1.DisplayName = "Aything";
        customer1.IsProject = true;
        customer1.IsProjectSpecified = true;
        customer1.BillWithParent = true;
        customer1.BillWithParentSpecified = true;
        customer1.Job = true;
        customer1.JobSpecified = true;
        customer1.ParentRef = new ReferenceType { Value = "1" };

        batch.Add(customer1, "bID1", OperationEnum.create);

        batch.Execute();

Hopefully, this should work

clement911 commented 3 years ago

FYI https://github.com/better-reports/QuickBooksSharp#batch now supports batch operations. Because it uses nullable properties, there is no need to bother with the *Specified properties.

pablo-martinez commented 3 years ago

RequestUrl: https://sandbox-quickbooks.api.intuit.com/v3/company/123146090856284/batch?minorversion=57&requestid=2491d7e22d9a4fa0a7cc82cb3e0ab192 2021-05-25 01:01:19.030 -07:00 [Verbose] Request Payload:{"BatchItemRequest":[{"Customer":{"ParentRef":{"value":"123"},"DisplayName":"Aything"},"bId":"bID1","operation":"create"}]} [01:01:19 VRB] Request Payload:{"BatchItemRequest":[{"Customer":{"ParentRef":{"value":"123"},"DisplayName":"Aything"},"bId":"bID1","operation":"create"}]} 2021-05-25 01:01:19.601 -07:00 [Verbose] Response Intuit_Tid header: 1-60acaea0-5255be84716cd9cb38290cf2, Response Payload: {"BatchItemResponse":[{"Fault":{"Error":[{"Message":"ParentRef Required Error","Detail":"ParentRef is either required or not if Job is true or false.","code":"6150","element":"Job"}],"type":"ValidationFault"},"bId":"bID1"}],"time":"2021-05-25T01:00:33.024-07:00"} [01:01:19 VRB] Response Intuit_Tid header: 1-60acaea0-5255be84716cd9cb38290cf2, Response Payload: {"BatchItemResponse":[{"Fault":{"Error":[{"Message":"ParentRef Required Error","Detail":"ParentRef is either required or not if Job is true or false.","code":"6150","element":"Job"}],"type":"ValidationFault"},"bId":"bID1"}],"time":"2021-05-25T01:00:33.024-07:00"} 2021-05-25 01:01:19.613 -07:00 [Verbose] Got the response from service.

Logs generated from your code.

You can clearly see the properties are not setting fine as the corresponding properties ending in specified are not set. Here is the same code in .Net for your node js code- DataService dataService = new DataService(context); Batch batch = dataService.CreateNewBatch();

        var customer1 = new Customer();
        customer1.DisplayName = "Aything";
        customer1.IsProject = true;
        customer1.IsProjectSpecified = true;
        customer1.BillWithParent = true;
        customer1.BillWithParentSpecified = true;
        customer1.Job = true;
        customer1.JobSpecified = true;
        customer1.ParentRef = new ReferenceType { Value = "1" };

        batch.Add(customer1, "bID1", OperationEnum.create);

        batch.Execute();

Hopefully, this should work

Setting each and every [*]Specified property to true is what worked for me. Thank you very much for the solution.

FYI https://github.com/better-reports/QuickBooksSharp#batch now supports batch operations. Because it uses nullable properties, there is no need to bother with the *Specified properties.

Thanks for that, I will definitely have to give it a try because the official library seems deprecated and is very counter-intuitive. Also and they don't seem to want to make changes to it in the near future.

clement911 commented 3 years ago

100% agree, that's why I created QuickBooksSharp. The official library is quite hard to use and seems frozen in time.

nimisha84 commented 3 years ago

Just to clarify. The official lib is not deprecated yet. We do update it for any new QBO API releases every quarter. good to know your issue is resolved now.

130990 commented 2 years ago

Hi @pablo-martinez I'm trying to do as same as you and store a Project(customer) in QBO, I can save the customer with all *Specified properties set on true as you metioned, but the problem that I got it's IsProject attribute it's always stored as false in QBO no matter how many time I set it as true... I'm working in a .NetCore API in C#, following is sample of how I set properties for customer to store:

>                     SaveCustomerDTO customerData = new SaveCustomerDTO();
>                     customerData.query = new Intuit.Ipp.Data.Customer()
>                     {
>                           ParentRef = new Intuit.Ipp.Data.ReferenceType() { Value = jobData.qbCst_id.ToString()},
>                           MetaData = new Intuit.Ipp.Data.ModificationMetaData() { CreateTime = DateTime.Now, LastUpdatedTime = DateTime.Now },
>                           DisplayName = "prj_Job_" + jobData.id,
>                           PrintOnCheckName = "prj_Job_" + jobData.id,
>                           BillWithParent = true,
>                           BillWithParentSpecified  = true,
>                           Job = true,
>                           JobSpecified = true,
>                           IsProject = true,     
>                           IsProjectSpecified= true,                                                
>                           Active = true,
>                           ActiveSpecified =true
>                     };

At end could you save customer as project in QBO? .... It's beacuse in QBO API Doc said this IsProject property for Customer is "read only", but I'm not pretty sure if it's.

Thanks

nimisha84 commented 2 years ago

Projects cannot be created from api side, only QBO UI. That is why u don't see this set when u try to push an update/create