Custom Tab with Grid not refreshing with navigating master data - acumatica

I have created a new table which is a child table for Vendor. Here I want to store some dates for each vendor. Below is the table structure (where CompanyID and RecordID is a PrimaryKey, RecordID is Identity with seed 1)-
CREATE TABLE [dbo].[VendorClosedDates](
[CompanyID] [int] NOT NULL,
[RecordID] [int] IDENTITY(1,1) NOT NULL,
[VendorID] [int] NOT NULL,
[VendorCloseDate] [datetime] NOT NULL,
[tstamp] [timestamp] NOT NULL,
[CreatedByID] [uniqueidentifier] NOT NULL,
[CreatedByScreenID] [char](8) NOT NULL,
[CreatedDateTime] [datetime] NOT NULL,
[LastModifiedByID] [uniqueidentifier] NOT NULL,
[LastModifiedByScreenID] [char](8) NOT NULL,
[LastModifiedDateTime] [datetime] NOT NULL,
CONSTRAINT [PK_VendorClosedDates] PRIMARY KEY CLUSTERED
(
[CompanyID] ASC,
[RecordID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Based on this I have created a custom project with dataview and added a new tab with grid to display all dates (only 1 column) from the new table. Based on the vendor I browse, these grid should refresh and show me only related data. However, for some reason it is not refreshing and not even showing any data. Below is the screenshot and some code snippet to help understand how I have code in place. May be I am missing something.
Grid code-
<px:PXTabItem Text="Closed Dates">
<Template>
<px:PXGrid runat="server" ID="CstPXGrid79" DataSourceID="ds" SkinID="DetailsInTab" Height="150px" Width="100%" AdjustPageSize="Auto" AllowPaging="True">
<Levels>
<px:PXGridLevel DataMember="ClosedDates">
<Columns>
<px:PXGridColumn DataField="VendorCloseDate" Width="90" /></Columns>
<RowTemplate>
<px:PXDateTimeEdit runat="server" ID="CstPXDateTimeEdit82" DataField="VendorCloseDate" /></RowTemplate></px:PXGridLevel></Levels>
<Mode AllowAddNew="True" AllowDelete="True" AllowUpdate="True" />
<AutoSize MinHeight="1000" /></px:PXGrid></Template></px:PXTabItem>
DAC snippet-
#region RecordID
public abstract class recordID : PX.Data.IBqlField
{
}
protected int? _RecordID;
[PXDBIdentity(IsKey = true)]
public virtual int? RecordID
{
get
{
return this._RecordID;
}
set
{
this._RecordID = value;
}
}
#endregion
#region VendorID
public abstract class vendorID : PX.Data.IBqlField
{
}
protected int? _VendorID;
[PXDBInt()]
[PXDefault(typeof(Vendor.bAccountID))]
public virtual int? VendorID
{
get
{
return this._VendorID;
}
set
{
this._VendorID = value;
}
}
#endregion
#region VendorCloseDate
public abstract class vendorCloseDate : PX.Data.IBqlField
{
}
protected DateTime? _VendorCloseDate;
[PXDBDate()]
[PXUIField(DisplayName = "Vendor Close Date")]
public virtual DateTime? VendorCloseDate
{
get
{
return this._VendorCloseDate;
}
set
{
this._VendorCloseDate = value;
}
}
#endregion
Dataview and Vendor_RowSelecting event under VendorMaint extension-
[PXViewName("ClosedDates")]
public PXSelect<VendorClosedDates,
Where<VendorClosedDates.vendorID, Equal<Current<Vendor.bAccountID>>>> ClosedDates;
protected virtual void Vendor_RowSelecting(PXCache cache, PXRowSelectingEventArgs e)
{
ClosedDates.View.RequestRefresh();
}
Any suggestion.

Everything looks good besides 2 things:
lack of Enabled property set to True for PXGrid.AutoSize (let me also suggest to change MinHeight to 200, as 1000 is way to much)
absolutely unnecessary use of RequestRefresh method in RowSelected handler - it must be removed from your BLC extension:
protected virtual void Vendor_RowSelecting(PXCache cache, PXRowSelectingEventArgs e)
{
ClosedDates.View.RequestRefresh();
}
On a side note, let me also suggest to replace PXDefault attribute with PXDBDefault on VendorID field within the VendorClosedDates DAC and additionally decorate VendorID with PXParent attribute:
[Serializable]
public class VendorClosedDates : IBqlTable
{
...
#region VendorID
[PXDBInt()]
[PXDBDefault(typeof(Vendor.bAccountID))]
[PXParent(typeof(Select<Vendor, Where<Vendor.bAccountID, Equal<Current<VendorClosedDates.vendorID>>>>))]
public int? VendorID { get; set; }
public class vendorID : IBqlField { }
#endregion
...
}
Vendor.BAccountID field is mapped to an identity column. Use of the PXDBDefault attribute is required in such cases, otherwise VendorClosedDates.VendorID field won't be updated with new Vendor.BAccountID value generated by database.
PXParentAttribute is required for cascade deletion of VendorClosedDates records when Vendor is deleted from application

Related

Acumatica APInvoice Extension Breaks Quick Checks

Version is 19.110.0013
I have created an inner join extension table for APInvoice. This has caused an issue with the Quick Checks flow. Specifically, creation of a Quick Check creates a record within the APInvoice table, but not a corresponding record in the extension table.
My DAC
using PX.Data;
using PX.Objects.AP;
namespace MyProject.DAC
{
[PXTable(IsOptional = false)]
[Serializable()]
public class ApInvoiceExtension : PXCacheExtension<APInvoice>
{
#region MyCustomFlag
public abstract class myCustomFlag : IBqlField { }
[PXDBBool()]
[PXUIField(DisplayName = "Custom Flag")]
public virtual bool? MyCustomFlag { get; set; }
#endregion
}
}
My Table
CREATE TABLE [dbo].[ApInvoiceExtension](
[CompanyID] [int] NOT NULL,
[DocType] [char](3) NOT NULL,
[RefNbr] [nvarchar](15) NOT NULL,
[MyCustomFlag] [bit] NULL,
CONSTRAINT [ApInvoiceExtension_PK] PRIMARY KEY CLUSTERED
(
[CompanyID] ASC,
[DocType] ASC,
[RefNbr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ApInvoiceExtension] ADD DEFAULT ((0)) FOR [CompanyID]
GO
I'm quite sure this has to do with the definition of APQuickCheck which is a DAC with the following attribute
[PXProjection(typeof(Select2<APRegister,
InnerJoin<APInvoice, On<APInvoice.docType, Equal<APRegister.docType>,
And<APInvoice.refNbr, Equal<APRegister.refNbr>>>,
InnerJoin<APPayment, On<APPayment.docType, Equal<APRegister.docType>,
And<APPayment.refNbr, Equal<APRegister.refNbr>>>>>,
Where<APRegister.docType, Equal<APDocType.quickCheck>,
Or<APRegister.docType, Equal<APDocType.voidQuickCheck>>>>), Persistent = true)]
The saving against this projection ignores the required extension records. I wondered if the issue was because the APInvoice referenced here was from the PX.Objects.AP.Standalone namespace instead of the PX.Objects.AP namespace which I extended, so I did attempt to get around this by creating a DAC extension for this namespace as well. My extension looked like this
using PX.Data;
using PX.Objects.AP.Standalone;
namespace MyProject.DAC.Standalone
{
[PXTable(IsOptional = false)]
[Serializable()]
public class ApInvoiceExtension : PXCacheExtension<APInvoice>
{
#region MyCustomFlag
public abstract class myCustomFlag : IBqlField { }
[PXDBBool()]
[PXUIField(DisplayName = "Custom Flag")]
public virtual bool? MyCustomFlag { get; set; }
#endregion
}
}
This addition didn't change the behavior, Quick Checks still created an entry in APInvoice but not in my APInvoiceExtension table.
You are absolutely right and this is because of PXProjection attribute. Please note that PXProjection is not a real table but like SQL view with a set of fields taken from several tables. You can see that APQuickCheck projection is a child APRegister class - as a result, it knows nothing about extended APInvoice fields and you should add them manually using PXDBFieldAttribute.BqlField property.
[PXNonInstantiatedExtension]
public class APQuickCheckExtension : PXCacheExtension<APQuickCheck>
{
#region MyCustomFlag
public abstract class myCustomFlag : IBqlField { }
[PXDBBool(BqlField = typeof(ApInvoiceExtension.myCustomFlag))]
[PXUIField(DisplayName = "Custom Flag")]
public virtual bool? MyCustomFlag
{
get;
set;
}
#endregion
}
[PXTable(IsOptional = false)]
[Serializable()]
public class ApInvoiceExtension : PXCacheExtension<APInvoice>
{
#region MyCustomFlag
public abstract class myCustomFlag : IBqlField { }
[PXDBBool()]
[PXUIField(DisplayName = "Custom Flag")]
public virtual bool? MyCustomFlag { get; set; }
#endregion
}
When doing an extension table you need to indicate the base table keys as the link in PXTable (or at least this was required back in 5.X when we first started using table extensions).
So your DAC extension might look like this:
[PXTable(typeof(APInvoice.docType), typeof(APInvoice.refNbr), IsOptional = false)]
[Serializable]
public class ApInvoiceExtension : PXCacheExtension<APInvoice>
{
#region MyCustomFlag
public abstract class myCustomFlag : IBqlField { }
[PXDBBool()]
[PXUIField(DisplayName = "Custom Flag")]
public virtual bool? MyCustomFlag { get; set; }
#endregion
}
Another note: Because your table is not optional you will need to pre-fill the extension table from the base table so you have all rows 1 for 1. I would recommend setting the IsOptional to true. When false and you have an APInvoice record without a matching APInvoiceExtension record the displayed values in screens and selectors might not display or function correctly.
Ended up opening a case with Acumatica. Response was that I needed to extend APRegister not APInvoice. Ended up changing APInvoice to APRegister (had to backfill my records) and it worked.
using PX.Data;
using PX.Objects.AP;
namespace MyProject.DAC
{
[PXTable(IsOptional = false)]
[Serializable()]
public class ApRegisterExtension : PXCacheExtension<ApRegister>
{
#region MyCustomFlag
public abstract class myCustomFlag : IBqlField { }
[PXDBBool()]
[PXUIField(DisplayName = "Custom Flag")]
public virtual bool? MyCustomFlag { get; set; }
#endregion
}
}
CREATE TABLE [dbo].[ApRegisterExtension](
[CompanyID] [int] NOT NULL,
[DocType] [char](3) NOT NULL,
[RefNbr] [nvarchar](15) NOT NULL,
[MyCustomFlag] [bit] NULL,
CONSTRAINT [ApRegisterExtension_PK] PRIMARY KEY CLUSTERED
(
[CompanyID] ASC,
[DocType] ASC,
[RefNbr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ApRegisterExtension] ADD DEFAULT ((0)) FOR [CompanyID]
GO

Int32 cast error in Generic Inquiry after saving a row in the table

I created a new custom table, and a new screen (FormView) to enter data. I created a Generic Inquiry to navigate to the new entry screen. After I entered and save the first record in the new table with the new entry screen, the Generic Inquiry screen throws a casting error on one of the columns. This should all be very quick and easy, but I can't seem to get around the casting error.
New table structure:
CREATE TABLE [dbo].[DPItemRebate](
[CompanyID] [int] NOT NULL,
[VendorID] [int] NOT NULL,
[CustomerID] [int] NOT NULL,
[InventoryID] [int] NOT NULL,
[RebateAmt] [decimal](19, 4) NOT NULL,
CONSTRAINT [PK_DPItemRebate] PRIMARY KEY CLUSTERED
([CompanyID] ASC, [VendorID] ASC, [CustomerID] ASC, [InventoryID] ASC)...
DAC:
[Serializable]
public class DPItemRebate : IBqlTable
{
#region VendorID
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Vendor")]
[Vendor(typeof(Search<BAccountR.bAccountID,
Where<BAccountR.type, Equal<BAccountType.companyType>,
Or<Vendor.type, NotEqual<BAccountType.employeeType>>>>),
Visibility = PXUIVisibility.SelectorVisible, CacheGlobal = true,
Filterable = true)]
[PXRestrictor(typeof(Where<Vendor.status, IsNull,
Or<Vendor.status, Equal<BAccount.status.active>,
Or<Vendor.status, Equal<BAccount.status.oneTime>>>>),
PX.Objects.AP.Messages.VendorIsInStatus, typeof(Vendor.status))]
public virtual int? VendorID { get; set; }
public abstract class vendorID : IBqlField { }
#endregion
#region CustomerID
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Customer")]
[CustomerActive(typeof(Search<BAccountR.bAccountID,
Where<Customer.type, IsNotNull,
Or<BAccountR.type, Equal<BAccountType.companyType>>>>),
Visibility = PXUIVisibility.SelectorVisible,
DescriptionField = typeof(Customer.acctName),
Filterable = true)]
public virtual int? CustomerID { get; set; }
public abstract class customerID : IBqlField { }
#endregion
#region InventoryID
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Inventory Item")]
[Inventory(typeof(Search<InventoryItem.inventoryID,
Where2<Match<Current<AccessInfo.userName>>,
And<InventoryItem.itemStatus, NotEqual<InventoryItemStatus.unknown>>>>),
typeof(InventoryItem.inventoryCD), typeof(InventoryItem.descr),
Filterable = true)]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : IBqlField { }
#endregion
#region RebateAmt
[PXDBDecimal()]
[PXUIField(DisplayName = "Rebate Amount")]
public virtual Decimal? RebateAmt { get; set; }
public abstract class rebateAmt : IBqlField { }
#endregion
}
Generic Inquiry:
Tables: DPItemRebate.DPItemRebate
Relations: <none>
Results:
Object: DPItemRebate
Data Fields: vendorID, vendorID_description, customerID, customerID_description, inventoryID, inventoryID_description, rebateAmt
The DAC fields are lookups except for RebateAmt. I borrowed the selector attributes from elsewhere in Acumatica DAC code. I added all fields to a new entry page, entered data with the new page, then open the Generic Inquiry and it gives an error:
"[InvalidCastException: Specified cast is not valid.]
System.Data.SqlClient.SqlBuffer.get_Int32() +65
PX.Data.PXDataRecord.GetInt32(Int32 i) +96
PX.Data.PXDBIntAttribute.RowSelecting(PXCache sender, PXRowSelectingEventArgs e) +210
PX.Data.PXCache.OnRowSelecting(Object item, PXDataRecord record, Int32& position, Boolean isReadOnly) +650"
and
"[PXException: Error: An error occurred during processing of the field Customer: Specified cast is not valid..]"
When I comment out the DAC lookup definitions for Vendor, CustomerActive, And Inventory; the casting error goes away, so it's likely related; but I need these for field lookups. What am I defining wrong?
I changed all of my lookup field attribute definitions to base PXSelector attributes and it finally worked without error. I still don't know why the other Acumatica ones threw errors, though.
Do not redeclare [PXDBInt(IsKey = true)] it is already defined in the [CustomerActive] attribute.

Save Parent-Child

I am creating a graph using Acumatica Framework and I am trying to save changes to the database but I am getting an error on Save.
I have a typical parent/child (i.e. master/detail) relationships and everything should be set correctly.
My child DAC has the PXDBDefault and the PXParent entries:
[PXDBInt()]
[PXDBDefault(typeof(DCRuleHeader.ruleHeaderID))]
[PXParent(typeof(Select<DCRuleHeader, Where<DCRuleHeader.ruleHeaderID, Equal<Current<DCRule.ruleHeaderID>>>>))]
public virtual int? RuleHeaderID
{
get
{
return this._RuleHeaderID;
}
set
{
this._RuleHeaderID = value;
}
}
In the header, the ID is an identity in the database and defined as a key in the DAC as follows:
[PXDBIdentity(IsKey = true)]
[PXUIField(Enabled = false)]
public virtual int? RuleHeaderID
{
get
{
return this._RuleHeaderID;
}
set
{
this._RuleHeaderID = value;
}
}
The View is also configured accordingly:
public class RulesMaint : PXGraph<RulesMaint, DCRuleHeader>
{
public PXSelect<DCRuleHeader> RuleHeader;
public PXSelect<DCRule, Where<DCRule.ruleHeaderID, Equal<Current<DCRuleHeader.ruleHeaderID>>>> Rules;
public PXAction<DCRuleHeader> ViewRule;
However, the below code is not working
RulesMaint rulesGraph = PXGraph.CreateInstance<RulesMaint>();
DCRuleHeader newHeader = rulesGraph.RuleHeader.Insert();
...
DCRule rule = rulesGraph.Rules.Insert();
...
rulesGraph.Actions.PressSave();
When I try the above, I get the error 'Error "RuleHeaderID" cannot be empty'
Shouldn't the framework handle everything itself and set the Parent ID of the child object automatically? Isn't that what PXDBDefault is for ?
Here is example how you can get Parent/Child DACs working with Form Detail view in Acumatica ERP.
For the begging let's create SQL Tables for Parent and Child in the following way:
Parent:
/****** Object: Table [dbo].[SOCustomParentTable] Script Date: 07/03/2017 12:55:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SOCustomParentTable](
[CompanyID] [int] NOT NULL,
[ParentID] [int] IDENTITY(1,1) NOT NULL,
[Description] [nvarchar](255) NULL,
[SomeOtherField] [nvarchar](50) NULL,
[ParentCD] [nvarchar](15) NOT NULL
) ON [PRIMARY]
GO
And the child
/****** Object: Table [dbo].[SOCustomChildTable] Script Date: 07/03/2017 12:54:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SOCustomChildTable](
[CompanyID] [int] NOT NULL,
[ChildID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NOT NULL,
[Description] [nvarchar](255) NULL,
[SomeOtherField] [nvarchar](50) NULL
) ON [PRIMARY]
GO
Now as we have SQL Tables ready let's create DAC's as the following classes:
Parent :
using System;
using PX.Data;
namespace DemoParentChild
{
[Serializable]
public class SOCustomParentTable: IBqlTable
{
#region ParentID
[PXDBIdentity()]
public int? ParentID { get; set; }
public class parentID : IBqlField{}
#endregion
#region Description
[PXDBString(255, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Description")]
public string Description { get; set; }
public class description : IBqlField{}
#endregion
#region SomeOtherField
[PXDBString(50, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Some Other Field")]
public string SomeOtherField { get; set; }
public class someOtherField : IBqlField{}
#endregion
#region ParentCD
[PXDBString(15,IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Parent ID")]
public string ParentCD { get; set; }
public class parentCD : IBqlField{}
#endregion
}
}
And the child:
using System;
using PX.Data;
namespace DemoParentChild
{
[Serializable]
public class SOCustomChildTable: IBqlTable
{
#region ChildID
[PXDBIdentity(IsKey=true)]
public int? ChildID { get; set; }
public class childID : IBqlField{}
#endregion
#region ParentID
[PXDBInt()]
[PXDBDefault(typeof(SOCustomParentTable.parentID))]
[PXParent(typeof(Select<SOCustomParentTable, Where<SOCustomParentTable.parentID, Equal<Current<SOCustomChildTable.parentID>>>>))]
public int? ParentID { get; set; }
public class parentID : IBqlField{}
#endregion
#region Description
[PXDBString(255, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Description")]
public string Description { get; set; }
public class description : IBqlField{}
#endregion
#region SomeOtherField
[PXDBString(50, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Some Other Field")]
public string SomeOtherField { get; set; }
public class someOtherField : IBqlField{}
#endregion
}
}
And to finish our work let's create a page of FormDetail type with the following Graph:
using System;
using PX.Data;
namespace DemoParentChild
{
public class tmp : PXGraph<tmp>
{
public PXSave<SOCustomParentTable> Save;
public PXCancel<SOCustomParentTable> Cancel;
public PXPrevious<SOCustomParentTable> Prev;
public PXNext<SOCustomParentTable> Next;
public PXSelect<SOCustomParentTable> MasterView;
public PXSelect<SOCustomChildTable,Where<SOCustomChildTable.parentID,Equal<Current<SOCustomParentTable.parentID>>>> DetailsView;
}
}
Now let's understand how this all is working.
As you can see the ParentID is Identity in SQL and is set to PXDBIdentity in DAC, but it's not set to be a Key for our DAC as we will use ParentCD as visible Key.
Also in the Child class the ChildID is set to PXDBIdentity, but it is set to be Key also as we don't need the line to have visible key for user.
Also in the Child class we have the following for creation of the Parent/Child relation:
[PXDBInt()]
[PXDBDefault(typeof(SOCustomParentTable.parentID))]
[PXParent(typeof(Select<SOCustomParentTable, Where<SOCustomParentTable.parentID, Equal<Current<SOCustomChildTable.parentID>>>>))]
public int? ParentID { get; set; }
Where PXDefault is setting ParendID of the Child to current Parent's ID and PXParent is creating the Relation between current Child and the Parent.
Commonly there are being created Line Number for child and Line Counter on the Parent to know the count of the Childs.
The full customization you can download here
I was having trouble with this before, because i have a habit of putting new code at the top of the editor, turns out that the data view selection (child) should always be at the bottom (after pxselect)

Contact lookup based on Customer selection

I need to create a Contact lookup in SO screen (SO301000). I have already created user defined custom field as below. I is listing all contacts but it is not refreshing based on when select customer. Do I have to write any event for CustomerID to refresh these Contact lookup? Does anyone has any idea?
[PXDBInt]
[PXUIField(DisplayName = "Contact")]
[PXSelector(typeof(Search2<Contact.contactID,
LeftJoin<BAccount, On<BAccount.bAccountID, Equal<Contact.bAccountID>>>>),
DescriptionField = typeof(Contact.displayName), Filterable = true, DirtyRead = true)]
[PXRestrictor(typeof(Where<Contact.isActive, Equal<True>>), PX.Objects.CR.Messages.ContactInactive, typeof(Contact.displayName))]
[PXDBChildIdentity(typeof(Contact.contactID))]
public virtual int? UsrCustContactID { get; set; }
public abstract class usrCustContactID : IBqlField { }
You are missing Where Clause and you need to use BAccount2 instead of BAccount. SOOrderEntry Graph has data view defined with Vendor DAC which gets initialized first/before BAccount and framework will substitute it with Vendor DAC. To prevent this, you need to use BAccount2 DAC in your BQL.
using System;
using PX.Data;
using PX.Objects.SO;
using PX.Objects.CR;
namespace DemoPkg
{
public class SOOrderPXExt : PXCacheExtension<SOOrder>
{
#region UsrContactID
public abstract class usrContactID : IBqlField { }
[PXDBInt()]
[PXUIField(DisplayName = "Contact", Visibility = PXUIVisibility.Visible)]
[PXSelector(typeof(Search2<Contact.contactID,
LeftJoin<BAccount2, On<BAccount2.bAccountID, Equal<Contact.bAccountID>>>>),
DescriptionField = typeof(Contact.displayName), Filterable = true, DirtyRead = true)]
[PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
[PXFormula(typeof(Default<CRCase.customerID>))]
[PXRestrictor(typeof(Where<Contact.contactType, NotEqual<ContactTypesAttribute.bAccountProperty>,
And<Where<BAccount2.bAccountID, Equal<Current<SOOrder.customerID>>,
Or<Current<SOOrder.customerID>, IsNull>>>>), PX.Objects.CR.Messages.ContactBAccountDiff)]
[PXRestrictor(typeof(Where<Contact.isActive, Equal<True>>), PX.Objects.CR.Messages.ContactInactive,
typeof(Contact.displayName))]
public virtual Int32? UsrContactID { get; set; }
#endregion
}
}
And make sure you have AutoRefresh set to true in aspx for PXSelector control of this field.
I see you do not have a where condition in your selector to be based on the given customer. Try updating your selector to match something like this...
[PXSelector(typeof(Search2<Contact.contactID,
LeftJoin<BAccount, On<BAccount.bAccountID, Equal<Contact.bAccountID>>>,
Where<BAccount.bAccountID, Equal<Current<SOOrder.customerID>>>>),
DescriptionField = typeof(Contact.displayName), Filterable = true, DirtyRead = true)]
In your page also make sure your selector has AutoRefresh="true"
Example:
<px:PXSelector ID="edWeightUOM" runat="server"
DataField="WeightUOM" Size="S" AutoRefresh="true" />

Object reference not set to an instance of an object. when adding columns (extension table approach) in Acumatica ERP

I am trying to add additional fields "isInterestPenalty" and "previousInvoice".
here is my extended table script:
CREATE TABLE [ARInvoiceTableExtension]
(
[CompanyID] [int] NOT NULL,
[DocType] [char](3) NOT NULL,
[RefNbr] [int] NOT NULL,
[DeletedDatabaseRecord] [bit] NOT NULL,
[isInterestPenalty] [bit] DEFAULT 0,
[previousInvoice] [nvarchar](15),
CONSTRAINT [ARInvoiceTableExtension_PK] PRIMARY KEY CLUSTERED
(
[CompanyID] ASC,
[DocType],
[RefNbr]
)
WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[ARInvoiceTableExtension] ADD DEFAULT ((0))
FOR [DeletedDatabaseRecord]
GO
and here is my DAC for that.
namespace ContractPriceDetailsCustomization
{
[PXTable(typeof(ARInvoice.refNbr), typeof(ARInvoice.docType),
IsOptional = true)]
public class ARInvoiceTableExtension : PXCacheExtension<ARInvoice>
{
#region isInterestPenalty
public abstract class isInterestPenalty : PX.Data.IBqlField
{
}
[PXDBBool]
[PXDefault(false)]
public bool IsInterestPenalty { get; set; }
#endregion
#region previousInvoice
public abstract class previousInvoice : PX.Data.IBqlField
{
}
[PXDBString(15)]
[PXDefault("")]
public string PreviousInvoice { get; set; }
#endregion
}
}
The error appears in CT301000 because the customization targets that page.
I would like to know what i did wrong?
I already fixed it.
instead of:
public bool IsInterestPenalty { get; set; }
i used
public bool? IsInterestPenalty { get; set; }
i need the "?"

Resources