通过基于SOAP合约的API将数千条记录导入Acumatica
我正在使用基于合同的SOAP API尝试将大约25000个日记账分录行从银行系统导入到单个Acumatica GL批处理中通过基于SOAP合约的API将数千条记录导入Acumatica,acumatica,acumatica-kb,Acumatica,Acumatica Kb,我正在使用基于合同的SOAP API尝试将大约25000个日记账分录行从银行系统导入到单个Acumatica GL批处理中 如果我尝试将所有记录同时添加到同一总账批次,我的 请求在几个小时后超时。因为它使用相同的GL 批处理,此解决方案不利用多线程 我还尝试将25000行一行一行地添加到 单个总账批处理和请求不会超时,但 之后,性能速度开始显著降低 大约有3000条记录添加到总账批次中。这 该过程需要几个小时才能运行,因为它使用相同的总账 批处理,此解决方案不利用多线程 我还研究了多线程,以便将
public static void CreateMultipleLinesPerJournalEntryBatchContractTEST(MyStoreContract.DefaultSoapClient soapClient, List<JournalEntry> journalEntries)
{
string myModuleForBatchLookup = "GL";
//list holding the values of all the records belonging to the batch in process
List<JournalEntry> allBatchItems = journalEntries;
//List used to store objects in format required by Acumatica
List<MyStoreContract.JournalTransactionDetail> myJournalTransactionsFormatted = new List<MyStoreContract.JournalTransactionDetail>();
try
{
//Creating a header and returning a batch value to be used for all line iterations.
JournalEntry myHeaderJournalEntryContract = allBatchItems.First();
string myBatchNumberToProcess = AddGLBatchHeaderContractTEST(soapClient, myHeaderJournalEntryContract);
// Do something with then n number of items defined in processing subBatch size or remaining items if smaller
foreach (JournalEntry je in allBatchItems)
{
//Moving the items in each batch from the original unformatted list to the formatted list one at a time
myJournalTransactionsFormatted.Add(new MyStoreContract.JournalTransactionDetail
{
BranchID = new MyStoreContract.StringValue { Value = je.Branch },
Account = new MyStoreContract.StringValue { Value = je.Account },
Subaccount = new MyStoreContract.StringValue { Value = je.Subaccount },
ReferenceNbr = new MyStoreContract.StringValue { Value = je.RefNumber },
DebitAmount = new MyStoreContract.DecimalValue { Value = je.DebitAmount },
CreditAmount = new MyStoreContract.DecimalValue { Value = je.CreditAmount },
TransactionDescription = new MyStoreContract.StringValue { Value = je.TransactionDescription },
UsrTransactionTime = new MyStoreContract.StringValue { Value = je.UsrTransactionTime },
UsrTransactionType = new MyStoreContract.StringValue { Value = je.UsrTransactionType },
UsrTranSequence = new MyStoreContract.StringValue { Value = je.UsrTranSequence },
UsrTellerID = new MyStoreContract.StringValue { Value = je.UsrTellerID }
});
}
//Specify the values of a new Jornal Entry using all the collected elements from the batch(list) created
MyStoreContract.JournalTransaction journalToBeCreated = new MyStoreContract.JournalTransaction
{
//Header data and details added by list generated by loop
BatchNbr = new MyStoreContract.StringSearch { Value = myBatchNumberToProcess }, //This is one of two lines used to lookup/search the batch needing to be updated
Module = new MyStoreContract.StringSearch { Value = myModuleForBatchLookup }, //This is one of two lines used to lookup/search the batch needing to be updated
Details = myJournalTransactionsFormatted.ToArray() // this is the line adding the array containing all the line details
};
soapClient.Put(journalToBeCreated);
Console.WriteLine("Added " + allBatchItems.Count.ToString() + " line transactions");
Console.WriteLine();
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("The following error was encountered and all entries for this batch need to be logged in error table");
Console.WriteLine();
Console.WriteLine(e.Message);
Console.WriteLine();
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
public static string AddGLBatchHeaderContractTEST(MyStoreContract.DefaultSoapClient soapClient, JournalEntry je)
{
try
{
//Specify the values of a new Jornal Entry Batch header
MyStoreContract.JournalTransaction journalToBeCreated = new MyStoreContract.JournalTransaction
{
//Header data
BranchID = new MyStoreContract.StringValue { Value = "PRODWHOLE" }, //This is the default branch
TransactionDate = new MyStoreContract.DateTimeValue { Value = je.TransactionDate.AddDays(-1) }, //Reduced 1 day from the batch
CurrencyID = new MyStoreContract.StringValue { Value = je.CurrencyCode }, //Currency to be used for the batch
Description = new MyStoreContract.StringValue { Value = je.TransactionDescription },
Hold = new MyStoreContract.BooleanValue { Value = true }
};
//Create a Journal Entry with the specified values
MyStoreContract.JournalTransaction newJournalTransaction = (MyStoreContract.JournalTransaction)soapClient.Put(journalToBeCreated);
string myBatchToProcess = newJournalTransaction.BatchNbr.Value;
return myBatchToProcess;
}
catch (Exception e)
{
Console.WriteLine("Error was caught while trying to create the header for the batch...");
Console.WriteLine();
Console.WriteLine(e);
Console.WriteLine();
return null;
}
}
我尝试了下面描述的Yuriy方法,但是我的自定义字段没有更新。仅更新标准字段。我应该使用哪个命令来更新扩展(自定义)字段。见下面的代码:
//Here I create instance of GLTran
GLTran row = graph.GLTranModuleBatNbr.Cache.CreateInstance() as GLTran;
//here I get a handle to graph extension GLTranExt to be able to use the added fields.
var rowExt = row.GetExtension<GLTranExt>();
row = graph.GLTranModuleBatNbr.Insert(row);
graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "AccountID", JE.Account);
graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "SubID", JE.Subaccount);
row.TranDesc = "my line description";
row.Qty = 1.0m;
row.CuryDebitAmt = (JE.DebitAmount);
row.CuryCreditAmt = (JE.CreditAmount);
rowExt.UsrTellerID = "Test teller";
rowExt.UsrTransactionTime = "Test Transaction Time";
rowExt.UsrTransactionType = "Test Transaction Type";
rowExt.UsrTranSequence = "Test Transaction Sequence";
row = graph.GLTranModuleBatNbr.Update(row);
graph.Actions.PressSave();
//这里我创建了GLTran的实例
GLTran row=graph.GLTranModuleBatNbr.Cache.CreateInstance()作为GLTran;
//在这里,我获得了图形扩展GLTranExt的句柄,以便能够使用添加的字段。
var rowExt=row.GetExtension();
行=graph.GLTranModuleBatNbr.Insert(行);
graph.GLTranModuleBatNbr.Cache.SetValueExt(行,“AccountID”,JE.Account);
graph.GLTranModuleBatNbr.Cache.SetValueExt(行,“子ID”,JE.Subaccount);
row.TranDesc=“我的线路描述”;
行数量=1.0m;
row.CuryDebitAmt=(JE.DebitAmount);
row.CuryCreditAmt=(JE.CreditAmount);
rowExt.UsrTellerID=“测试出纳员”;
rowExt.UsrTransactionTime=“测试事务时间”;
rowExt.UsrTransactionType=“测试事务类型”;
rowExt.UsrTranSequence=“测试事务序列”;
行=graph.GLTranModuleBatNbr.Update(行);
graph.Actions.PressSave();
在销售订单导入中,我每小时有18000行(4核,32Gb内存)。所以你的25000和我得到的非常相似(一个销售订单有1-6行)。对于您提供的第二个链接,API调用的参数是什么,Acumatica实例的数量是多少(CPU、RAM、SQL Server的参数)
我建议您考虑缩放AcMICATA,并通过SQL分割来缩放数据库。
编辑 如果您需要一个带有25000行的GL批次,那么我建议您采用以下解决方法:2.1将文本框信息读取为xml(或JSON)
2.2创建GL图形的实例
2.3通过图形插入所需金额(在您的情况下为25000行)
2.4调用图形。按Save()
你好,尤里。这里的问题是,我试图将所有25000条记录放入一个日记账事务中。我有4个内核,16Gb的RAM。我将在上面包含我的代码,以便您可以看到它。不幸的是,我以前从未横向扩展过解决方案,所以我不确定这种方法是否可以在项目的最后期限内学习/测试。另外,由于我对每个批进行一个API调用,扩展是否会有所帮助?请看附录。还可以在skype上添加我:zaletskiy,我会尽量找时间帮助你嗨,Yuriy。我遵循了你的方法,几乎成功了。它适用于标准字段,但不更新自定义字段。请参阅上面添加的更改。我调用“row=graph.GLTranModuleBatNbr.Update(row);”来更新标准字段和graph.Actions.PressSave();为了保存它们,我必须丢失一个更新自定义字段的命令,因为这些字段不起作用,也没有生成任何错误。谢谢您的回复,Yuriy。我发现了问题所在:我使用的命令的顺序/顺序是错误的。我必须先使用“row=graph.GLTranModuleBatNbr.Insert(row);”,然后再使用“var rowExt=row.GetExtension();”。当您插入行时,顺序很重要。如果您按错误的顺序将它们输出,则该行可能具有不同的键。感谢您建议将图形实例化,而不是使用API。这帮助我使用了正确的方法。
//Here I create instance of GLTran
GLTran row = graph.GLTranModuleBatNbr.Cache.CreateInstance() as GLTran;
//here I get a handle to graph extension GLTranExt to be able to use the added fields.
var rowExt = row.GetExtension<GLTranExt>();
row = graph.GLTranModuleBatNbr.Insert(row);
graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "AccountID", JE.Account);
graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "SubID", JE.Subaccount);
row.TranDesc = "my line description";
row.Qty = 1.0m;
row.CuryDebitAmt = (JE.DebitAmount);
row.CuryCreditAmt = (JE.CreditAmount);
rowExt.UsrTellerID = "Test teller";
rowExt.UsrTransactionTime = "Test Transaction Time";
rowExt.UsrTransactionType = "Test Transaction Type";
rowExt.UsrTranSequence = "Test Transaction Sequence";
row = graph.GLTranModuleBatNbr.Update(row);
graph.Actions.PressSave();