cheslijones
cheslijones

Reputation: 9194

Consolidating and deleting invoice lines but getting TxnLineID: required field is missing although provided

I have an invoice with multiple lines that I want to consolidate into one line. It takes the and iterates through each . It sums each to a variable. After the loop, it should create a new line on the invoice and delete the others.

I keep getting a "TxnLineID: required field is missing" even though I am providing it as "-1" for a new line:

private static void Main(string[] args)
{
    // creates the session manager object using QBFC
    var querySessionManager = new QBSessionManager();

    // want to know if a session has begun so it can be ended it if an error happens
    var booSessionBegun = false;

    try
    {
        // open the connection and begin the session with QB
        querySessionManager.OpenConnection("", "Test Connection");
        querySessionManager.BeginSession("", ENOpenMode.omDontCare);

        // if successful then booSessionBegin = True
        booSessionBegun = true;

        // Get the RequestMsgSet based on the correct QB Version
        var queryRequestSet = GetLatestMsgSetRequest(querySessionManager);

        // Initialize the message set request object
        queryRequestSet.Attributes.OnError = ENRqOnError.roeStop;

        // QUERY RECORDS **********************
        // appendInvoiceQuery to request set
        // only invoices that start with the consulting invoice prefix
        // include all of the line items
        // only unpaid invoices
        var invoiceQ = queryRequestSet.AppendInvoiceQueryRq();
        invoiceQ.ORInvoiceQuery.InvoiceFilter.ORRefNumberFilter.RefNumberFilter.MatchCriterion.SetValue(ENMatchCriterion.mcStartsWith);
        invoiceQ.ORInvoiceQuery.InvoiceFilter.ORRefNumberFilter.RefNumberFilter.RefNumber.SetValue("ML-11");
        invoiceQ.ORInvoiceQuery.InvoiceFilter.PaidStatus.SetValue(ENPaidStatus.psNotPaidOnly);
        invoiceQ.IncludeLineItems.SetValue(true);

        // DELETE INVOICE ***********************************
        // var deleteI = queryRequestSet.AppendTxnDelRq();
        // deleteI.TxnDelType.SetValue(ENTxnDelType.tdtInvoice);
        // deleteI.TxnID.SetValue("3B57C-1539729221");

        // Do the request and get the response message set object
        var queryResponseSet = querySessionManager.DoRequests(queryRequestSet);

        // Uncomment the following to view and save the request and response XML
        var requestXml = queryRequestSet.ToXMLString();
        // Console.WriteLine(requestXml);
        SaveXML(requestXml, 1);
        var responseXml = queryResponseSet.ToXMLString();
        // Console.WriteLine(responseXml);
        SaveXML(responseXml, 2);

        // Get the statuscode of the response to proceed with
        var respList = queryResponseSet.ResponseList;
        var ourResp = respList.GetAt(0);
        var statusCode = ourResp.StatusCode;

        // Test what the status code
        if (statusCode == 0)
        {
            // Parse the string into an XDocument object
            var xmlDoc = XDocument.Parse(responseXml);

            // Set the xmlDoc root
            var xmlDocRoot = xmlDoc.Root.Element("QBXMLMsgsRs")
                                        .Element("InvoiceQueryRs")
                                        .Elements("InvoiceRet");

            var i = 1;

            // Iterate through the elements to get values and do some logic
            foreach (var invoiceElement in xmlDocRoot)
            {
                // Create connection to update
                var updateSessionManager = new QBSessionManager();
                updateSessionManager.OpenConnection("", "Test Connection");
                updateSessionManager.BeginSession("", ENOpenMode.omDontCare);

                // Make the request set for updates
                var updateRequestSet = GetLatestMsgSetRequest(updateSessionManager);
                updateRequestSet.Attributes.OnError = ENRqOnError.roeStop;

                // Set the variables required to edit a file
                var txnId = (string) invoiceElement.Element("TxnID");
                var editSequence = (string) invoiceElement.Element("EditSequence");

                var xmlLineItemRoot = invoiceElement.Elements("InvoiceLineRet");

                var feeAmount = 0.0f;

                foreach (var invoiceLineItemElement in xmlLineItemRoot)
                {
                    if (invoiceLineItemElement.Element("ItemRef").Element("FullName").Value == "Consulting Fees:Consulting")
                    {
                        feeAmount = float.Parse(invoiceLineItemElement.Element("Amount").Value) + (float) feeAmount;
                    }
                }
                //// UPDATING RECORDS ******************************
                //// TxnID and EditSequence required

                var invoiceM = updateRequestSet.AppendInvoiceModRq();
                invoiceM.TxnID.SetValue(txnId);
                invoiceM.EditSequence.SetValue(editSequence);
                invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod.TxnLineID.SetValue("-1");
                invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod.ItemRef.FullName.SetValue("Consulting Fees:Consulting");
                invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod.Amount.SetValue((double)feeAmount);

                updateSessionManager.DoRequests(updateRequestSet);

                i++;

                updateSessionManager.EndSession();
                updateSessionManager.CloseConnection();
            }
        }

        // end and disconnect after done
        querySessionManager.EndSession();
        booSessionBegun = false;
        querySessionManager.CloseConnection();
    }
    catch (Exception e)
    {
        // if it couldn't connect then display a message saying so and make sure to EndSession/CloseConnection
        Console.WriteLine(e.Message.ToString() + "\nStack Trace: \n" + e.StackTrace + "\nExiting the application");

        if (booSessionBegun)
        {
            querySessionManager.EndSession();
            querySessionManager.CloseConnection();
        }
    }
}

Furthermore, I want it to remove the lines from the invoice that were used in the sum. I've read conflicting information on how to do this.

One camp says, don't specify those lines and it will erase them when the updateRequestSet is executed. Another contradicts by saying that not specifying them, it will retain them. Can someone please clear this up. I haven't gotten far enough to test, however.

Oh and here is the entirety of the error:

InvoiceMod
ORInvoiceLineModList:
element(2) - InvoiceLineMod:
TxnLineID: required field is missing
End of InvoiceLineMod
End of ORInvoiceLineModList
End of InvoiceMod

Stack Trace:
   at Interop.QBFC13.IQBSessionManager.DoRequests(IMsgSetRequest request)
   at ConsolidateInvoiceLineItems.Program.Main(String[] args) in C:\qb\QuickBooks\ConsolidateInvoiceLineItems\ConsolidateInvoiceLineItems\Program.cs:line 226
Exiting the application

Upvotes: 0

Views: 174

Answers (1)

cheslijones
cheslijones

Reputation: 9194

Wish I could take credit for this, but actually got help from the Intuit Developers forum.

Need to change the multiple Append() to the following:

            var invoiceModLineItems = invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod;
            invoiceModLineItems.TxnLineID.SetValue("-1");
            invoiceModLineItems.ItemRef.FullName.SetValue("Consulting Fees:Consulting");
            invoiceModLineItems.Amount.SetValue((double)feeAmount);

Upvotes: 0

Related Questions