Cannot add Invoice in QBXML request due to the Customer FullName - quickbooks

When sending a CustomerQueryRq in qbxml, it returns:
500: The query request has not been fully completed.
There was a required element ("Client Name") that could not be found in QuickBooks.
So then I send a CustomerAddRq that returns:
3100: The name "Client Name" of the list element is already in use.
And the InvoiceAddRq fails saying:
3140: There is an invalid reference to QuickBooks Customer "Client Name"
in the Invoice. QuickBooks error message: The specified name is either
invalid or of the wrong type.
How could the Customer with FullName "Client Name" already be in use, but then it is not found when trying to add an Invoice for that Customer?
Am I misinterpreting these error messages?

This is your answer right here:
The specified name is either invalid or of the wrong type.
This tells me that there is NOT a customer with that exact name, but that there's a VENDOR or an EMPLOYEE or a OTHER NAME entry with the same name.
The Name field in QuickBooks is a UNIQUE key across Vendors, Employees, Other Name entries, and Customers.

Note: Always escape and trim your data and check the length before it is passed to QB. Always refer to OSR.
First of all try to find a customer by name using CustomerQueryRq xml:
// CustomerQuery Request
$name = 'John Doe';
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
<QBXMLMsgsRq onError="continueOnError">
<CustomerQueryRq>
<NameFilter>
<MatchCriterion>StartsWith</MatchCriterion>
<Name>' . $name . '</Name>
</NameFilter>
</CustomerQueryRq>
</QBXMLMsgsRq>
</QBXML>';
Parse your response.
If something is found (there could be John Doe and John Doe 1, etc), check their email addresses. If match is found, bind its QuickBooks ID to the customer in your e-commerce DB. You will refer to this ID in further requests. Skip step #3.
If nothing is found, add a new customer (step 3).
Adding a customer. Use CustomerAdd XML now:
$name = 'John Doe';
$firstname = 'John';
$lastname = 'Doe';
$address_xml = ''; // Put address XML block here
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="2.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CustomerAddRq>
<CustomerAdd>
<Name>' . $name . '</Name>
<CompanyName></CompanyName>
<FirstName>' . $firstname . '</FirstName>
<LastName>' . $lastname . '</LastName>
' . $address_xml . '
<Phone>555-555-55</Phone>
<AltPhone></AltPhone>
<Fax>555-555-55</Fax>
<Email>john#doe.com</Email>
<Contact>' . $name . '</Contact>
</CustomerAdd>
</CustomerAddRq>
</QBXMLMsgsRq>
</QBXML>';
Parse your request and store QuickBooks ID in your database to refer to it in future.
Build your InvoiceAdd XML and specify a customer ID (not Name):
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<InvoiceAddRq>
<InvoiceAdd>
<CustomerRef>
<ListID>' . $id . '</ListID>
</CustomerRef>
<!-- rest of XML -->
';
Don't forget to save QuickBooks ID of just created invoice in your database.

Related

How can I get "Time/Costs" account IDs with QBXML?

I'm running this query:
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="14.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<InvoiceQueryRq>
<IncludeLineItems>1</IncludeLineItems>
<IncludeLinkedTxns>1</IncludeLinkedTxns>
</InvoiceQueryRq>
</QBXMLMsgsRq>
</QBXML>
And I get this invoice line which is an expense created with the "Add Time/Costs" button in Quickbooks Desktop.
<InvoiceLineRet>
<TxnLineID>8E-1343336207</TxnLineID>
<Desc>License and Title</Desc>
<Rate>315</Rate>
<Amount>315.00</Amount>
<ServiceDate>2012-07-26</ServiceDate>
<SalesTaxCodeRef>
<ListID>80000002-1343060273</ListID>
<FullName>Non</FullName>
</SalesTaxCodeRef>
</InvoiceLineRet>
With most invoice lines, there's an item associated with it and I can get the account(s) associated with the item. I want to get the account ListID that's associated with this invoice line, as with other invoice lines. I can get the account name with a GeneralDetailReportQuery, but not the ID, and that report is much harder to work with as I'm importing Quickbooks data into another system.
How can I find the accountID for lines like this?

How to create an invoice for a sales order Quickbooks Desktop

