The QB SDK supports modification of many list and transaction objects. Modification is accomplished by sending a mod request, which follow the naming convention of: ObjectTypeModRq, where ObjectType represents some the object to be modified. For a complete listing, see the QuickBooks objects and operations accessible with the SDK.
When modifying transactions you need to keep in mind that a transaction can be understood as having two parts, a body and a set of line items and line item groups. The body can be modified alone, without touching the line item data. However, if the application touches any of the line items or line item groups, you need to be careful. Specifically, any line item not specifically identified in a modify request will be deleted, which means:
The following table lists the different types of mod, delete, and void operations covered by this page and the corresponding request messages and qbXML required to perform each operation.
To do this: | Use this request message and required attributes: |
---|---|
To clear some properties of a list object | ObjectTypeModRq with listID and editSequence; send null/empty qbXML elements for the properties to be cleared |
To modify some properties of a list object | ObjectTypeModRq with listID and editSequence send qbXML elements with new values for the properties to be modified |
To delete a list object | ListDelRq with objectType and listID |
To clear some body properties of a transaction object | ObjectTypeModRq with transactionID and editSequence; send null/empty qbXML elements for the properties to be cleared, omit line item list |
To modify some body properties only of a transaction | ObjectTypeModRq with transactionID and editSequence; send qbXML elements with new values for the properties to be modified, omit line item list |
To delete a transaction object, including transaction body and all line items. | TxnDelRq with txnType and txnID |
To clear some line item properties of a transaction | ObjectTypeModRq with transactionID and editSequence send null/empty qbXML elements for the properties to be cleared, be sure to identify all line items to be retained |
To modify line item properties of a transaction | ObjectTypeModRq with transactionID and editSequence send qbXML elements with new values for the properties to be updated, be sure to identify all line items to be retained |
To delete a line item | ObjectTypeModRq with transactionID and editSequence specify line items to be retained, others will be deleted |
To add a line item | ObjectTypeModRq with transactionID and editSequence for the new line, include an ObjectTypeLineMod, with its TxnLineID set to -1, be sure to identify all lines to be retained. |
To void a transaction object | TxnVoidRq with txnType and txnID |
Whenever a modify request is processed successfully, the response message will include a detail element, of type ObjectTypeRet that holds the updated state of the object.
Every time an object is changed, whether the change is made through the user interface or through the SDK, QuickBooks changes the value of its EditSequence property. Responses to add, modify, or query requests from the SDK include the current value of the EditSequence property for every object in the response set. If an application sends a request to modify an object, QuickBooks compares the EditSequence sent with the request (which identifies the application’s version of the object) with the current EditSequence. If the two match, it confirms that the application is working with the current state of the object, and QuickBooks will process the request; If the two don’t match, it means that the object’s state has changed in QuickBooks since the application obtained its copy. In this case, QuickBooks will reject the request and return an error.
To clear the current value of one or more properties of an object, send a modify request message that supplies an empty value for the property or properties to be cleared. The following example shows an ItemServiceModRq message that sends empty values in the ParentRef, SalesPrice and PurchaseCost tags. The result of this request will be the clearing of these properties.
<QBXML>
<QBXMLMsgsRq onError = "continueOnError">
<ItemServiceModRq requestID = "101">
<ItemServiceMod>
<ListID>60000-933272656</ListID>
<EditSequence>933272656</EditSequence>
<ParentRef>
<ListID></ListID>
</ParentRef>
<SalesAndPurchaseMod>
<SalesPrice></SalesPrice>
<PurchaseCost></PurchaseCost>
</SalesAndPurchaseMod>
</ItemServiceMod>
</ItemServiceModRq>
</QBXMLMsgsRq>
</QBXML>
Some points to notice about this request:
If a reference property is to be cleared, there are four ways to specify this in the request:
Provide an empty reference:
<ClassRef />
Provide an empty ListID:
<ClassRef>
<ListID></ListID>
</ClassRef>
Provide an empty FullName tag:
<ClassRef>
<FullName></FullName>
</ClassRef>
Provide empty ListID and and FullName tags:
<ClassRef>
<ListID></ListID>
<FullName></FullName>
</ClassRef>
If a property that is an aggregate is to be cleared, the request can either provide empty tags for all elements of the aggregate, or simply provide an empty tag for the aggregate:
<BillAddress>
<Addr1></Addr1>
<Addr2></Addr2>
<Addr3></Addr3>
<Addr4></Addr4>
<City></City>
<State></State>
<PostalCode></PostalCode>
<Country></Country>
</BillAddress>
or
<BillAddress />
Some points to notice about this request:
To modify the current value of one or more properties of an object, send a modify request message that supplies the new value for the property or properties to be modified. The following example shows a PurchaseOrderModRq message that sends a new value for the ShipToEntityRef property, The result of this request will be the replacement of the current value with the value specified in the request.
This request is working with a transaction object, but it is touching only the body of the transactions, so the special considerations for working with line items do not apply.
<PurchaseOrderModRq>
<PurchaseOrderMod>
<TxnID>100-100052155</TxnID>
<EditSequence>100052155</EditSequence>
<ShipToEntityRef>
<FullName>Tom Jones</FullName>
</ShipToEntityRef>
</PurchaseOrderMod>
</PurchaseOrderModRq>
Some points to notice about this request:
If the application is modifying a transaction and needs to modify properties only in the body of the transaction (not making any changes to the transaction’s line item table), there is no need to explicitly retain the line items, and the modify request should omit any reference to any line items. The line item table will be retained as is, and the request will process more quickly than if would if the line items were explicitly retained.
If you are going to clear or modify any value of any transaction line item, your modification request must explicitly retain all of the line items that should be retained. Failure to explicitly retain a line item will be understood as a request to drop it.
Note
Note
Unless noted otherwise, if you are making changes to any line item, you need to specify all of the line items to be retained in the transaction. Otherwise, any lines omitted in the transaction Mod operation will be dropped!
To retain a line item, the application does not have include all of the item’s properties in the request. It is only necessary for the request to include the line item’s TxnLineID, as follows:
<PurchaseOrderLineMod>
<TxnLineID>101</TxnLineID>
</PurchaseOrderLineMod>
This will retain the current state of the named line item.
To modify a line item, specify the line to be modified with its TxnLineID and, as in the other modification requests, construct a request message (either with QBFC or by writing the qbXML) with the qbXML tags for the line item properties that need to be modified.
The following example shows a PurchaseOrderModRq message that modifies two line items in a transaction table and retains one unchanged. For line item 101 it changes the values of the rate and quantity properties; for line item 102 it changes the value of its description property, for line item 103 it identifies the line item as one to be retained in its current state, as described above.
<PurchaseOrderModRq>
<PurchaseOrderMod>
<TxnID>100-100052155</TxnID>
<EditSequence>100052155</EditSequence>
.
.
.
<!—- modifying the quantity and rate of the itemLine1 -->
<PurchaseOrderLineMod>
<TxnLineID>101</TxnLineID>
<Quantity>12</Quantity>
<Rate>10.00</Rate>
</PurchaseOrderLineMod>
<!—- modifying the description of the itemLine2 -->
<PurchaseOrderLineMod>
<TxnLineID>102</TxnLineID>
<Desc>new description</Desc>
</PurchaseOrderLineMod>
<!— even if the itemline3 doesn’t change, it needs to be specified in the Modify request.
Omitting the itemline3 would be interpreted as a deletion! -->
<PurchaseOrderLineMod>
<TxnLineID>103</TxnLineID>
</PurchaseOrderLineMod>
</PurchaseOrderMod>
</PurchaseOrderModRq>
You can add new lines to an existing transaction. However, a common mistake is to attempt this with the ItemLineAdd aggregate. That won’t work. You have to use the ItemLineMod aggregate with the TxnLineID element set to -1 and then specify the new data for that new line.
This new line can be used for a new line item, or it can be an empty line used as a separator or comment in the transaction table.
To delete a line item from the table, simply omit it from the Modify request.
The procedures for modifying line groups are parallel to those for individual line items:
To retain a line group, the application does not have include all of the group’s lines and properties in the request. It is only necessary for the request to include the line item’s TxnLineID, as follows:
<PurchaseOrderLineGroupMod>
<TxnLineID>101</TxnLineID>
</PurchaseOrderLineGroupMod>
This will retain the current state of the group identified by the line ID.
if you want to modify a value within a line group, the request must include every line in the group.
The example in this section shows a request that modifies item lines within an item group. The table below shows the item lines before and after the modification. The invoice has one item group that has two components: service1 and service2. Changes are made here to the quantity attribute of the item group itself as well as to attributes of the two service item lines.
Original state of line group | Modified state of line group |
---|---|
ItemLine1 (TxnLineID=101) - Group start | ItemLine1 (TxnLineID=101) - Group start: change the quantity |
ItemLine2 (TxnLineID=102) - service 1 | ItemLine2 (TxnLineID=102) - service1: change description |
Item Line3 (TxnLineID=103) - service 2 | ItemLine3 (TxnLineID=103) - service 2: change item name to service 3, quantity and rate |
<InvoiceModRq>
<InvoiceMod>
<TxnID>100-100052155</TxnID>
<EditSequence>100052155</EditSequence>
…
…
<InvoiceLineGroupMod>
<TxnLineID>101</TxnLineID>
<Quantity>15</Quantity>
<InvoiceLineMod>
<TxnLineID>102</TxnLineID>
<Desc>new description</Desc>
</InvoiceLineMod>
<InvoiceLineMod>
<TxnLineID>103</TxnLineID>
<ItemRef>
<FullName>service3</FullName >
</ItemRef>
<Quantity>10</Quantity>
<Rate>3.20</Rate>
</InvoiceLineMod>
</InvoiceLineGroupMod>
</InvoiceMod>
</InvoiceModRq>
The following example shows inserting a new line item line into an item group. The table below shows the invoice lines before and after the addition. The invoice has one item group that has two components: service1 and service2. A new line is added following service1.
Original state of line group | Modified state of line group |
---|---|
ItemLine1 (TxnLineID=101) - Group start | ItemLine1 (TxnLineID=101) - Group start |
ItemLine2 (TxnLineID=102) - service 1 | ItemLine2 (TxnLineID=102) - service1 |
Item Line3 (TxnLineID=103) - service 2 | ItemLine3 (TxnLineID=-1) - new line (service3) |
ItemLine4 (TxnLineID=103) - service2 |
<InvoiceModRq>
<InvoiceMod>
<TxnID>100-100052155</TxnID>
<EditSequence>100052155</EditSequence>
…
…
<!—- no changes to item group start -->
<InvoiceLineGroupMod>
<TxnLineID>101</TxnLineID>
<InvoiceLineMod>
<TxnLineID>102</TxnLineID>
</InvoiceLineMod>
<!—- Pass in a TxnLineID = -1 indicates that it is a new itemline -->
<InvoiceLineMod>
<TxnLineID>-1</TxnLineID>
<ItemRef>
<FullName>service3</FullName>
</ItemRef>
<Quantity>10</Quantity>
<Rate>3.20</Rate>
</InvoiceLineMod>
<InvoiceLineMod>
<TxnLineID>103</TxnLineID>
</InvoiceLineMod>
<!—- the object representing the end of the group is not returned in the InvoiceRet object
(or on any transaction ret). Therefore, the user cannot provide its TxnLineID. You cannot
change directly the line representing the End of the group or delete it. -->
</InvoiceLineGroupMod>
</InvoiceMod>
</InvoiceModRq>
Many transactions, including purchase orders and invoices, have rate, quantity, and amount properties. The general formula used in calculations is:
Quantity * Rate = Amount
However, since QuickBooks always calculates these values, giving rate and amount in the same request is not permitted. If you do supply both values in a request, QuickBooks enters a warning in the log file, and the rate you supply is ignored. QuickBooks calculates the rate as Amount / Quantity.
Note
Note
The Amount, Rate, and Quantity fields cannot be cleared.
The SDK has two request messages for deleting objects:
For a list of the types of objects that can be deleted, see QuickBooks objects and operations accessible with the SDK.
Note
Note
To delete a list object, you must have the QuickBooks company file open in single-user mode. However, for QuickBooks Enterprise edition, it is possible to delete list items in multi user mode.
The SDK provides the TxnVoidRq message for voiding transactions.
A void request will return a TxnVoidRs response message, which can include the original information that was sent in the request, plus TimeCreated, TimeModified, and the RefNumber of the transaction that was voided.
Some transaction and list operations may fail if an accountant’s copy of the company file has been made. Beginning with QB 2009 and qbXML 8.0, you can use the Accountant Copy Exists request to check for this before running requests that will fail if the accountant copy exists.
A locked transaction is a transaction that is currently being edited in the user interface.The QuickBooks SDK also locks transactions for the time required to write them during an Add or Modify operation. If your application attempts to delete or void a locked transaction, you will receive an error ( status code 3175). You will also receive an error if you attempt to delete or void a transaction (for example, a sales receipt) while a linked transaction (such as a deposit) is locked in the user interface (error 3176 “related object is in use.).
For this reason, if you receive status code 3175, you will not know whether the locked transaction is the one you are trying to delete or void, or one that is linked to it.
Under certain conditions, you can delete (or void) a transaction that was created prior to the company’s closing date. There must be no password set by the QuickBooks Admin under “edit transaction on or before date” in the Accounting preferences. Also, the user must have the appropriate permissions, as described in the QuickBooks user interface.
Before a qualified user can delete or void a transaction from within the QuickBooks user interface, the following warning appears: “The transaction’s date is prior to the closing date for this company file. This will affect your accounting. Are you sure you want to make this change?” Your application should check the company preferences (using a PreferenceQueryRq) to find out the closing date of the company so you can issue a similar warning when your users try to delete a transaction that is already closed.
If your application tries to delete or void a closed transaction, you will receive status code 3161.
Note
Note
Starting with QB 2009 and qbXML 8.0, closing date preferences for the company file can be obtained from a PreferencesQuery.
If your application attempts an operation without having the correct permissions, you will receive status code 3260 (“Insufficient permission level to perform this action”). For information about permissions, see the onscreen help in the QuickBooks user interface.