在流程图中使用未绑定的DAC无法运行处理功能

时间:2017-12-28 15:28:42

标签: acumatica

我正在创建一个Process,用于将项目从外部API源导入Acumatica中的记录。

我创建了一个未绑定的DAC,用于表示外部API提供的条目。

[Serializable]
public class ImportItem : IBqlTable
{
    [PXBool]
    [PXUIField(DisplayName = "Selected")]
    public bool? Selected { get; set; }
    public abstract class selected : IBqlField { }

    [PXString]
    [PXUIField(DisplayName = "External Ref Nbr")]
    public string RefNbr { get; set; }
    public abstract class refNbr : IBqlField { }
}

在Process图中,我实现主视图的委托来创建和返回Resultset(通常从API数据生成)。然后我有一个绑定到此图表的屏幕,其中有一个网格视图,显示项目以允许用户选择要导入的项目。然后,主要的代理人将在Acumatica中为所选项目创建记录。

public class ImportItemsProcess : PXGraph<ImportItemsProcess>
{
    public PXProcessing<ImportItem> ImportItems;
    public PXCancel<ImportItem> Cancel;

    public ImportItemsProcess()
    {
        ImportItems.SetProcessCaption("Import");
        ImportItems.SetProcessAllCaption("Import All");
        ImportItems.SetProcessDelegate(ProcessImportItems);
    }

    protected virtual IEnumerable importItems(PXAdapter adapter)
    {
        PXResultset<ImportItem> items = new PXResultset<ImportItem>();

        /* Would create ImportItems from external API data here */
        items.Add(new PXResult<ImportItem>(new ImportItem() { RefNbr = "1" }));
        items.Add(new PXResult<ImportItem>(new ImportItem() { RefNbr = "2" }));
        items.Add(new PXResult<ImportItem>(new ImportItem() { RefNbr = "3" }));

        return items;
    }

    public static void ProcessImportItems(List<ImportItem> importItems)
    {
        throw new PXException("ProcessImportItems() has been called");
    }
}

ASPX页面:

<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
    <px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" PrimaryView="ImportItems" TypeName="APIImporter.ImportItemsProcess" >
    </px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phL" runat="Server">
    <px:PXGrid ID="grid" runat="server" Height="400px" Width="100%" Style="z-index: 100"
        AllowPaging="True" AllowSearch="True" AdjustPageSize="Auto" DataSourceID="ds" SkinID="Primary" TabIndex="1500" TemporaryFilterCaption="Filter Applied">
        <Levels>
            <px:PXGridLevel DataMember="ImportItems">
                <RowTemplate>
                    <px:PXCheckBox ID="edSelected" runat="server" AlreadyLocalized="False" DataField="Selected" Text="Selected" CommitChanges="true">
                    </px:PXCheckBox>
                    <px:PXTextEdit ID="edRefNbr" runat="server" AlreadyLocalized="False" DataField="RefNbr" DefaultLocale="">
                    </px:PXTextEdit>
                </RowTemplate>
                <Columns>
                    <px:PXGridColumn DataField="Selected" TextAlign="Center" Type="CheckBox" Width="60px" CommitChanges="true">
                    </px:PXGridColumn>
                    <px:PXGridColumn DataField="RefNbr">
                    </px:PXGridColumn>
                </Columns>
            </px:PXGridLevel>
        </Levels>
        <AutoSize Container="Window" Enabled="True" MinHeight="200" />
    </px:PXGrid>
</asp:Content>

如果在此处作为简化示例编写,则永远不会调用Process委托。我怀疑是否与单击Process按钮时有关,对服务器的回调运行视图的委托函数,该函数重新创建ImportItem对象列表,并且框架无法将新创建的对象与回发中的对象相关联没有Key字段。但是,如果我将一个IsKey属性添加到DAC的RefNbr ...

    [PXString(IsKey = true)]
    [PXUIField(DisplayName = "External Ref Nbr")]
    public string RefNbr { get; set; }

...现在当在屏幕上选择一个项目时,我立即给出一个行级错误,并显示消息“错误:参数超出范围。参数名称:表”。

3 个答案:

答案 0 :(得分:0)

首先尝试为DAC字段添加抽象类。 如果这不能解决您的问题,请将您的ASPX代码添加到您的问题中。

[Serializable]
public class ImportItem : IBqlTable
{
    #region Selected
    public abstract class selected : IBqlField { }

    [PXBool]
    [PXUIField(DisplayName = "Selected")]
    public bool? Selected { get; set; }
    #endregion

    #region RefNbr
    public abstract class refNbr : IBqlField { }

    [PXString]
    [PXUIField(DisplayName = "External Ref Nbr")]
    public string RefNbr { get; set; }
    #endregion
}

答案 1 :(得分:0)

在数据视图委托中,除了返回它们之外,还必须将项目添加到缓存中。请尝试以下:

        protected virtual IEnumerable importItems()
        {    
            int iCachedData = 0;
            foreach (var row in ImportItems.Cache.Cached)
            {
                iCachedData++;
                yield return row;
            }

            if (iCachedData == 0)
            {
               for (int iCounter = 1; iCounter <= 5; iCounter++)
               {
                   ImportItem item = new ImportItem() { RefNbr = iCounter };
                   item = ImportItems.Insert(item);
                   ImportItems.Cache.SetStatus(item, PXEntryStatus.Held);
                   yield return item;
               }
            }
        }
祝你好运!

答案 2 :(得分:0)

