The Short Sale system was exhibiting a bug where inserting a Ledger via AJAX resulted in duplicate ledgers being created. The bug was fixed with a minor tweak to the data-options tag of the Ledger DIV tag. Understanding the minor tweak is important in understanding how QBO 2.0 AJAX works. <LedgerItem> <LedgerID>12</LedgerID> <Status>Paid</Status> </LedgerItem> Presumably, the Ledger has many more columns populated than just LedgerID and Status. The Import Framework will grab existing values from the database, overwrite those existing values with the transmitted XML values, and save the Ledger. However, it's conceivable that we might want to intentionally NULL some values in the Ledger; Ledger.AccountNumber perhaps. This can be done though the Import Framework with: <LedgerItem> <LedgerID>12</LedgerID> <Status>Paid</Status> <AccountNumber></AccountNumber> <!-- or <AccountNumber/> --> </LedgerItem> In the case of the Short Sale system Ledger, there is a custom XSLT that renders a qbo.LedgerObject via a DIV tag. In some cases, the user would be in an insert mode, in other cases in an update mode. Thus, the DIV tag looked like this: < div id="IncomeLedger" class="panel hidden" type="qbo.LedgerObject" data-options="{{ledger: 'Monthly Household Income', object: 'ShortSale', objectid: '{//ShortSaleID}',ledgerid: '{//SomeLedgerID}', save: false }}">.</ div > ledgerid: '' . This cause the AJAX to transmit:<LedgerItem> <LedgerID></LedgerID> <Ledger>Monthly Household Income</Ledger> ... </LedgerItem>
< div id="IncomeLedger" class="panel hidden" type="qbo.LedgerObject" data-options="{{ledger: 'Monthly Household Income', object: 'ShortSale', objectid: '{//ShortSaleID}',ledgerid: '{//SomeLedgerID}', save: false, bindNull: false }}">.</ div > Why did this cause duplicate Ledger rows? The Ledger.Import method behaves a bit differently than most classes, because it is designed to handle LedgerItems as well as Ledgers in a single XML payload. Basically, this happens: if (LedgerID.IsNull) Insert(); ... else Update(); ... SetProperties(importRow); SaveAll(); In this example, Insert() was correctly being called, at which point a LedgerID was created and set. Then, in preparation for saving any defined LedgerItems, SetProperties(importRow) was NULLing out the LedgerID because of the <LedgerID></LedgerID> node. SaveAll() would then insert the same ledger again. |
Troubleshooting >