What I missed in Acumatica processing page implementation - acumatica

I try to create Acumatica processing page.
I have following aspx code:
<%# Page Language="C#" MasterPageFile="~/MasterPages/TabView.master" AutoEventWireup="true"
ValidateRequest="false" CodeFile="SM102000.aspx.cs"
Inherits="Page_SM102000" Title="Untitled Page" %>
<%# MasterType VirtualPath="~/MasterPages/TabView.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
PrimaryView="StackOverflowProcess" TypeName="StackOverflowSync.UsrStackOverflowProcess">
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" runat="server">
<px:PXGrid ID="grid" runat="server"
Height="400px"
Width="100%"
AllowPaging="True"
AdjustPageSize="Auto"
AutoAdjustColumns="True"
AllowSearch="True"
SkinID="Inquire"
DataSourceID="ds"
NoteIndicator="true"
TabIndex="3300"
TemporaryFilterCaption="Filter Applied">
<Levels>
<px:PXGridLevel DataMember="StackOverflowProcess">
<Columns>
<px:PXGridColumn DataField="Selected" TextAlign="Center" Width="20px" Type="CheckBox" AllowCheckAll="True">
</px:PXGridColumn>
<px:PXGridColumn DataField="FailInfo" Width="20px">
</px:PXGridColumn>
<px:PXGridColumn DataField="SynchronizationType" Width="80px">
</px:PXGridColumn>
<px:PXGridColumn DataField="LastFullSync" TextAlign="Right" Width="100px">
</px:PXGridColumn>
<px:PXGridColumn DataField="LastRunCmt" Width="80px">
</px:PXGridColumn>
<px:PXGridColumn DataField="LastRunFld" TextAlign="Right" Width="100px">
</px:PXGridColumn>
</Columns>
</px:PXGridLevel>
</Levels>
<AutoSize Container="Window" Enabled="True" MinHeight="400" />
</px:PXGrid>
</asp:Content>
Following DAC class:
using PX.Data;
using System;
namespace StackOverflowSync.DAC
{
[Serializable()]
public class UsrStackOverflowSettingItem: IBqlTable
{
#region SettingID
public abstract class settingID : PX.Data.IBqlField
{
}
protected int _SettingID;
[PXDBIdentity(IsKey = true)]
public virtual int SettingID
{
get
{
return this._SettingID;
}
set
{
this._SettingID = value;
}
}
#endregion
#region FailInfo
public abstract class failInfo : PX.Data.IBqlField
{
}
protected string _FailInfo;
[PXDBString(255, IsUnicode = true)]
[PXDefault()]
[PXUIField(DisplayName = "")]
public virtual string FailInfo
{
get
{
return this._FailInfo;
}
set
{
this._FailInfo = value;
}
}
#endregion
#region Selected
public abstract class selected : IBqlField
{
}
protected bool? _Selected = false;
/// <summary>
/// Indicates whether the record is selected for mass processing.
/// </summary>
[PXBool]
[PXDefault(false)]
[PXUIField(DisplayName = "Selected")]
public bool? Selected
{
get
{
return _Selected;
}
set
{
_Selected = value;
}
}
#endregion
#region SynchronizationType
public abstract class synchronizationType : PX.Data.IBqlField
{
}
protected string _SynchronizationType;
[PXDBString(255, IsUnicode = true)]
[PXDefault()]
[PXUIField(DisplayName = "Synchronization Type")]
public virtual string SynchronizationType
{
get
{
return this._SynchronizationType;
}
set
{
this._SynchronizationType = value;
}
}
#endregion
#region LastFullSync
public abstract class lastFullSync : PX.Data.IBqlField
{
}
protected DateTime? _LastFullSync;
[PXDBDate()]
[PXDefault()]
[PXUIField(DisplayName = "Last Full Sync")]
public virtual DateTime? LastFullSync
{
get
{
return this._LastFullSync;
}
set
{
this._LastFullSync = value;
}
}
#endregion
#region LastRunCmt
public abstract class lastRunCmt : PX.Data.IBqlField
{
}
protected decimal? _LastRunCmt;
[PXDBDecimal(2)]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Last Run: Records Commited")]
public virtual decimal? LastRunCmt
{
get
{
return this._LastRunCmt;
}
set
{
this._LastRunCmt = value;
}
}
#endregion
#region LastRunFld
public abstract class lastRunFld : PX.Data.IBqlField
{
}
protected decimal? _LastRunFld;
[PXDBDecimal(2)]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Last Run: Records Failed")]
public virtual decimal? LastRunFld
{
get
{
return this._LastRunFld;
}
set
{
this._LastRunFld = value;
}
}
#endregion
#region CreatedByID
public abstract class createdByID : PX.Data.IBqlField
{
}
protected Guid? _CreatedByID;
[PXDBCreatedByID()]
public virtual Guid? CreatedByID
{
get
{
return this._CreatedByID;
}
set
{
this._CreatedByID = value;
}
}
#endregion
#region Tstamp
public abstract class tstamp : PX.Data.IBqlField
{
}
protected byte[] _Tstamp;
[PXDBTimestamp()]
public virtual byte[] Tstamp
{
get
{
return this._Tstamp;
}
set
{
this._Tstamp = value;
}
}
#endregion
#region CreatedByScreenID
public abstract class createdByScreenID : PX.Data.IBqlField
{
}
protected string _CreatedByScreenID;
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID
{
get
{
return this._CreatedByScreenID;
}
set
{
this._CreatedByScreenID = value;
}
}
#endregion
#region CreatedDateTime
public abstract class createdDateTime : PX.Data.IBqlField
{
}
protected DateTime? _CreatedDateTime;
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime
{
get
{
return this._CreatedDateTime;
}
set
{
this._CreatedDateTime = value;
}
}
#endregion
#region LastModifiedByID
public abstract class lastModifiedByID : PX.Data.IBqlField
{
}
protected Guid? _LastModifiedByID;
[PXDBLastModifiedByID()]
[PXUIField(DisplayName = "Last Modified By")]
public virtual Guid? LastModifiedByID
{
get
{
return this._LastModifiedByID;
}
set
{
this._LastModifiedByID = value;
}
}
#endregion
#region LastModifiedDateTime
public abstract class lastModifiedDateTime : PX.Data.IBqlField
{
}
protected DateTime? _LastModifiedDateTime;
[PXDBLastModifiedDateTime()]
[PXUIField(DisplayName = "Modified At")]
public virtual DateTime? LastModifiedDateTime
{
get
{
return this._LastModifiedDateTime;
}
set
{
this._LastModifiedDateTime = value;
}
}
#endregion
#region LastModifiedByScreenID
public abstract class lastModifiedByScreenID : PX.Data.IBqlField
{
}
protected string _LastModifiedByScreenID;
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID
{
get
{
return this._LastModifiedByScreenID;
}
set
{
this._LastModifiedByScreenID = value;
}
}
#endregion
}
}
And following graph:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using PX.Data;
using PX.SM;
using StackOverflowSync.DAC;
namespace StackOverflowSync
{
public class UsrStackOverflowProcess:PXGraph<UsrStackOverflowProcess>
{
[PXFilterable]
public PXProcessing<UsrStackOverflowSettingItem> StackOverflowProcess;
public PXCancel<UsrStackOverflowSettingItem> Cancel;
public UsrStackOverflowProcess()
{
StackOverflowProcess.SetProcessDelegate(Process);
}
public static void Process(List<UsrStackOverflowSettingItem> syncItems)
{
foreach (UsrStackOverflowSettingItem usrStackOverflowPrcSt in syncItems)
{
//
}
}
public override bool IsDirty => false;
}
}
If I compile and open all of it in my Acumatica instance I see three buttons: Process, and Process All and Cancel, which is expected behavior. When I check "Process All" then method Process receives all items. But if I select few items, and press at Process, method Process doesn't receive any ( I've checked in debugger ). What else should I add/remove to my code in order make button Process work properly?

