0

On a PO, I can't seem to get a PO Line's Account field (ExpenseAcctID) to persist. The value appears in the UI normally, and when I check the value in the FieldUpdated, RowUpdated, and RowPersisted handlers, the field actually has a value. Somehow it's not persisting to the db. The field was customized as shown below. The field in the .ASPX is specified as a PXSelector. Any ideas?

    [PXMergeAttributes(Method = MergeMethod.Replace)]
    [PXRestrictor(typeof(Where<Account.active, Equal<True>>), PX.Objects.GL.Messages.AccountInactive)]
    [PXRestrictor(typeof(Where<Where<Current<GLSetup.ytdNetIncAccountID>, IsNull,
                        Or<Account.accountID, NotEqual<Current<GLSetup.ytdNetIncAccountID>>>>>), PX.Objects.GL.Messages.YTDNetIncomeSelected)]
    [PXDimensionSelector(AccountAttribute.DimensionName,
        typeof(SearchFor<Account.accountID>
                .In<SelectFrom<Account>
                    .LeftJoin<PMBudget>.On<Account.accountGroupID.IsEqual<PMBudget.accountGroupID>>
                    .Where<
                        Where<POLine.lineType.FromCurrent.IsEqual<POLineType.nonStock>
                            .And<Where<PMBudget.projectID.IsEqual<POLine.projectID.FromCurrent>
                            .And<Where<PMBudget.projectTaskID.IsEqual<POLine.taskID.FromCurrent>
                            .And<Where<PMBudget.costCodeID.IsEqual<POLine.costCodeID.FromCurrent>
                            .And<Where<PMBudget.curyRevisedAmount.IsGreater<Zero>
                            .And<Where<PMBudget.accountGroupID.IsNotNull>
                            >>>>>>>>>
                        .Or<Where<POLine.lineType.FromCurrent.IsNotEqual<POLineType.nonStock>
                            .Or<Where<POLine.projectID.FromCurrent.IsNull
                            .Or<Where<POLine.taskID.FromCurrent.IsNull
                            .Or<Where<POLine.costCodeID.FromCurrent.IsNull
                            >>>>>>>>>>
                    .AggregateTo<GroupBy<Account.accountID>>
                    .OrderBy<Account.accountCD.Asc>>),
            typeof(Account.accountCD),
            new Type[] { typeof(Account.accountCD), typeof(Account.description), typeof(Account.accountGroupID), typeof(PMBudget.curyRevisedAmount),
                typeof(PMBudget.projectID), typeof(PMBudget.projectTaskID), typeof(PMBudget.costCodeID) },
            DescriptionField = typeof(Account.description),
            Filterable = false
            )]
    [PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
    [PXUIField(DisplayName = "Account", Visibility = PXUIVisibility.Visible)]
    protected void POLine_ExpenseAcctID_CacheAttached(PXCache cache)
    {
    }
Tony Lanzer
  • 281
  • 1
  • 15
  • 1
    Not adding as an answer because I'm not sure. I *think* Acumatica no longer knows it is a DB field. Try adding [PXDBInt]. You replaced the previously defined attribute of [Account] which contained the [PXDBInt] attribute in it, but your replacement does not tell Acumatica that it is a DB field since it no longer has reference to PXDBInt. – Brian Stevens Oct 17 '20 at 18:34
  • That worked, so go ahead and add as an answer if you want. :) I had thought about trying that actually, but the POLine class didn't include it so I didn't. As you mention, though, the AccountAttribute class did, but I didn't catch that. Thanks! – Tony Lanzer Oct 18 '20 at 07:06

1 Answers1

3

Acumatica needs the attribute [PXDBInt] to relate the field to the database. The original definition of the field in the DAC is:

