1
votes

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.

3

3 Answers

1
votes

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
}

AP Quick Check with custom flag

enter image description here

0
votes

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.

0
votes

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