Reported issue is caused by the non-nullable SettingID field. All DAC fields must be of a nullable type. Your custom screen should operate as expected after you change type of the SettingID property and the _SettingID field to Nullable<int> (int?):
[Serializable()]
public class UsrScanCoSettingItem : IBqlTable
{
#region SettingID
public abstract class settingID : PX.Data.IBqlField
{
}
protected int? _SettingID;
[PXDBIdentity(IsKey = true)]
public virtual int? SettingID
{
get
{
return this._SettingID;
}
set
{
this._SettingID = value;
}
}
#endregion
...
}

The problem is that in aspx you have the first column defined as:
<px:PXGridColumn DataField="Seleted" ...
While the name of the column you want is Selected. Looks like it is as easy as that.

I've been where you are and I think to solve it I had to build the list. Try something like the following.
//Invoices.SetProcessDelegate(SendData);
Invoices.SetProcessDelegate(delegate(List<ARInvoice> list)
{
List<ARInvoice> newlist = new List<ARInvoice>(list.Count);
foreach (ARInvoice doc in list)
{
newlist.Add(doc);
}
SendData(newlist);
});

Related

Acumatica - Processing Screen Not Executing Process Delegate for Selected Records

I have a processing screen in Acumatica ERP (2020R2). Whenever I run Process All, it executes the process delegate correctly. But whenever I select some of the records and run the Process action, the process delegate doesn't even get called.
I've implemented several processing screens, and I've never had this problem.
I did notice that, when I click the Selected checkbox, a red dot appears beside the row on the grid and doesn't go away. On other processing screens that I've implemented, the red dot appears then goes away.
Here is my graph:
public class StkItemUpdateProcess : PXGraph<StkItemUpdateProcess>
{
#region Fliter DAC
[PXHidden]
public class StkItemFilter : IBqlTable
{
#region UpdateID
[PXString(15, IsUnicode = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXUIField(DisplayName = "Update ID")]
[PXSelector(
typeof(SearchFor<StkItemUpdateHdr.updateID>),
typeof(StkItemUpdateHdr.updateID),
typeof(StkItemUpdateHdr.descr),
typeof(StkItemUpdateHdr.vendorID),
typeof(StkItemUpdateHdr.effectiveDate)
)]
public virtual string UpdateID { get; set; }
public abstract class updateID : PX.Data.BQL.BqlString.Field<updateID> { }
#endregion
#region VendorID
[PXInt]
[PXUIField(DisplayName = "Vendor")]
[PXSelector(
typeof(
SearchFor<Vendor.bAccountID>.
In<SelectFrom<Vendor>.
InnerJoin<Address>.
On<Address.addressID.IsEqual<Vendor.defAddressID>>.
Where<Vendor.status.IsEqual<BAccount.status.active>>>
),
typeof(Vendor.acctCD),
typeof(Vendor.acctName),
typeof(Address.city),
typeof(Address.state),
SubstituteKey = typeof(Vendor.acctCD),
DescriptionField = typeof(Vendor.acctName)
)]
public virtual int? VendorID { get; set; }
public abstract class vendorID : PX.Data.BQL.BqlInt.Field<vendorID> { }
#endregion
#region InventoryID
[PXInt]
[PXUIField(DisplayName = "Inventory ID")]
[PXSelector(
typeof(
SearchFor<InventoryItem.inventoryID>.
In<SelectFrom<InventoryItem>.
InnerJoin<POVendorInventory>.
On<POVendorInventory.inventoryID.IsEqual<InventoryItem.inventoryID>>.
Where<InventoryItem.stkItem.IsEqual<True>.
And<POVendorInventory.vendorID.IsEqual<StkItemUpdateHdr.vendorID.FromCurrent>>.
And<POVendorInventory.active.IsEqual<True>>>>
),
typeof(InventoryItem.inventoryCD),
typeof(InventoryItem.descr),
typeof(InventoryItem.itemClassID),
typeof(InventoryItem.itemType),
SubstituteKey = typeof(InventoryItem.inventoryCD)
)]
[PXRestrictor(
typeof(Where<InventoryItem.stkItem.IsEqual<True>.
And<POVendorInventory.vendorID.IsEqual<StkItemUpdateHdr.vendorID.FromCurrent>>.
And<POVendorInventory.active.IsEqual<True>>>),
Messages.InvalidVendorItemPair)]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : PX.Data.BQL.BqlInt.Field<inventoryID> { }
#endregion
#region FromEffectiveDate
[PXDate]
[PXUIField(DisplayName = "From Date")]
[PXUnboundDefault(typeof(AccessInfo.businessDate), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual DateTime? FromEffectiveDate { get; set; }
public abstract class fromEffectiveDate : PX.Data.BQL.BqlDateTime.Field<fromEffectiveDate> { }
#endregion
#region ToEffectiveDate
[PXDate]
[PXUIField(DisplayName = "To Date")]
[PXUnboundDefault(typeof(AccessInfo.businessDate), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual DateTime? ToEffectiveDate { get; set; }
public abstract class toEffectiveDate : PX.Data.BQL.BqlDateTime.Field<toEffectiveDate> { }
#endregion
}
#endregion
#region Selects / Views
public PXCancel<StkItemFilter> Cancel;
public PXFilter<StkItemFilter> Filter;
public PXFilteredProcessingJoin<StkItemUpdateDet, StkItemFilter,
InnerJoin<StkItemUpdateHdr,
On<StkItemUpdateHdr.updateID.IsEqual<StkItemUpdateDet.updateID>>,
InnerJoin<Vendor,
On<Vendor.bAccountID.IsEqual<StkItemUpdateHdr.vendorID>>,
InnerJoin<InventoryItem,
On<InventoryItem.inventoryID.IsEqual<StkItemUpdateDet.inventoryID>>>>>,
Where<Brackets<StkItemFilter.updateID.FromCurrent.IsNull.
Or<StkItemUpdateDet.updateID.IsEqual<StkItemFilter.updateID.FromCurrent>>>.
And<StkItemFilter.vendorID.FromCurrent.IsNull.
Or<StkItemUpdateHdr.vendorID.IsEqual<StkItemFilter.vendorID.FromCurrent>>>.
And<StkItemFilter.inventoryID.FromCurrent.IsNull.
Or<StkItemUpdateDet.inventoryID.IsEqual<StkItemFilter.inventoryID.FromCurrent>>>.
And<StkItemFilter.fromEffectiveDate.FromCurrent.IsNull.
Or<StkItemUpdateHdr.effectiveDate.IsGreaterEqual<StkItemFilter.fromEffectiveDate.FromCurrent>>>.
And<StkItemFilter.toEffectiveDate.FromCurrent.IsNull.
Or<StkItemUpdateHdr.effectiveDate.IsLessEqual<StkItemFilter.toEffectiveDate.FromCurrent>>>>,
OrderBy<Desc<StkItemUpdateHdr.effectiveDate, Asc<StkItemUpdateDet.updateID, Asc<Vendor.acctCD, Asc<InventoryItem.inventoryCD>>>>>>
StkItemUpdates;
#endregion
#region Constructor
public StkItemUpdateProcess()
{
StkItemUpdates.SetProcessCaption("Update");
StkItemUpdates.SetProcessTooltip("Update Selected Stock Items");
StkItemUpdates.SetProcessAllCaption("Update All");
StkItemUpdates.SetProcessAllTooltip("Update All Stock Items");
StkItemUpdates.SetProcessDelegate(UpdateStkItems);
StkItemUpdates.SetSelected<StkItemUpdateDet.selected>();
}
#endregion
#region Overrides
public override bool IsDirty => false;
#endregion
#region Event Handlers
protected virtual void _(Events.FieldUpdated<StkItemFilter, StkItemFilter.updateID> e)
{
if (e.Row == null) return;
StkItemFilter filter = Filter.Current;
if(filter.UpdateID != null)
{
StkItemUpdateHdr hdr =
SelectFrom<StkItemUpdateHdr>.
Where<StkItemUpdateHdr.updateID.IsEqual<#P.AsString>>.
View.ReadOnly.Select(e.Cache.Graph, filter.UpdateID);
e.Cache.SetValueExt<StkItemFilter.vendorID>(filter, hdr?.VendorID);
}
}
protected virtual void _(Events.FieldSelecting<StkItemUpdateDet, StkItemUpdateDet.defaultVendor> e)
{
if (e.Row == null) return;
StkItemUpdateDet det = e.Row;
PXResultset<POVendorInventory> existingVendors =
SelectFrom<POVendorInventory>.
Where<POVendorInventory.inventoryID.IsEqual<#P.AsInt>>.
View.ReadOnly.Select(e.Cache.Graph, det.InventoryID);
//IsDefault cannot be used in BQL statement because it is not bound.
foreach (POVendorInventory vendor in existingVendors)
{
if (vendor.IsDefault == true)
{
e.ReturnValue = vendor.VendorID;
break;
}
}
}
#endregion
#region Actions
public PXAction<StkItemFilter> OpenUpdate;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Open Update")]
public virtual void openUpdate()
{
StkItemUpdateDet det = StkItemUpdates.Current;
StkItemUpdateMaint stkItemUpdateMaint = PXGraph.CreateInstance<StkItemUpdateMaint>();
stkItemUpdateMaint.UpdateHdr.Current = stkItemUpdateMaint.UpdateHdr.Search<StkItemUpdateHdr.updateID>(det.UpdateID);
if (stkItemUpdateMaint.UpdateHdr.Current != null)
{
throw new PXRedirectRequiredException(stkItemUpdateMaint, true, "Stock Item Update")
{
Mode = PXBaseRedirectException.WindowMode.NewWindow
};
}
}
public PXAction<StkItemFilter> OpenStockItem;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Open Stock Item")]
public virtual void openStockItem()
{
StkItemUpdateDet det = StkItemUpdates.Current;
InventoryItemMaint invtItemMaint = PXGraph.CreateInstance<InventoryItemMaint>();
invtItemMaint.Item.Current = invtItemMaint.Item.Search<InventoryItem.inventoryID>(det.InventoryID);
if (invtItemMaint.Item.Current != null)
{
throw new PXRedirectRequiredException(invtItemMaint, true, "Stock Item")
{
Mode = PXBaseRedirectException.WindowMode.NewWindow
};
}
}
#endregion
#region Static Methods
public static void UpdateStkItems(List<StkItemUpdateDet> stkItemUpdateDets)
{
StkItemUpdateMaint stkItemUpdateMaint = PXGraph.CreateInstance<StkItemUpdateMaint>();
InventoryItemMaint invtItemMaint = PXGraph.CreateInstance<InventoryItemMaint>();
foreach (StkItemUpdateDet det in stkItemUpdateDets)
{
stkItemUpdateMaint.Clear();
invtItemMaint.Clear();
StkItemUpdateHdr hdr = stkItemUpdateMaint.UpdateHdr.Current = stkItemUpdateMaint.UpdateHdr.Search<StkItemUpdateHdr.updateID>(det.UpdateID);
InventoryItem invtItem = invtItemMaint.Item.Current = invtItemMaint.Item.Search<InventoryItem.inventoryID>(det.InventoryID);
if (hdr == null || invtItem == null) continue;
BasisPricing.BasisPricing_InventoryItemExt invtItemExt = PXCache<InventoryItem>.GetExtension<BasisPricing.BasisPricing_InventoryItemExt>(invtItem);
bool fieldUpdated = false;
if (invtItemExt.UsrManualCost != det.ManualCost)
{
invtItemMaint.Item.Cache.SetValueExt<BasisPricing.BasisPricing_InventoryItemExt.usrManualCost>(invtItem, det.ManualCost);
fieldUpdated = true;
}
if (invtItem.RecPrice != det.MSRP)
{
invtItemMaint.Item.Cache.SetValueExt<InventoryItem.recPrice>(invtItem, det.MSRP);
fieldUpdated = true;
}
if (fieldUpdated)
{
invtItemMaint.Item.Cache.Update(invtItem);
invtItemMaint.Actions.PressSave();
det.LastUpdatedDateTime = DateTime.Now;
stkItemUpdateMaint.UpdateDets.Cache.Update(det);
stkItemUpdateMaint.Actions.PressSave();
}
}
}
#endregion
}
Here is my ASPX code:
<%# Page Language="C#" MasterPageFile="~/MasterPages/FormView.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="IN507500.aspx.cs" Inherits="Page_IN507500" Title="Untitled Page" %>
<%# MasterType VirtualPath="~/MasterPages/FormView.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
TypeName="INCostPriceUpdate.StkItemUpdateProcess"
PrimaryView="Filter"
>
<CallbackCommands>
<px:PXDSCallbackCommand Name="OpenUpdate" Visible="false" />
<px:PXDSCallbackCommand Name="OpenStockItem" Visible="false" />
</CallbackCommands>
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" DataMember="Filter" Width="100%" AllowAutoHide="false">
<Template>
<px:PXLayoutRule ID="PXLayoutRule1" runat="server" StartRow="True"/>
<px:PXLayoutRule ID="PXLayoutRule2" runat="server" StartColumn="True" LabelsWidth="85px" ControlSize="XM" />
<px:PXSelector ID="PXSelector1" runat="server" DataField="UpdateID" CommitChanges="true" />
<px:PXSelector ID="FilterVendorID" runat="server" DataField="VendorID" CommitChanges="true" />
<px:PXSelector ID="FilterInventoryID" runat="server" DataField="InventoryID" CommitChanges="true" />
<px:PXLayoutRule ID="PXLayoutRule3" runat="server" StartColumn="True" LabelsWidth="75px" />
<px:PXDateTimeEdit ID="FilterFromDate" runat="server" DataField="FromEffectiveDate" CommitChanges="true" />
<px:PXDateTimeEdit ID="FilterToDate" runat="server" DataField="ToEffectiveDate" CommitChanges="true" />
</Template>
<AutoSize Container="Window" Enabled="True" MinHeight="30" />
</px:PXFormView>
<px:PXGrid ID="StkItemUpdateDetGrid" runat="server" Width="100%" Height="650px" SyncPosition="true" AdjustPageSize="Auto" AllowPaging="false" SkinID="PrimaryInquire" DataSourceID="ds">
<Levels>
<px:PXGridLevel DataMember="StkItemUpdates">
<Columns>
<px:PXGridColumn DataField="Selected" Type="CheckBox" TextAlign="Center" CommitChanges="true" AllowCheckAll="true" AllowMove="false" AllowResize="false" AllowSort="false" AllowShowHide="false"></px:PXGridColumn>
<px:PXGridColumn DataField="StkItemUpdateHdr__VendorID" Width="140" ></px:PXGridColumn>
<px:PXGridColumn DataField="UpdateID" LinkCommand="OpenUpdate" ></px:PXGridColumn>
<px:PXGridColumn DataField="StkItemUpdateHdr__EffectiveDate" Width="90" />
<px:PXGridColumn DataField="InventoryID" CommitChanges="true" Width="150" LinkCommand="OpenStockItem" ></px:PXGridColumn>
<px:PXGridColumn DataField="InventoryDescr" Width="200" ></px:PXGridColumn>
<px:PXGridColumn DataField="ManualCost" Width="100" CommitChanges="true" ></px:PXGridColumn>
<px:PXGridColumn DataField="MSRP" Width="100" CommitChanges="true" ></px:PXGridColumn>
<px:PXGridColumn DataField="CurrManualCost" Width="100" ></px:PXGridColumn>
<px:PXGridColumn DataField="CurrMSRP" Width="100" ></px:PXGridColumn>
<px:PXGridColumn DataField="LastUpdatedDateTime" Width="150" DisplayFormat="g" ></px:PXGridColumn>
<px:PXGridColumn DataField="DefaultVendor" Width="150" ></px:PXGridColumn>
<px:PXGridColumn DataField="AvailVendors" Width="250" ></px:PXGridColumn></Columns>
<RowTemplate>
<px:PXSelector AllowEdit="True" runat="server" ID="CstPXSelector1" DataField="DefaultVendor" ></px:PXSelector>
<px:PXSelector runat="server" ID="CstPXSelector3" DataField="StkItemUpdateHdr__VendorID" AllowEdit="True" ></px:PXSelector></RowTemplate></px:PXGridLevel>
</Levels>
</px:PXGrid>
</asp:Content>
Here is the main DAC used on the Processing Screen:
public class StkItemUpdateDet : IBqlTable
{
#region Selected
[PXBool]
[PXUIField(DisplayName = "Selected")]
public virtual bool? Selected { get; set; }
public abstract class selected : PX.Data.BQL.BqlBool.Field<selected> { }
#endregion
#region UpdateID
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXUIField(DisplayName = "Update ID", Enabled = false)]
[PXDBDefault(typeof(StkItemUpdateHdr.updateID))]
[PXParent(typeof(SelectFrom<StkItemUpdateHdr>.
Where<StkItemUpdateHdr.updateID.IsEqual<StkItemUpdateDet.updateID.FromCurrent>>)
)]
public virtual string UpdateID { get; set; }
public abstract class updateID : PX.Data.BQL.BqlString.Field<updateID> { }
#endregion
#region InventoryID
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Inventory ID")]
[PXDefault]
[PXSelector(
typeof(
SearchFor<InventoryItem.inventoryID>.
In<SelectFrom<InventoryItem>.
InnerJoin<POVendorInventory>.
On<POVendorInventory.inventoryID.IsEqual<InventoryItem.inventoryID>>.
Where<InventoryItem.stkItem.IsEqual<True>.
And<POVendorInventory.vendorID.IsEqual<StkItemUpdateHdr.vendorID.FromCurrent>>.
And<POVendorInventory.active.IsEqual<True>>>>
),
typeof(InventoryItem.inventoryCD),
typeof(InventoryItem.descr),
typeof(InventoryItem.itemClassID),
typeof(InventoryItem.itemType),
SubstituteKey = typeof(InventoryItem.inventoryCD)
)]
[PXRestrictor(
typeof(Where<InventoryItem.stkItem.IsEqual<True>.
And<POVendorInventory.vendorID.IsEqual<StkItemUpdateHdr.vendorID.FromCurrent>>.
And<POVendorInventory.active.IsEqual<True>>>),
Messages.InvalidVendorItemPair)]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : PX.Data.BQL.BqlInt.Field<inventoryID> { }
#endregion
#region InventoryDesc
[PXString]
[PXUIField(DisplayName = "Descr.", Enabled = false)]
[InventoryDescr]
public virtual string InventoryDescr { get; set; }
public abstract class inventoryDescr : PX.Data.BQL.BqlString.Field<inventoryDescr> { }
#endregion
#region ManualCost
[PXDBDecimal(6)]
[PXUIField(DisplayName = "New Manual Cost")]
[PXDefault(TypeCode.Decimal, "0.000000")]
public virtual decimal? ManualCost { get; set; }
public abstract class manualCost : PX.Data.BQL.BqlDecimal.Field<manualCost> { }
#endregion
#region MSRP
[PXDBDecimal(2)]
[PXUIField(DisplayName = "New MSRP")]
[PXDefault(TypeCode.Decimal, "0.00")]
public virtual decimal? MSRP { get; set; }
public abstract class msrp : PX.Data.BQL.BqlDecimal.Field<msrp> { }
#endregion
#region CurrManualCost
[PXDecimal(6)]
[PXUIField(DisplayName = "Current Manual Cost", Enabled = false)]
[ManualCost]
public virtual decimal? CurrManualCost { get; set; }
public abstract class currManualCost : PX.Data.BQL.BqlDecimal.Field<currManualCost> { }
#endregion
#region CurrMSRP
[PXDecimal(2)]
[PXUIField(DisplayName = "Current MSRP", Enabled = false)]
[MSRP]
public virtual decimal? CurrMSRP { get; set; }
public abstract class currMSRP : PX.Data.BQL.BqlDecimal.Field<currMSRP> { }
#endregion
#region LastUpdatedDateTime
[PXDBDate(PreserveTime = true, UseTimeZone = false)]
[PXUIField(DisplayName = "Update Last Executed", Enabled = false)]
public virtual DateTime? LastUpdatedDateTime { get; set; }
public abstract class lastUpdatedDateTime : PX.Data.BQL.BqlDateTime.Field<lastUpdatedDateTime> { }
#endregion
#region DefaultVendor
[PXInt]
[PXUIField(DisplayName = "Default Vendor", Enabled = false)]
[PXSelector(
typeof(SearchFor<Vendor.bAccountID>),
SubstituteKey = typeof(Vendor.acctCD)
)]
public int? DefaultVendor { get; set; }
public abstract class defaultVendor : PX.Data.BQL.BqlInt.Field<defaultVendor> { }
#endregion
#region AvailVendors
[PXString]
[PXUIField(DisplayName = "Available Vendors", Enabled = false)]
[AvailVendors]
public string AvailVendors { get; set; }
public abstract class availVendors : PX.Data.BQL.BqlString.Field<availVendors> { }
#endregion
#region System Fields
#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
#endregion
#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
#endregion
#region CreatedDateTime
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
#endregion
#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
#endregion
#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
#endregion
#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
#endregion
#region tstamp
[PXDBTimestamp()]
public virtual byte[] tstamp { get; set; }
public abstract class Tstamp : PX.Data.BQL.BqlByteArray.Field<Tstamp> { }
#endregion
#region Noteid
[PXNote()]
public virtual Guid? Noteid { get; set; }
public abstract class noteid : PX.Data.BQL.BqlGuid.Field<noteid> { }
#endregion
#endregion
}

Unbound Field in Standalone Projection

I have a Rich Text field attached to the PMQuote and CRQuote DACs. On the CRQuote, the user field is on the standalone class and the regular class, and that is working as desired. However, Acumatica's reporting does not show the HTML formatting so I am creating an unbound Plain Text field to put on the reports and in GI's. This field works fine on the PMQuote, but not on the CRQuote. On the CRQuote, the field is there, but it is always blank. I'm sure it is something to do with the projection, but I'm not sure how it should be created.
Here is the PMQuote field (working properly)
[PXString(IsUnicode = true)]
[PXUIField(Visible = false, DisplayName = "Scope Text")]
public virtual String UsrScopePlainText
{
get
{
return PX.Data.Search.SearchService.Html2PlainText(UsrScope);
}
}
public abstract class usrScopePlainText : PX.Data.BQL.BqlString.Field<usrScopePlainText> { }
And here is what I have on the CRQuote (not working):
public class CRQuoteExt : PXCacheExtension<CRQuote>
{
#region UsrScope
[PXDBText(IsUnicode = true, BqlField = typeof(CRQuoteStandaloneExt.usrScope))]
[PXUIField(DisplayName = "Scope")]
public virtual string UsrScope { get; set; }
public abstract class usrScope : IBqlField { }
#endregion
#region UsrScopePlainText
[PXString(IsUnicode = true)]
[PXUIField(Visible = false, DisplayName = "Scope Text")]
public virtual String UsrScopePlainText
{
get
{
return PX.Data.Search.SearchService.Html2PlainText(UsrScope);
}
}
public abstract class usrScopePlainText : IBqlField { }
#endregion
}
public class CRQuoteStandaloneExt : PXCacheExtension<PX.Objects.CR.Standalone.CRQuote>
{
#region UsrScope
[PXDBText(IsUnicode = true)]
[PXUIField(DisplayName = "Scope")]
public virtual string UsrScope { get; set; }
public abstract class usrScope : IBqlField { }
#endregion
#region UsrScopePlainText
[PXString(IsUnicode = true)]
[PXUIField(Visible = false, DisplayName = "Scope Text")]
public virtual String UsrScopePlainText
{
get
{
return PX.Data.Search.SearchService.Html2PlainText(UsrScope);
}
}
public abstract class usrScopePlainText : IBqlField { }
#endregion
}
Thanks!
An alternative solution could be to have a reusable attribute that you can attach to any field. I think this is cleaner than adding logic directly in the Data Access class...
using PX.Objects.IN;
using PX.Data;
using System;
namespace PX.Objects.IN
{
public class InventoryItemPlainTextBodyExt : InventoryItem
{
[HtmlToText(typeof(InventoryItem.body))]
[PXDependsOnFields(typeof(InventoryItem.body))]
[PXUIField(DisplayName="Body (Plain Text)")]
public virtual string BodyPlainText { get; set; }
public abstract class bodyPlainText : PX.Data.BQL.BqlString.Field<bodyPlainText> { }
}
[PXString]
public class HtmlToTextAttribute : PXEventSubscriberAttribute, IPXFieldSelectingSubscriber
{
protected Type _htmlField;
public HtmlToTextAttribute(Type htmlField) :base()
{
_htmlField = htmlField;
}
public void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
e.ReturnValue = PX.Data.Search.SearchService.Html2PlainText(sender.GetValue(e.Row, _htmlField.Name) as string);
}
}
}
I'm not sure what happened, but I put the original code I posted above back into the customization project and it started working as expected.

Replace a checkbox by a Yes/No dropdown box in Acumatica

Good day
I have a checkbox on my shipment page called Special Labels.
The client wants the field to display as a Yes/No dropdown box or something in that line.
Is this possible?
I think you could handle this a couple of ways:
Option 1 (PXDropdown):
Create a string field for a Yes/No dropdown and use its value to set your boolean field:
#region ActiveString
public abstract class activeString : PX.Data.IBqlField
{
}
[PXString]
[PXDefault("false")]
[YesNo.List()]
[PXUIField(DisplayName = "Active")]
public virtual string ActiveString { get; set; }
#endregion
#region Active
public abstract class active : PX.Data.IBqlField
{
}
[PXDBBool]
[PXDefault(true)]
[PXUIField(DisplayName = "Active", Visible = false, Enabled = false)]
public virtual bool? Active {
get { return Convert.ToBoolean(this.ActiveString ?? "false"); }
set { value = Convert.ToBoolean(this.ActiveString ?? "false"); }
}
#endregion
The dropdown ASPX markup:
<px:PXDropdown ID="edActive" runat="server"
DataField="ActiveString" Size="XS" >
<AutoCallBack Command="Save" Target="form">
</AutoCallBack>
</px:PXDropdown>
Option 2 (PXSelector):
Create a small table in the database for a selector, such as:
CREATE TABLE [dbo].[UsrTrueFalse]
(
[BoolValue] bit NOT NULL,
[TextValue] [varchar](3) NOT NULL
)
and create a DAC over the table:
[System.SerializableAttribute()]
public class UsrTrueFalse : IBqlTable
{
#region BoolValue
public abstract class boolValue : PX.Data.IBqlField
{
}
[PXDBBool]
[PXUIField(DisplayName = "Bool Value")]
public virtual bool? BoolValue { get; set; }
#endregion
#region TextValue
public abstract class textValue : PX.Data.IBqlField
{
}
[PXDBString(3)]
[PXUIField(DisplayName = "Text Value")]
public virtual string TextValue { get; set; }
#endregion
}
and then add a PXSelector attribute on your boolean field:
#region Active
public abstract class active : PX.Data.IBqlField
{
}
[PXDBBool]
[PXDefault(true)]
[PXSelector(typeof(Search<UsrTrueFalse.boolValue>),
DescriptionField = typeof(UsrTrueFalse.textValue))]
[PXUIField(DisplayName = "Active")]
public virtual bool? Active { get; set; }
#endregion
The PXSelector ASPX markup:
<px:PXSelector ID="edActive" runat="server" DataField="Active" DataSourceID="ds" Size="XS" DisplayMode="Text">
<AutoCallBack Command="Save" Target="form">
</AutoCallBack>
</px:PXSelector>

I am trying to bring selector(Formula CD) for filter data in formula master screen,

FormulaID is the identity field and it's new developed screen, but I am not able to get the selector. I have tried all the ways that I know to achieve that:
Maintaining parent and child relationships
Dataview with BQL Query
Below are the definitions of the FormulaID and FormulaCD from DAC:
#region FormulaID
public abstract class formulaID : PX.Data.IBqlField
{
}
protected int? _FormulaID;
[PXDBIdentity(IsKey =true)]
[PXUIField(Enabled = false)]
public virtual int? FormulaID
{
get
{
return this._FormulaID;
}
set
{
this._FormulaID = value;
}
#endregion
#region FormulaCD
public abstract class formulaCD : PX.Data.IBqlField
{
}
protected string _FormulaCD;
[PXDBString(30,IsUnicode = true)]
[PXUIField(DisplayName = "Formula ID", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<TSFormula.formulaCD>),
typeof(TSFormula.descr),SubstituteKey = typeof(TSFormula.formulaCD), ValidateValue = false)]
public virtual string FormulaCD
{
get
{
return this._FormulaCD;
}
set
{
this._FormulaCD = value;
}
}
#endregion
In my example below, the PXDBIdentity integer field is not enabled and not visible. The String field is marked isKey=true with the PXSelector described. The ASPX page markup offers the px:PXSelector tag for the String field as shown:
<px:PXSelector ID="edContractNumber" runat="server" DataField="ContractNumber"
AutoRefresh="True" DataSourceID="ds" NullText="<NEW>">
<GridProperties FastFilterFields="ShortName">
<Columns>
<px:PXGridColumn DataField="ContractNumber" Width="90px"></px:PXGridColumn>
<px:PXGridColumn DataField="ShortName" Width="120px"></px:PXGridColumn>
</Columns>
</GridProperties>
</px:PXSelector>
Here are the DAC fields:
#region ContractID
public abstract class contractID : PX.Data.IBqlField
{
}
[PXDBIdentity()]
[PXDefault(0)]
[PXUIField(Visible = false, Enabled = false)]
public virtual int? ContractID
{
get;
set;
}
#endregion
#region ContractNumber
public abstract class contractNumber : PX.Data.IBqlField
{
}
[PXDBString(IsKey = true)]
[PXDefault()]
[PXSelector(typeof(Search3<MyDAC.contractNumber,
OrderBy<Desc<MyDAC.contractID>>>),
new Type[] {
typeof(MyDAC.shortName),
typeof(MyDAC.contractNumber)},
DirtyRead = true)]
[PXUIField(DisplayName = "Contract Number", Required = true)]
public virtual string ContractNumber { get; set; }
#endregion

Using Unbound DACs in Process graph fails to run Processing functions

I'm creating a Process to import items from an external API source into records in Acumatica.
I've created an unbound DAC that is used to represent the entries available from the external 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 { }
}
In a Process graph I implement the delegate of the main view to create and return the Resultset (normally generated from the API data). I then have a screen bound to this graph with a grid view that displays the items to allow the user to select the ones to import. The main Process delegate will then create the records in Acumatica for the selected items.
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");
}
}
And the ASPX page:
<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>
When written as the simplified example here the Process delegate is never invoked. I suspect is has something to do with when the Process button is clicked the callback to the server runs the view's delegate function that re-creates the list of ImportItem objects and that the framework can not relate the newly created objects to the ones in the postback without a Key field. However, if I add an IsKey attribute to the RefNbr of the DAC...
[PXString(IsKey = true)]
[PXUIField(DisplayName = "External Ref Nbr")]
public string RefNbr { get; set; }
...now when selecting an item on the Screen I'm immediately given a line-level error with the message "Error: The argument is out of range. Parameter name: table".
In the data view delegate, you have to add the items to the Cache in addition to returning them. Try below:
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;
}
}
}
Good luck!
Try adding abstract classes for your DAC fields first.
If that doesn't resolve your issue please add your ASPX code to your question.
[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
}
I have tried the Processing Graph functionality Using Bound DAC but not Database Table.
This is useful in the case when you want to Access some API and fetch the records in processing screen without saving into the Database. I am not including aspx code here.
The Highlight point in this code in [PXVirtualDAC] and the Key Field in DAC because of this we can achieve this functionality without creating a table. You can say that a Virtual DAC - without bound any database table.
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

Resources