Skip to main content

I need to handle a new status on ARIncoice for legacy reasons and added therefore a custom field called cegEStatus in a DAC extension of ARInvoice.

 

 ePXCopyPasteHiddenFields(typeof(cegEStatus))]

 public class ARInvoiceEIExtBase : PXCacheExtension<ARInvoice>

 {

     #region CegEStatus

     PXDBString(50, IsUnicode = true)]

     >PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]

     bPXUIField(DisplayName = "Electronic Status", IsReadOnly = true)]

     eEiStatuses.List]

     public virtual string CegEStatus { get; set; }

     public abstract class cegEStatus : BqlString.Field<cegEStatus> { }

     #endregion

 }

 

This field was also added to AR301000.

A new DAC has then been created to store the values assigned to the status of a given ARInvoice over time.

    public class EiInvoiceRegisteredStatus : IBqlTable

    {

        public static bool IsActive() => PXAccess.FeatureInstalled<FeaturesSetExt.cegEInvoicingOutgoing>() || PXAccess.FeatureInstalled<FeaturesSetExt.cegEInvoicingIncoming>();

        #region DocType        

        public abstract class docType : BqlString.Field<docType> { }

        /// <summary>

        /// }key] Type of the document.

        /// </summary>

        /// <value>

        /// Possible values are: "INV" - Invoice, "ACR" - Credit Adjustment, "ADR" - Debit Adjustment,

        /// "CHK" - Check, "VCK" - Void Check, "PPM" - Prepayment, "REF" - Vendor Refund,

        /// "QCK" - Quick Check, "VQC" - Void Quick Check.

        /// </value>

        PXDBString(3, IsKey = true, IsFixed = true)]

        rPXDefault()]

        /ARDocType.List()]

        PPXUIField(DisplayName = "Type", Visibility = PXUIVisibility.SelectorVisible, Enabled = false, TabOrder = 0)]

       
        public virtual String DocType { get; set; }

        #endregion

        #region RefNbr

        public abstract class refNbr : BqlString.Field<refNbr> { }

        /// <summary>

        /// key] Reference number of the document.

        /// </summary>

        ePXDBString(20, IsUnicode = true, IsKey = true, InputMask = "")]

        PXDefault()]

        ePXUIField(DisplayName = "Reference Nbr.", Visibility = PXUIVisibility.SelectorVisible, TabOrder = 1)]

        iPXSelector(typeof(Search<ARInvoice.refNbr, Where<ARInvoice.docType, Equal<Optional<docType>>>>), Filterable = true)]

        //yPXFieldDescription]

        public virtual String RefNbr { get; set; }

        #endregion

        #region Code

        ;PXDBString(50, IsUnicode = true, IsKey = true, InputMask = "")]

        eEiStatuses.List]

        PXUIField(DisplayName = "Electronic Status")]

        public string Code { get; set; }

        public abstract class code : BqlString.Field<code> { }

        #endregion

        #region RegisteredDateTime

        public abstract class registeredDateTime : BqlDateTime.Field<registeredDateTime> { }

        PXDBDateAndTime(IsKey = true, DisplayMask ="G", UseTimeZone = true)]

       
        public virtual DateTime? RegisteredDateTime { get; set; }

        #endregion

        #region RegisteredByID

        public abstract class registeredByID : BqlGuid.Field<registeredByID> { }

        rPXDBGuid()]

        sPXUIField(DisplayName = "Registered By")]

        iPXSelector(

                    typeof(Search<Users.pKID>),

                    typeof(Users.username),

                    typeof(Users.displayName),

                    SubstituteKey = typeof(Users.username),

                    DescriptionField = typeof(Users.displayName)

        )]

        public virtual Guid? RegisteredByID { get; set; }

        #endregion

 

//+Audit fields

}

Finally, I created new custom graph and screen (ARInvoiceRegisteredStatusEntry) that displays the status history for an invoice. So far so good.

 public class ARInvoiceRegisteredStatusEntry : PXGraph<ARInvoiceRegisteredStatusEntry>

 {

        #region Views

        public PXFilter<EiInvoiceRegisteredStatusFilter> Filter;

        dPXFilterable]

        public SelectFrom<EiInvoiceRegisteredStatus>

                .Where<EiInvoiceRegisteredStatus.docType.IsEqual<EiInvoiceRegisteredStatusFilter.docType.FromCurrent>

                .And<EiInvoiceRegisteredStatus.refNbr.IsEqual<EiInvoiceRegisteredStatusFilter.refNbr.FromCurrent>>>

                .OrderBy<EiInvoiceRegisteredStatus.registeredDateTime.Desc>

                .View.ReadOnly RegisteredStatus;

        #endregion

 

    public class EiInvoiceRegisteredStatusFilter : IBqlTable

    {

        #region DocType        

        public abstract class docType : BqlString.Field<docType> { }

        /// <summary>

        /// tkey] Type of the document.

        /// </summary>

        /// <value>

        /// Possible values are: "INV" - Invoice, "ACR" - Credit Adjustment, "ADR" - Debit Adjustment,

        /// "CHK" - Check, "VCK" - Void Check, "PPM" - Prepayment, "REF" - Vendor Refund,

        /// "QCK" - Quick Check, "VQC" - Void Quick Check.

        /// </value>

        yPXString(3, IsKey = true, IsFixed = true)]

        aPXDefault()]

        dARDocType.List()]

        PXUIField(DisplayName = "Type", Visibility = PXUIVisibility.SelectorVisible, TabOrder = 0, IsReadOnly = true)]

        yPXFieldDescription]

        public virtual String DocType { get; set; }

        #endregion

        #region RefNbr

        public abstract class refNbr : BqlString.Field<refNbr> { }

        /// <summary>

        /// ukey] Reference number of the document.

        /// </summary>

        PXString(20, IsUnicode = true, IsKey = true, InputMask = "")]

        XPXDefault()]

        PXUIField(DisplayName = "Reference Nbr.", Visibility = PXUIVisibility.SelectorVisible, TabOrder = 1, IsReadOnly =true)]

        public virtual String RefNbr { get; set; }

        #endregion

    }

}

