Reputation: 9194
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
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