我尝试了使用绑定DAC而不是数据库表的处理图功能。 当您要访问某些API并在处理屏幕中获取记录而不保存到数据库时,这很有用。我不在这里包括aspx代码。

[PXVirtualDAC]中此代码中的突出显示点和DAC中的“关键字段”,因此,我们无需创建表即可实现此功能。您可以说是虚拟DAC-无需绑定任何数据库表。

public class TestUnboundProcessing : PXGraph<TestUnboundProcessing>
{
    #region Unbound DAC
    public class UnboundDAC : IBqlTable
    {
        #region Selected
        [PXDBBool]
        [PXUIField(DisplayName = "Selected")]
        public virtual bool? Selected { get; set; }
        public abstract class selected : PX.Data.IBqlField { }
        #endregion

        [PXDBString(50, IsUnicode = true,IsKey =true)]
        [PXUIField(DisplayName = "Id")]
        public string Id { get; set; }
        public abstract class id : PX.Data.IBqlField { }

        [PXDBString(100, IsUnicode = true)]
        [PXUIField(DisplayName = "Author")]
        public string Author { get; set; }
        public abstract class author : PX.Data.IBqlField { }

        [PXDBString(1000, IsUnicode = true)]
        [PXUIField(DisplayName = "Body")]
        public string Body { get; set; }
        public abstract class body : PX.Data.IBqlField { }
    }
    #endregion


    #region Processing Filter DAC
    [Serializable]
    public partial class TestFilter : PX.Data.IBqlTable
    {
        #region LastSyncDate
        [PXDate()]
        [PXDefault(typeof(AccessInfo.businessDate))]
        [PXUIField(DisplayName = "Last Sync Date", Visibility = PXUIVisibility.Visible)]
        public virtual DateTime? LastSyncDate { get; set; }
        public abstract class lastSyncDate : PX.Data.IBqlField { }
        #endregion

        #region ProjectID
        [PXDBString(10, IsUnicode = true)]
        [PXUIField(DisplayName = "Project ID")]
        public virtual String ProjectID { get; set; }
        public abstract class projectID : PX.Data.IBqlField { }
        #endregion

        #region IssueID
        [PXDBString(10, IsUnicode = true)]
        [PXUIField(DisplayName = "Issue ID", Visibility = PXUIVisibility.SelectorVisible)]
        public virtual String IssueID { get; set; }
        public abstract class issueID : PX.Data.IBqlField { }
        #endregion
    }
    #endregion


    #region Filter + Delegate Overrides

    public PXFilter<TestFilter> Filter;
    public PXCancel<TestFilter> Cancel;

    [PXVirtualDAC]
    [PXFilterable]
    public PXFilteredProcessing<UnboundDAC, TestFilter> UnboundView;

    protected virtual IEnumerable unboundView()
    {
        GetUnboundDACList();
        foreach (UnboundDAC item in UnboundView.Cache.Cached)
        {
            yield return item;
        }
    }

    private void GetUnboundDACList()
    {
        UnboundView.Cache.Insert(new UnboundDAC() { Id = "1", Author = "Test 1", Body = "Comment 1" });
        UnboundView.Cache.Insert(new UnboundDAC() { Id = "2", Author = "Test 2", Body = "Comment 2" });
        UnboundView.Cache.Insert(new UnboundDAC() { Id = "3", Author = "Test 3", Body = "Comment 3" });
        //return UnboundView.Cache;
    }

    #endregion

    #region Constructor + Process

    public TestUnboundProcessing()
    {
        TestFilter filter = Filter.Current;
        UnboundView.SetProcessDelegate(delegate (List<UnboundDAC> docList)
        {
            UnboundProcessing(docList, filter);
        }
      );
    }
    #endregion

    #region Processing functions

    public static void UnboundProcessing(List<UnboundDAC> docList, TestFilter aFilter)
    {
        TestUnboundProcessing graph = CreateInstance<TestUnboundProcessing>();
        graph.SaveRecords(graph, docList, aFilter);
    }

    public void SaveRecords(TestUnboundProcessing aProcessingGraph, List<UnboundDAC> docList, TestFilter aFilter)
    {
        bool isErrorOccured = false;
        CRActivityMaint graph = PXGraph.CreateInstance<CRActivityMaint>();
        foreach (UnboundDAC item in docList)
        {
            try
            {
                CRActivity addedActivity = new CRActivity();
                addedActivity.UIStatus = ActivityStatusListAttribute.Completed;
                addedActivity.Type = "N";
                addedActivity.Location = item.Id;
                addedActivity.Subject = item.Author;
                addedActivity.Body = item.Body;
                addedActivity.IsPrivate = true;
                graph.Activities.Insert(addedActivity);
            }
            catch (Exception ex)
            {
                isErrorOccured = true;
                PXProcessing<JRComment>.SetError(docList.IndexOf(item), ex.Message);
            }
        }

        if (graph.Activities.Cache.Cached.Count() > 0)
        {
            graph.Actions.PressSave();
        }

        if (isErrorOccured)
        {
            throw new PXException("One or more record processed unsuccessful");
        }
    }


    #endregion

    #region Filter Events

    protected virtual void TestFilter_LastSyncDate_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
    {
        UnboundView.Cache.Clear();
    }

    protected virtual void TestFilter_ProjectID_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
    {
        UnboundView.Cache.Clear();
    }

    protected virtual void TestFilter_IssueID_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
    {
        UnboundView.Cache.Clear();
    }

    #endregion