Solved

Enabling and persisting only specific fields for edit after custom action button clicked

  • 22 June 2022
  • 5 replies
  • 563 views

Apologies this is a long one.

Customizations added:

  • Custom field added via ARTranExt for field “SomeField” of type string
  • Custom field added via ARRegisterExt for field “SomeFieldChanged” of type boolean
  • Custom action “EnableSomeField” added on the Action menu

What I’m trying to achieve:

  • When a user opens an existing invoice, ARTranExt.SomeField must not be editable
  • When the user clicks the EnableSomeField action, only SomeField must become editable.  I set a property calleld “editMode” to true
  • When the user selects an ARTran row, in Event.RowSelected<ARTran>, I check if editMode is true, and if yes, enable ARTranExt.SomeField
  • In Events.RowUpdated<ARTran>, I check if currentRow.SomeField == oldRow.SomeField, and if not, I set ARRegisterExt.SomeFieldChanged to true

The code:

public class ARInvoiceEntry_Extension : PXGraphExtension<ARInvoiceEntry>
    {
        private bool editMode = false;

        public override void Initialize()
        {
            base.Initialize();
            base.Base.ActionsMenuItem.AddMenuAction(this.ChangeIntegrationFields);
        }

        #region Actions

        public PXAction<ARInvoice> ChangeIntegrationFields;

        [PXButton(CommitChanges = true)]
        [PXUIField(
            DisplayName = "Change Integration Fields",
            Enabled = false,
            Visible = true,
            MapEnableRights = PXCacheRights.Update,
            MapViewRights = PXCacheRights.Update)]
        protected virtual void changeIntegrationFields()
        {
            this.editMode = true;
        }

        #endregion

        #region Event Handlers

        protected virtual void _(Events.RowSelected<ARInvoice> e)
        {
            ARInvoice invoice = e.Row;
            if (invoice == null) return;

            this.ChangeIntegrationFields.SetEnabled(true);

            e.Cache.AllowUpdate = true;
            base.Base.Transactions.Cache.AllowUpdate = true;
        }

        protected virtual void _(Events.RowSelected<ARTran> e)
        {
            ARTran artran = e.Row;
            if (artran == null) return;
            if (this.editMode) this.EnableFields(e.Cache, artran, true);
        }

        private void EnableFields(PXCache cache, ARTran row, bool enableFields)
        {
            //  Set all fields to readonly and disabled
            PXUIFieldAttribute.SetReadOnly(cache, row, true);
            PXUIFieldAttribute.SetEnabled(cache, row, false);

            //  Set specific fields to editable
            PXUIFieldAttribute.SetReadOnly<ARTranExt.someField>(cache, row, !enableFields);
            PXUIFieldAttribute.SetEnabled<ARTranExt.someField>(cache, row, enableFields);
        }

        protected virtual void _(Events.RowUpdated<ARTran> e)
        {
            var artran = (ARTran)e.Row;
            var oldartran = (ARTran)e.OldRow;
            if (artran == null || oldartran == null) return;

            ARTranExt artranext = artran.GetExtension<ARTranExt>();
            ARTranExt oldartranext = oldartran.GetExtension<ARTranExt>();

            if (IntegrationFieldsChanged(artranext, oldartranext))
            {
                var currentInvoice = base.Base.CurrentDocument.SelectSingle();

                base.Base.Caches[typeof(ARRegister)]
                    .SetValue<ARRegisterOIFExt.someFieldChanged>(
                        currentInvoice, true);
            }
        }

        private bool IntegrationFieldsChanged(ARTranExt oldRow, ARTranExt newRow)
        {
            if (oldRow.SomeField != newRow.SomeField) return true;
            return false;
        }

        #endregion
    }

Problem I’m having:

  • When the user opens the document SomeField is already editable, I believe this is because of the .AllowUpdate properties I’m settings to true in Event.RowSelected<ARInvoice>, which makes sense according to the summary description on the properties.
  • Problem is when I add logic for that, i.e. setting the .AllowUpdate’s to true only if EditMode is true, then it doesn’t seem to take affect.  When changing SomeField and saving the data isn’t persisted to the database and the UI reverts back to the previous values.  Is there a reason why it would take affect after the page has already rendered and the user then clicks the button which would execute that part of the logic?
  • Also by setting the .AllowUpdate properties to true, if I understand correctly I’m setting everything in the cache to editable, then in EnableFields() I’m first disabling all the UI fields again and then only enabling the one’s I want to be updated, it seems a bit convoluted.  Is there a better approach for this can only make the specific fields in the cache updateable and not touch the rest of them?

I minimized the amount of custom fields to try and keep it shorter, but the idea is to implement this exact same customization on ARInvoiceEntry, APInvoiceEntry and JournalEntry.

I did the dev training where that whole Phoneshop is built, but I searched through that solution and I can’t find that .Cache.AllowInsert/Update/Delete, etc. so unless I completely missed it I don’t think it was touched on, so I’m unsure if this is even the correct approach.  I’m rambling now sorry.

icon

Best answer by Leonardo Justiniano 22 June 2022, 17:12

View original

5 replies

Userlevel 6
Badge +4

Hi @rualdventer64 

I think you have to define those rules at Workflow level
 

 

Userlevel 7
Badge

Hi @Leonardo Justiniano - were you able to find a solution for your issue? Thank you!

Userlevel 6
Badge +4

Hi @Leonardo Justiniano - were you able to find a solution for your issue? Thank you!

Hi @Chris Hackett, Do you mean this topic or the one I posted a while ago?

About this one, you have to setup the workflow conditions to enable/disable fields on the current state where the custom action button is enabled. Also on RowSelected you have to manage what is enabled/disabled due the lack of functional link with the workflow. Finally you can assign values on the transition to another state or simple manage the assignment on a custom c#function invoked during clicking.

 

Other than that, about my topic, looks like an Acumatica bug. I moved away from the need to have it that way but still I believe is affecting another customization I have.

Userlevel 7
Badge

Hi @Leonardo Justiniano  - Thank you. I mistakenly asked you instead of OP😐

Hi @rualdventer64 - were you able to find a solution for your issue? Thank you!

Userlevel 7
Badge +5

HI @rualdventer64 - did you make this process work?  I have a similar request to have a button used to enable the field for editing (so I can make a copy of the original field value first). Just wondering if you navigated through this.

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved