我正在创建一个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; }
...现在当在屏幕上选择一个项目时,我立即给出一个行级错误,并显示消息“错误:参数超出范围。参数名称:表”。
答案 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