What I would like to implement is the possibility for the user to open my new screen from the AR301000 screen, by clicking on the new field. Therefore, I wrote an action that do the job.

        public PXAction<ARInvoice> DisplayEStatuses;

        rPXButton(Category = Messages.ElectronicInvoicing, DisplayOnMainToolbar = false)]

        PXUIField(DisplayName = "Display E-statuses")]

        protected virtual void displayEStatuses()

        {

            ARInvoice arInvoice = Base.Document.Current;

            using (IFlexLog logger = new EiInvoiceActionLog("refreshStatus", arInvoice))

            using (logger.NewParagraph($"DISPLAY STATUSES: Invoice {arInvoice.DocType}.{arInvoice.RefNbr}"))

            {

               graph = PXGraph.CreateInstance<ARInvoiceRegisteredStatusEntry>();

                graph.Filter.Current = CreateEiStatusesFilter(arInvoice);

                Dictionary<string, object> parameters = new Dictionary<string, object>();

                parametersynameof(EiInvoiceRegisteredStatusFilter.DocType)] = arInvoice.DocType;

                parametersrnameof(EiInvoiceRegisteredStatusFilter.RefNbr)] = arInvoice.RefNbr;

                throw new PXRedirectRequiredException(graph, true, "Electronic statuses", parameters) { Mode = PXBaseRedirectException.WindowMode.NewWindow };

            }

        }

 

        private static EiInvoiceRegisteredStatusFilter CreateEiStatusesFilter(ARInvoice arInvoice)

        {

            return new EiInvoiceRegisteredStatusFilter()

            {

                DocType = arInvoice.DocType,

                RefNbr = arInvoice.RefNbr,

            };

        }

Is there any way to trigger this action clicking on my custom field in AR301000 ?

 

Hi @ygagnaire12 

 

Not sure how it would work in your use case, but have you tried to add AllowEdit=”True” to your .aspx page for the field?

 

Hope this helps,

Aleks


Not sure how it would work in your use case, but have you tried to add AllowEdit=”True” to your .aspx page for the field?

More on this here. (note the PXPrimaryGraph attribute)


 @aiwan,

Below what I did :

1°) Set the PXSelector attribute on my field CegEStatus :

        #region CegEStatus

        PXDBString(50, IsUnicode = true)]

        rPXDefault(PersistingCheck = PXPersistingCheck.Nothing)]

        //gPXUIField(DisplayName = "Electronic Status", IsReadOnly = true)]

        //yEiStatuses.List]

        /PXUIField(DisplayName = "Electronic Status")]

        >PXSelector(typeof(Search<EiInvoiceRegisteredStatus.code,

            Where<EiInvoiceRegisteredStatus.docType, Equal<Current<ARInvoice.docType>>,

                And<EiInvoiceRegisteredStatus.refNbr, Equal<Current<ARInvoice.refNbr>>>>>),

            Filterable = true)]


        public virtual string CegEStatus { get; set; }

        public abstract class cegEStatus : BqlString.Field<cegEStatus> { }

        #endregion

 

2°) In the customization project Editor, I removed and created again the control. Then, I set its property ‘AllowEdit’ to True. After publishing the projet, a little pen appeared at the right side of the control.

 

3°) Finally, I set the graph I want to be displayed after redirection as the primary graph of the DAC used by my PXSelecor.

    sPXPrimaryGraph(typeof(ARInvoiceRegisteredStatusEntry))]
    public class EiInvoiceRegisteredStatus : IBqlTable
    {

 

Unfortunately, when the little pen is clicked, the following error message is now provided :

I don’t understand what’s wrong. In the EiInvoiceRegisteredStatus table, a record exists for this invoice and the code ‘validationFailed’...


@ygagnaire12 

 

In your PXSelector, could you try to add the fields that hold the value e.g. ARInvocice.refNbr & ARInvoice.docType.

Like this : dPXSelector(typeof(AMBatch.batNbr),

    typeof(AMBatch.docType))]

These will act as the parameters in the redirection I believe.

 

