在 acumatica 系统中使用 web 服务 API 在屏幕账单和调整中导入支付金额

Import Amount Paid in screen Bill And Adjusment using webservices API in acumatica system

我需要使用 web 服务将支付金额的值导入 Acumatica ERP 系统。请参考下面的截图。

我已经使用 Reference Number = "1700000016"、DocType = "Bill"、VendorRef = "SV-889-JKT-2"、VendorID = "V000000030" 和 Amount Paid = "1,250,000" 创建了一些代码。请参考下面的代码。

   sCon.getLogin(username, password, url, context);
            AP301000Content konten = context.AP301000GetSchema();
            //context.AP301000Clear();
            List<Command> oCmds = new List<Command>();

            //oCmds.Add(konten.Actions.Insert);
            //--------------- adding header transaction -----------------//
            konten.DocumentSummary.Type.Commit = false;
            konten.DocumentSummary.Type.LinkedCommand = null;
            oCmds.Add(new Value { LinkedCommand = konten.DocumentSummary.Type, Value = "Bill" });
            oCmds.Add(new Value { LinkedCommand = konten.DocumentSummary.ReferenceNbr, Value = "0000" });
            oCmds.Add(new Value { LinkedCommand = konten.DocumentSummary.Date, Value = dtDateSV.Text });
            oCmds.Add(new Value { LinkedCommand = konten.DocumentSummary.VendorRef, Value = "SV-889-JKT-2" });
            oCmds.Add(new Value { LinkedCommand = konten.DocumentSummary.Vendor, Value = "V000000030" });

            //-------------- adding detail transaction (Based on values in Data Grid )-------------
            int a = dgvDocDetailSV.Rows.Count;
            for (int x = 0; x < a; x++)
            {
                oCmds.Add(konten.DocumentDetails.ServiceCommands.NewRow);
                oCmds.Add(new Value { LinkedCommand = konten.DocumentDetails.Branch, Value = dgvDocDetailSV.Rows[x].Cells[1].Value.ToString() });
                oCmds.Add(new Value { LinkedCommand = konten.DocumentDetails.InventoryID, Value = dgvDocDetailSV.Rows[x].Cells[2].Value.ToString() });
                oCmds.Add(new Value { LinkedCommand = konten.DocumentDetails.JobOrderNbr, Value = dgvDocDetailSV.Rows[x].Cells[3].Value.ToString() });
                oCmds.Add(new Value { LinkedCommand = konten.DocumentDetails.Quantity, Value = dgvDocDetailSV.Rows[x].Cells[4].Value.ToString() });
                oCmds.Add(new Value { LinkedCommand = konten.DocumentDetails.UOM, Value = dgvDocDetailSV.Rows[x].Cells[5].Value.ToString() });
                oCmds.Add(new Value { LinkedCommand = konten.DocumentDetails.UnitCost, Value = dgvDocDetailSV.Rows[x].Cells[6].Value.ToString() });
            }
            //------ add document in Applications Tab Menu -------//
            string DocTypePrepayment = "Prepayment";
            string RefNbrPrepayment = "1700000015";
            oCmds.Add(new Key
            {
                ObjectName = konten.Applications.DocTypeDisplayDocType.ObjectName,
                FieldName = konten.Applications.DocTypeDisplayDocType.FieldName,
                Value = DocTypePrepayment
            });
            oCmds.Add(new Key
            {
                ObjectName = konten.Applications.ReferenceNbrDisplayRefNbr.ObjectName,
                FieldName = konten.Applications.ReferenceNbrDisplayRefNbr.FieldName,
                Value = RefNbrPrepayment
            });
            oCmds.Add(new Value { LinkedCommand = konten.Applications.AmountPaid, Value = "1250000" });

            //------ save transaction in acumatica -------//
            oCmds.Add(konten.Actions.Save);
            var result = context.AP301000Submit(oCmds.ToArray());

我在尝试导入此数据后收到一条错误消息。错误消息是“System.Web.Services.Protocols.SoapException:服务器无法处理请求。---> PX.Data.PXException:错误 #111:处理字段 CuryAdjdAmt 时发生错误:对象引用未设置为一个实例对象.. ---> System.NullReferenceException: 对象引用未设置为对象的实例。 ”。 CuryAdjdAmt 字段似乎为空,该字段映射到 Acumatica 系统的应用程序菜单选项卡中的 AmountPaid 字段。

请给我参考解决这个问题。 谢谢

由于我们大约一年前对“账单和调整”屏幕进行的性能改进,调整数据视图委托似乎存在问题。我已将所有详细信息转发给 Acumatica 工程团队进行进一步调查。

作为临时解决方法,您可以实施 APInvoiceEntry BLC 的扩展并稍微更改调整数据视图的委托:

public class APInvoiceEntryExt : PXGraphExtension<APInvoiceEntry>
{
    [PXCopyPasteHiddenView]
    public PXSelectJoin<APAdjust,
        InnerJoin<APPayment, On<APPayment.docType, Equal<APAdjust.adjgDocType>,
            And<APPayment.refNbr, Equal<APAdjust.adjgRefNbr>>>>> Adjustments;

    public IEnumerable adjustments()
    {
        IEnumerable result;

        bool origIsImport = Base.IsImport;
        Base.IsImport = false;
        try
        {
            result = Base.Adjustments.Select();
        }
        finally
        {
            Base.IsImport = origIsImport;
        }

        return result;
    }
}

应用临时解决方法后,我能够使用以下命令集更新 AmountPaid 字段。考虑到 Adjustments 数据视图的复杂程度(因为它必须处理从数据库检索的记录和在运行时创建的记录),当应用程序选项卡中有超过 1 个文档时,您必须使用 RowNumber 服务命令([=不幸的是,Key 类型的 20=] API 命令无法在“应用程序”选项卡中定位记录)。

下面的示例将向 Acumatica 发送 2 个请求 API: - 第一次调用从“应用程序”选项卡导出所有记录 - 通过循环返回的数组,您可以确定需要为 AmountPaid 设置新值的记录 RowNumbers - 在第二次调用中,您传递 RowNumber 并将新值分配给 AmountPaid 字段

Screen context = new Screen();
context.CookieContainer = new System.Net.CookieContainer();
context.Url = "http://localhost/AP301000/Soap/AP301000.asmx";
context.Login("admin", "123");

Content billSchema = context.GetSchema();

// 1st call to export all records from the Applications tab
billSchema.DocumentSummary.Type.Commit = false;
billSchema.DocumentSummary.Type.LinkedCommand = null;

var commands = new Command[]
{
    new Value
    {
        Value = "Bill",
        LinkedCommand = billSchema.DocumentSummary.Type
    },
    new Value
    {
        Value = "000927",
        LinkedCommand = billSchema.DocumentSummary.ReferenceNbr
    },
    billSchema.Applications.DocTypeDisplayDocType,
    billSchema.Applications.ReferenceNbrDisplayRefNbr,
    billSchema.Applications.Balance
};
var applications = context.Submit(commands).ToList();
// end of 1st call to export all records from the Applications tab

// 2nd call to set AmountPaid in the Applications tab
var cmds = new List<Command>();
foreach (var application in applications)
{
    cmds.Add(
        new Value
        {
            Value = applications.IndexOf(application).ToString(),
            LinkedCommand = billSchema.Applications.ServiceCommands.RowNumber
        });
    cmds.Add(
        new Value
        {
            Value = application.Applications.Balance.Value,
            LinkedCommand = billSchema.Applications.AmountPaid
        });
}
cmds.Add(billSchema.Actions.Save);
context.Submit(cmds.ToArray());
// end of 2nd call to set AmountPaid in the Applications tab