0

Context

I'm importing sales data into QuickBooks using a C# desktop application and the QuickBooks QBFC API.

I need to build a list of the Memo values for all Sales Receipts in the company file. This is because the Memo contains a sales reference which must be checked for duplicates before a new Sales Receipt can be imported.

Issue

The code I'm using at present is:

IMsgSetRequest requestMsgSet = qbSessionManager.CreateMsgSetRequest("UK", 13, 0);

ISalesReceiptQuery salesReceiptQuery = requestMsgSet.AppendSalesReceiptQueryRq();

salesReceiptQuery.metaData.SetValue(ENmetaData.mdNoMetaData);
salesReceiptQuery.IncludeRetElementList.Add("Memo");

IMsgSetResponse responseMsgSet = qbSessionManager.DoRequests(requestMsgSet);

IResponseList responseList = responseMsgSet.ResponseList;

for (int i = 0; i < responseList.Count; i++)
{
    IResponse response = responseList.GetAt(i);

    if (response.StatusCode == 0)
    {
        ExistingOrderIds.Add(response.Detail.ToString());
    }
    else
    {
        Log.Error("While building OrderId list. Error returned when listing memos from QuickBooks Sales Receipts");
        Log.Error(response.StatusCode + " " + response.StatusMessage + " " + response.Detail);
    }
}

This returns just a single IResponseList item and response.detail.toString() yields "System.__ComObject". There are actually several hundred Sales Receipts in this company file.

Question

What am I doing wrong here?

johnny 5
  • 19,893
  • 50
  • 121
  • 195
ifinlay
  • 621
  • 1
  • 7
  • 24
  • so what happens when you debug the code.. for example this line inside the for loop `IResponse response = responseList.GetAt(i);` are you getting any items added to the ` ExistingOrderIds.Add()` method when called..? – MethodMan Apr 11 '16 at 17:21
  • In the debugger responseList.Count is always 1. response.StatusCode then yields zero and a single item gets added to ExistingOrderIds with a value of "System.__ComObject". – ifinlay Apr 11 '16 at 17:25
  • Further information - Studying the OSR further I think I may have the for loop at the wrong level. I note that IResponse contains a "List of ISalesReceiptRet Objects". I can't get this into a readable form though. – ifinlay Apr 11 '16 at 17:28

1 Answers1

0

Ok, finally cracked this. My misconception is that you iterate on IResponseList. Actually the single IResponseList contains all my Memos in a list of ISalesReceiptRet objects. Hence iteration needs to occur on the ISalesReceiptRetList. The QuickBooks OSR examples are not remotely clear on this! So the working code is as follows:

IMsgSetRequest requestMsgSet = qbSessionManager.CreateMsgSetRequest("UK", 13, 0);

ISalesReceiptQuery salesReceiptQuery = requestMsgSet.AppendSalesReceiptQueryRq();

salesReceiptQuery.metaData.SetValue(ENmetaData.mdNoMetaData);
salesReceiptQuery.IncludeRetElementList.Add("Memo");

IMsgSetResponse responseMsgSet = qbSessionManager.DoRequests(requestMsgSet);

IResponse response = responseMsgSet.ResponseList.GetAt(0);

ISalesReceiptRetList salesReceiptRetList = (ISalesReceiptRetList)response.Detail;

for (int i = 0; i < salesReceiptRetList.Count; i++)
{
    if (salesReceiptRetList.GetAt(i).Memo != null)
    {
        string memo = salesReceiptRetList.GetAt(i).Memo.GetValue();

        if (memo != string.Empty)
        {
           ExistingOrderIds.Add(memo);
        } 
    }
}
johnny 5
  • 19,893
  • 50
  • 121
  • 195
ifinlay
  • 621
  • 1
  • 7
  • 24
  • `ExistingOrderIds = salesReceiptRetList.Where(x => false == string.IsNullOrWhiteSpace(x.Memo)).Select(x => x.Memo.GetValue()).ToList()` you should probably rename existingOrderIds to OrderMemos or something the makes more sense – johnny 5 Apr 11 '16 at 19:04
  • Thanks, this looks neat. Unfortunately "'ISalesReceiptRetList' does not contain a definition for 'Where'". On the renaming issue, in this partcular context the Memo field always contains an OrderId. The system from which orders are imported has OrderIds too long to be accomodated by the QuickBooks Sale No (annoyingly!) – ifinlay Apr 11 '16 at 19:25
  • You need to add an reference to system.linq – johnny 5 Apr 11 '16 at 19:28
  • "using System.Linq;" is already there as well as System.Linq.Expressions. I'm wondering if Linq handling just isn't implemented due to what lies behind ISalesReceiptRetList i.e. a COM interface to a completely different code structure. – ifinlay Apr 11 '16 at 19:43
  • ...I wasn't able to use foreach in my original loop so I guess IEnumerable isn't implemented for ISalesReceiptRetList. I also checked that System.Linq is in scope btw. – ifinlay Apr 11 '16 at 19:52