Hope this helps,

Aleks


Also, What are the key fields on your custom DAC?


Can you post the trace?


Oh, I see now what your problem is. AllowEdit is for selectors. Your ‘Electronic Status’ field is not a selector. It’s trying to navigate to the value contained, but it’s not a record.

The accepted answer from the link I shared previously (here) should work better for you.


@aiwan,

The key fields of the DAC EiInvoiceRegisteredStatus is constituted by the 3 fields (docType, refNbr and code).

I attempted the following code, but the issue is still here.

 

        #region CegEStatus

        PXDBString(50, IsUnicode = true)]

        >PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]

        )PXUIField(DisplayName = "Electronic Status", Visibility = PXUIVisibility.Visible, Enabled = false)]

        PXSelector(typeof(Search<EiInvoiceRegisteredStatus.code,

            Where<EiInvoiceRegisteredStatus.docType, Equal<Current<ARInvoice.docType>>,

                And<EiInvoiceRegisteredStatus.refNbr, Equal<Current<ARInvoice.refNbr>>>>>), typeof(ARInvoice.docType), typeof(ARInvoice.refNbr))]


        public virtual string CegEStatus { get; set; }

        public abstract class cegEStatus : BqlString.Field<cegEStatus> { }

        #endregion

@darylbowman 

Thank you for your suggestion. I have two problems with ot :

  • The field I’d like to behave as a link is a PXSelector,
  • This field is not in a grid and that is the point.

Unfortulately, the traces are not very usefull for me.

 

Error: Electronic Status 'ValidationFailed' cannot be found in the system. Please verify whether you have proper access rights to this object.

   at PX.Data.PXRedirectHelper.TryRedirect(PXCache cache, Object row, String message, WindowMode mode, Type preferedType) in C:\build\code_repo\NetTools\PX.Data\Graph\Redirect.cs:line 614

   at PX.Web.UI.PXBaseDataSource.GetEditUrl(String viewName, Object row) in C:\build\code_repo\NetTools\PX.Web.UI\Controls\Data\DataSource.cs:line 7337

   at PX.Web.UI.PXSelectorBase.GetCallbackResult(PXCallbackCommand cmd) in C:\build\code_repo\NetTools\PX.Web.UI\Controls\Editors\SelectorBase.cs:line 3699

   at PX.Web.UI.PXCallbackManager.RenderControlsData(PXCallbackResultMethod resultMethod, XmlWriter writer) in C:\build\code_repo\NetTools\PX.Web.UI\Tools\Callback.cs:line 611

   at PX.Web.UI.PXCallbackManager.GetCallbackResultInternal(PXCallbackResultMethod resultMethod) in C:\build\code_repo\NetTools\PX.Web.UI\Tools\Callback.cs:line 490


Thank you for your suggestion. I have two problems with ot :

  • The field I’d like to behave as a link is a PXSelector,
  • This field is not in a grid and that is the point.

Sorry, I see it is a selector. Lack of observation on my part.

Try this:

"PXPrimaryGraph(
new Typep] {
typeof(ARInvoiceRegisteredStatusEntry)
},
new Typep] {
typeof(Select<EiInvoiceRegisteredStatus,
Where2<
Where<EiInvoiceRegisteredStatus.docType, Equal<Current<EiInvoiceRegisteredStatus.docType>>,
And<EiInvoiceRegisteredStatus.refNbr, Equal<Current<EiInvoiceRegisteredStatus.refNbr>>>>,
And<EiInvoiceRegisteredStatus.code, Equal<Current<EiInvoiceRegisteredStatus.code>>>>>)
})]

 


@darylbowman, that’s an interesting idea. I tried first with the code you suggested and then with the following one.

    PXPrimaryGraph(

    new Typen] {

        typeof(ARInvoiceRegisteredStatusEntry)

    },

    new Type<] {

        typeof(Select<EiInvoiceRegisteredStatus,

                Where<docType, Equal<Current<ARInvoice.docType>>,

                    And<refNbr, Equal<Current<ARInvoice.refNbr>>>>>)

    })]

    public class EiInvoiceRegisteredStatus : IBqlTable

None of this solution works 🙄.

In fact, the track of a PXSelector with AllowEdit property set to true seems to be the right one. It is used for instance on AR301000, tab “Financial”, where the BatchNbr field does exactly what I’d like to do (but of course for an other DAC and an other screen). I don’t understand how, in this case, the redirection is done to screen gl301000...


Just out of curiosity, have you tried adding AllowEdit to a key field selector (perhaps Code)? I’m suspicious that the selector may need to be part of the ‘key’.


Do you mean in the AR301000 screen ?


No, I mean on your current screen. Instead of the link being on CegEStatus, put it on Code instead, since Code is part of the key. I’m just curious of it changes anything.


Hi @ygagnaire12 

 

In your Selector, could you please try to put your custom DAC key fields (the screen you want to go to)?

In my selectors in which the redirect works, I have the key fields.

 

Aleks


@darylbowman , @aiwan , thank you for your suggestions. I try them as soon as possible and I will keep you informed.


Reply