I have a customer in Quickbook Desktop, so that I have generated a slaes order for the particular customer, now for the customer sales order I have to generate a invoice. . When I tried it I got the following error. How to link a quickbook desktop customer sales order to a invoice?
I tried using IDTYPE attribute. What is wrong here? Kindly help
0x80040400: QuickBooks found an error when parsing the provided XML text stream.
Parsing response.
Processing response.
Job 'create_invoice' received response: ''.
This is my sales order xml response.
{"xml_attributes"=>{},
"txn_id"=>"75-1640702627",
"time_created"=>"2021-12-28T14:43:47+00:00",
"time_modified"=>"2021-12-28T14:43:47+00:00",
"edit_sequence"=>"1640702627",
"txn_number"=>37,
"customer_ref"=>{"xml_attributes"=>{}, "list_id"=>"80000001-1640593593", "full_name"=>"Test Customer"},
"template_ref"=>{"xml_attributes"=>{}, "list_id"=>"80000008-1640593060", "full_name"=>"Custom Sales Order"},
"txn_date"=>"2021-12-28",
"ref_number"=>"18",
"bill_address"=>{"xml_attributes"=>{}, "addr1"=>"212 W. Chskskss St.", "addr2"=>"Ste.100", "addr3"=>"wqw, Parròquia d'Encamp www", "addr4"=>"Andorra"},
"bill_address_block"=>{"xml_attributes"=>{}, "addr1"=>"212 W. Chskskss St.", "addr2"=>"Ste.100", "addr3"=>"wqw, Parròquia d'Encamp www", "addr4"=>"Andorra"},
"due_date"=>"2021-12-28",
"ship_date"=>"2021-12-28",
"subtotal"=>1.0,
"sales_tax_percentage"=>0.0,
"sales_tax_total"=>0.0,
"total_amount"=>1.0,
"is_manually_closed"=>false,
"is_fully_invoiced"=>false,
"is_to_be_printed"=>true,
"is_to_be_emailed"=>false}
Trying to generate invoice for this particular sales order
Here is my invoice XML attributes that I am sending to Quickbook Desktop
xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="7.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<InvoiceAddRq >
<InvoiceAdd>
<CustomerRef>
<FullName>Test Customer</FullName >
</CustomerRef>
<BillAddress>
<Addr1>212 W. Chskskss St.</Addr1>
<Addr2>Ste.100</Addr2>
<City>wqw</City>
<State>Parròquia d'Encamp www</State>
<PostalCode>06268</PostalCode>
<Country>Andorra</Country>
</BillAddress>
<InvoiceLineAdd>
<ItemRef>
<FullName >Inspection Request</FullName>
</ItemRef>
<Desc >plants</Desc>
<Quantity >1</Quantity>
<Amount >50.00</Amount>
</InvoiceLineAdd>
<LinkToTxnID>75-1640702627<LinkToTxnID>
</InvoiceAdd>
</InvoiceAddRq>
</QBXMLMsgsRq>
</QBXML>'
First thing coming to my mind is: "Where is your closing QBXML tag?"
</QBXML>
Beside that. The SDK includes an XML Validator tool which you can use to validate the XML structure. Try to use this to see where your structure probably does not meet the requirements.

QBXML SalesOrderAdd issue

I am trying to create SalesOrder through QBWebConnector (backend - Rails + qbwc), following Onscreen Reference for Intuit Software Development Kits, and it says that SalesOrderAdd requires only CustomerRef attribute, but QBXML validator says:
Line: 10
LinePos: 9
Src Text: </SalesOrderAdd>
Reason: Element content is incomplete according to the DTD/Schema.
Expecting: ClassRef, TemplateRef, TxnDate, RefNumber, BillAddress, ShipAddress, PONumber, TermsRef, DueDate, SalesRepRef, FOB, ShipDate.
QBXML Request is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?qbxml version="7.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<SalesOrderAddRq>
<SalesOrderAdd>
<CustomerRef>
<FullName>Test customer</FullName>
</CustomerRef>
</SalesOrderAdd>
</SalesOrderAddRq>
</QBXMLMsgsRq>
</QBXML>
Why is that? Can I change this behavior somehow (omit all tags except pointed as required in Onscreen Reference)?
The OSR is... less than perfect. But it does indicate there are additional required fields.
You need to add at least one line item or group line.

how to add payment method to quickbooks through qbxml?

I'm using consolibyte php with web connector.I'm trying to create payment method add request using following xml.But i'm getting following error.but in quickbooks with that name no term existed.can you help any one?
3100: The name "cashondelivery" of the list element is already in use.
$xml='<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="8.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<PaymentMethodAddRq>
<PaymentMethodAdd>
<Name>cashondelivery</Name>
<IsActive>true</IsActive>
<PaymentMethodType>AmericanExpress</PaymentMethodType>
</PaymentMethodAdd>
</PaymentMethodAddRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
That means that cashondelivery is already in QB.
Look for deleted entries as well. You might need to check the other lists and see if it is there.

Iteration samples in Quick books using web connector

