jsgoupil / quickbooks-sync

Sync Quickbooks Desktop
MIT License
87 stars 40 forks source link

Fix ordering of the ObjectItems. #37

Closed rogerfar closed 5 years ago

rogerfar commented 5 years ago

When creating and invoice it will attempt to sort the InvoiceLineAdd list by the nameOrder, but because this is an unsafe order it jumbles the list and causes the lines to be out of order when generating the XML.

I added a unit test to show this behaviour. The old sort would generate the following XML:

<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
    <QBXMLMsgsRq onError="continueOnError">
        <InvoiceAddRq>
            <InvoiceAdd>
                <CustomerRef>
                    <ListID>12345</ListID>
                </CustomerRef>
                <IsPending>true</IsPending>
                <InvoiceLineAdd>
                    <Desc>Test Item 0 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 8 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 8 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 7 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 7 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 6 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 6 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 5 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 5 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 4 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 4 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 3 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 3 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 2 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 2 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 1 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 1 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 0 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 9 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 9 item</Desc>
                </InvoiceLineAdd>
            </InvoiceAdd>
        </InvoiceAddRq>
    </QBXMLMsgsRq>
</QBXML>

The new way:

<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
    <QBXMLMsgsRq onError="continueOnError">
        <InvoiceAddRq>
            <InvoiceAdd>
                <CustomerRef>
                    <ListID>12345</ListID>
                </CustomerRef>
                <IsPending>true</IsPending>
                <InvoiceLineAdd>
                    <Desc>Test Item 0 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 0 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 1 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 1 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 2 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 2 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 3 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 3 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 4 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 4 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 5 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 5 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 6 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 6 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 7 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 7 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 8 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 8 item</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Test Item 9 for Test</Desc>
                </InvoiceLineAdd>
                <InvoiceLineAdd>
                    <Desc>Another Test 9 item</Desc>
                </InvoiceLineAdd>
            </InvoiceAdd>
        </InvoiceAddRq>
    </QBXMLMsgsRq>
</QBXML>
jsgoupil commented 5 years ago

The same code exists in ObjectItems`1.cs I suspect it would be a problem there too.

rogerfar commented 5 years ago

You're right, OrderBy is indeed enough to get it to work, no need to do the GroupBy and flattening again. I pushed another commit with these changes.