我有一个包含多行的发票,我想将其合并为一行。它需要和遍历每个对象。它将每个加和成一个变量。循环之后,它将在发票上创建新行并删除其他行。
我一直得到“ TxnLineID:必填字段丢失”,即使我为新行提供“ -1”:
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();
}
}
}
此外,我希望它从发票中删除总计中使用的行。我已经阅读了有关如何执行此操作的信息。
一个阵营说,不要指定那些行,当执行updateRequestSet时,它将删除它们。另一个与之相反的说法是,不指定它们将保留它们。有人可以解决这个问题吗?但是,我还没有做足够的测试。
哦,这是整个错误:
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
答案 0 :(得分:0)
希望我能为此功劳,但实际上得到了Intuit Developers论坛的帮助。
需要将多个Append()
更改为以下内容:
var invoiceModLineItems = invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod;
invoiceModLineItems.TxnLineID.SetValue("-1");
invoiceModLineItems.ItemRef.FullName.SetValue("Consulting Fees:Consulting");
invoiceModLineItems.Amount.SetValue((double)feeAmount);