I have seen documention on iterration on QBSDK_ProGuid.pdf file(page 117).i am confusion how to issue the same query again and setting iterator value now set to Continue, and the IteratorID field set to the IteratorID value returned from the first query iteration.
<?xml version="1.0" ?>
<?qbxml version="5.0" ?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CustomerQueryRq requestID="5001" iterator="Continue"
iteratorID="{D7355385-A17B-4f5d-B34D-F34C79C3E6FC}">
<MaxReturned>10</MaxReturned>
<IncludeRetElement>ListID</IncludeRetElement>
</
CustomerQueryRq>
</QBXMLMsgsRq>
</QBXML>
I am following WCWebService sample which is provided by intuit... and getting customer data ..
can any one please provide a sample which is using iteration Concept.
Thanks !
Below is an example of using iterators to query for a customers, fetching five (5) customers at a time. This query fetches customers with the following criteria:
Modified after January 29th, 1984
OwnerID is 0 (this just makes sure we get back DataExt values (custom fields) defined in the GUI)
Your initial request will look as below. Notice that we declare the iterator=“Start” attribute to start our iterator:
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="5.0"?>
<QBXML>
<QBXMLMsgsRq onError="continueOnError">
<CustomerQueryRq requestID="1" iterator="Start">
<MaxReturned>5</MaxReturned>
<FromModifiedDate>1984-01-29T22:03:19</FromModifiedDate>
<OwnerID>0</OwnerID>
</CustomerQueryRq>
</QBXMLMsgsRq>
</QBXML>
QuickBooks will send you back a response containing the first five (5) customers that looks like below. Notice that QuickBooks has sent us back an iteratorID="..." attribute and an iteratorRemainingCount="..." attribute, indicating the ID used to identify the iterator, and the number of items left in the iterator.
<?xml version="1.0" ?>
<QBXML>
<QBXMLMsgsRs>
<CustomerQueryRs
requestID="1"
statusCode="0"
statusSeverity="Info"
statusMessage="Status OK"
iteratorRemainingCount="18"
iteratorID="{eb05f701-e727-472f-8ade-6753c4f67a46}">
<CustomerRet>
<ListID>110000-1232697602</ListID>
<TimeCreated>2009-01-23T03:00:02-05:00</TimeCreated>
<TimeModified>2009-01-23T03:00:02-05:00</TimeModified>
<EditSequence>1232697602</EditSequence>
<Name>10th Customer</Name>
<FullName>10th Customer</FullName>
<IsActive>true</IsActive>
<Sublevel>0</Sublevel>
<Balance>0.00</Balance>
<TotalBalance>0.00</TotalBalance>
<SalesTaxCodeRef>
<ListID>10000-1232327562</ListID>
<FullName>Tax</FullName>
</SalesTaxCodeRef>
<ItemSalesTaxRef>
<ListID>10000-1232327661</ListID>
<FullName>Out of State</FullName>
</ItemSalesTaxRef>
<JobStatus>None</JobStatus>
</CustomerRet>
... 4 more customer records will go here ...
</CustomerQueryRs>
</QBXMLMsgsRs>
</QBXML>
You'll then check the iteratorRemainingCount attribute and, if it's greater than 0, send your next request using the iteratorID attribute. Remember, every subsequent request request using this iterator must use the same search criteria and that search criteria must be sent with every request.
So, in this case, every request for the next part of the iterator will resend the <MaxReturned>, <FromModifiedDate>, and <OwnerID> elements. Notice that we send the returned iteratorID="..." attribute from the previous response, and declare the iterator="Continue" attribute indicating we want to continue fetching from an existing iterator:
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="5.0"?>
<QBXML>
<QBXMLMsgsRq onError="continueOnError">
<CustomerQueryRq
requestID="2"
iterator="Continue"
iteratorID="{eb05f701-e727-472f-8ade-6753c4f67a46}">
<MaxReturned>5</MaxReturned>
<FromModifiedDate>1984-01-29T22:03:19</FromModifiedDate>
<OwnerID>0</OwnerID>
</CustomerQueryRq>
</QBXMLMsgsRq>
</QBXML>
This process will repeat until there are no more items left in the iterator. On each response, you'll check the iteratorRemainingCount attribute, and if it's greater than 0, you'll issue another request to get the next part of the iterator.
Eventually, you'll notice that the iteratorRemainingCount attribute will dwindle to zero (0) at which point you'll stop issuing requests, because the iterator has no more records to return. If you do issue another request, you'll get back an error as the iterator has, at this point, expired.
<?xml version=“1.0” ?>
<QBXML>
<QBXMLMsgsRs>
<CustomerQueryRs
requestID="5"
statusCode="0"
statusSeverity="Info"
statusMessage="Status OK"
iteratorRemainingCount="0"
iteratorID="{eb05f701-e727-472f-8ade-6753c4f67a46}">
<CustomerRet>
<ListID>1B0000-1232697643</ListID>
<TimeCreated>2009-01-23T03:00:43-05:00</TimeCreated>
<TimeModified>2009-01-23T03:00:43-05:00</TimeModified>
<EditSequence>1232697643</EditSequence>
<Name>Pat Daniels</Name>
<FullName>Pat Daniels</FullName>
<IsActive>true</IsActive>
<Sublevel>0</Sublevel>
<Balance>0.00</Balance>
<TotalBalance>0.00</TotalBalance>
<SalesTaxCodeRef>
<ListID>10000-1232327562</ListID>
<FullName>Tax</FullName>
</SalesTaxCodeRef>
<ItemSalesTaxRef>
<ListID>10000-1232327661</ListID>
<FullName>Out of State</FullName>
</ItemSalesTaxRef>
<JobStatus>None</JobStatus>
</CustomerRet>
... 4 more customer records will go here ...
</CustomerQueryRs>
</QBXMLMsgsRs>
</QBXML>

Resources