#region ExpenseAcctID
public abstract class expenseAcctID : PX.Data.BQL.BqlInt.Field<expenseAcctID> { }
protected Int32? _ExpenseAcctID;
[Account(typeof(POLine.branchID),DisplayName = "Account", Visibility = PXUIVisibility.Visible, Filterable = false, DescriptionField = typeof(Account.description), AvoidControlAccounts = true)]
[PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
public virtual Int32? ExpenseAcctID
{
    get
    {
        return this._ExpenseAcctID;
    }
    set
    {
        this._ExpenseAcctID = value;
    }
}
#endregion

The [Account] attribute contains the following attributes that are applied for you:

[PXUIField(DisplayName = "Account", Visibility = PXUIVisibility.Visible, FieldClass = DimensionName)]   
[PXDBInt]
[PXInt]
[PXRestrictor(typeof(Where<Account.active, Equal<True>>), Messages.AccountInactive)]
[PXRestrictor(typeof(Where<Where<Current<GLSetup.ytdNetIncAccountID>, IsNull,
    Or<Account.accountID, NotEqual<Current<GLSetup.ytdNetIncAccountID>>>>>), Messages.YTDNetIncomeSelected)]    

By using [PXMergeAttributes(Method = MergeMethod.Replace)] in your cache_attached, all attributes within the DAC definition for that field are dropped and replaced with only what you define.

You switched to [PXDimensionSelector] which does not contain the attribute [PXDBInt]. That means Acumatica has no way of knowing that the field is intended to be tied to the database. You still have access to the field within the screen, but interactions between the cache and the database will skip this field.

To resolve, just add [PXDBInt] to your cache_attached as follows:

[PXMergeAttributes(Method = MergeMethod.Replace)]
[PXDBInt]
[PXRestrictor(typeof(Where<Account.active, Equal<True>>), PX.Objects.GL.Messages.AccountInactive)]
[PXRestrictor(typeof(Where<Where<Current<GLSetup.ytdNetIncAccountID>, IsNull,
                    Or<Account.accountID, NotEqual<Current<GLSetup.ytdNetIncAccountID>>>>>), PX.Objects.GL.Messages.YTDNetIncomeSelected)]
[PXDimensionSelector(AccountAttribute.DimensionName,
    typeof(SearchFor<Account.accountID>
            .In<SelectFrom<Account>
                .LeftJoin<PMBudget>.On<Account.accountGroupID.IsEqual<PMBudget.accountGroupID>>
                .Where<
                    Where<POLine.lineType.FromCurrent.IsEqual<POLineType.nonStock>
                        .And<Where<PMBudget.projectID.IsEqual<POLine.projectID.FromCurrent>
                        .And<Where<PMBudget.projectTaskID.IsEqual<POLine.taskID.FromCurrent>
                        .And<Where<PMBudget.costCodeID.IsEqual<POLine.costCodeID.FromCurrent>
                        .And<Where<PMBudget.curyRevisedAmount.IsGreater<Zero>
                        .And<Where<PMBudget.accountGroupID.IsNotNull>
                        >>>>>>>>>
                    .Or<Where<POLine.lineType.FromCurrent.IsNotEqual<POLineType.nonStock>
                        .Or<Where<POLine.projectID.FromCurrent.IsNull
                        .Or<Where<POLine.taskID.FromCurrent.IsNull
                        .Or<Where<POLine.costCodeID.FromCurrent.IsNull
                        >>>>>>>>>>
                .AggregateTo<GroupBy<Account.accountID>>
                .OrderBy<Account.accountCD.Asc>>),
        typeof(Account.accountCD),
        new Type[] { typeof(Account.accountCD), typeof(Account.description), typeof(Account.accountGroupID), typeof(PMBudget.curyRevisedAmount),
            typeof(PMBudget.projectID), typeof(PMBudget.projectTaskID), typeof(PMBudget.costCodeID) },
        DescriptionField = typeof(Account.description),
        Filterable = false
        )]
[PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
[PXUIField(DisplayName = "Account", Visibility = PXUIVisibility.Visible)]
protected void POLine_ExpenseAcctID_CacheAttached(PXCache cache) { }
Brian Stevens
  • 1,826
  • 1
  • 7
  • 16