Skip to main content
Solved

How to keep specific PMQuote fields editable in all statuses except 'Closed' in Acumatica 26R1?

  • October 15, 2026
  • 5 replies
  • 55 views
  • Translate All

Forum|alt.badge.img

Hi everyone,
I am working on Acumatica 26R1 and I need to make three specific fields (externalRef, subject, and ownerID) editable on the Project Quotes screen (PM304500 / PMQuoteMaint) across all document statuses, except when the quote status is 'Closed'.
I attempted to achieve this using a standard graph extension with the RowSelected event, but the fields remain grayed out/locked on the screen:

 

using PX.Data;
using PX.Objects.PM;

namespace PX.Objects.PM
{
    public class PMQuoteMaint_Extension : PXGraphExtension<PMQuoteMaint>
    {
        protected void _(Events.RowSelected<PMQuote> e)
        {
            PMQuote row = e.Row;
            if (row == null) return;

            // Goal: Allow editing only if the quote is NOT Closed
            if (row.Status != PMQuoteStatusAttribute.Closed)
            {
                Base.Quote.AllowUpdate = true;
                Base.Quote.Cache.AllowUpdate = true;
                
                PXUIFieldAttribute.SetEnabled<PMQuote.externalRef>(e.Cache, row, true);
                PXUIFieldAttribute.SetEnabled<PMQuote.subject>(e.Cache, row, true);
                PXUIFieldAttribute.SetEnabled<PMQuote.ownerID>(e.Cache, row, true);
            }
        }
    }
}

Even though the code executes, the fields stay disabled in statuses like Approved or Draft. It seems the native business logic or the new Workflow engine in 26R1 is overriding my RowSelected changes and locking the fields.

Question:
Since this is 26R1, what is the best practice to accomplish this? Should I override this via the Workflow API (customizing the workflow states to un-protect these fields), or do I need to inject my logic into a native graph extension like PMQuoteMaintExt?
Any code snippets or workflow configuration examples would be greatly appreciated.
Thanks in advance!

Best answer by Naveen Boga

​@SaulGomez61  I just built this customization for you and attached the customization package here. Please deploy it to your instance, test the functionality, and let me know if you have any questions or encounter any issues.

View original

5 replies

nickcerri32
Captain II
Forum|alt.badge.img+8

​@SaulGomez61 ​@Naveen Boga has done a customization very similar to this for the same screen for one of my clients.  I’m sure he can provide some insight.  

Translate

JKurtz29
Varsity III
Forum|alt.badge.img+1
  • Varsity III
  • October 15, 2026

I used to do that in some simple event handlers too, but with the Workflow engine, seems that no longer works (or I too am missing a step).  How I achieved this was with a Workflow Extension.

In the example below, I was doing this for a custom field, UsrConfirmed, but you should be able to swap in your own field(s).

Maybe there’s an easier (and shorter) way?

 

public class POOrderEntry_Workflow_Extension : PXGraphExtension<PX.Objects.PO.POOrderEntry_Workflow, POOrderEntry>
{
public static bool IsActive() => true;

public override void Configure(PXScreenConfiguration config) =>
Configure(config.GetScreenConfigurationContext<POOrderEntry, POOrder>());

protected virtual void Configure(WorkflowContext<POOrderEntry, POOrder> context)
{
context.UpdateScreenConfigurationFor(screen =>
{
return screen
.WithFlows(flows =>
{
flows.Update<POOrderType.regularOrder>(flow =>
{
return flow
.WithFlowStates(states =>
{
states.Update<POOrderStatus.open>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingApproval>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingEmail>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingPrint>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.printed>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
});
});
flows.Update<POOrderType.blanket>(flow =>
{
return flow
.WithFlowStates(states =>
{
states.Update<POOrderStatus.open>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingApproval>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingEmail>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingPrint>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.printed>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
});
});
flows.Update<POOrderType.dropShip>(flow =>
{
return flow
.WithFlowStates(states =>
{
states.Update<POOrderStatus.open>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingApproval>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingEmail>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingPrint>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.printed>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
});
});
flows.Update<POOrderType.standardBlanket>(flow =>
{
return flow
.WithFlowStates(states =>
{
states.Update<POOrderStatus.open>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingApproval>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingEmail>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.pendingPrint>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
states.Update<POOrderStatus.printed>(state =>
{
return state
.WithFieldStates(fields =>
{
fields.RemoveField<POOrderExtAIGA.usrConfirmed>();
fields.AddField<POOrderExtAIGA.usrConfirmed>();
});
});
});
});
});
});
}
}

 

Translate

Naveen Boga
Captain II
Forum|alt.badge.img+20
  • Captain II
  • Answer
  • October 15, 2026

​@SaulGomez61  I just built this customization for you and attached the customization package here. Please deploy it to your instance, test the functionality, and let me know if you have any questions or encounter any issues.

Translate

JKurtz29
Varsity III
Forum|alt.badge.img+1
  • Varsity III
  • October 15, 2026

​@SaulGomez61  I just built this customization for you and attached the customization package here. Please deploy it to your instance, test the functionality, and let me know if you have any questions or encounter any issues.


Does Acumatica now merge multiple customization projects that modify a screen’s Workflow via their UI editor?

Last time I checked, you could only have one project that modified a given’s screen’s Workflow, so I’ve avoided using their UI Workflow editor as some popular ISV solutions don’t play well in that space, and some of our customers like to do their own Workflow changes.  To work around that issue, I just do my Workflow changes in code.

Translate

Forum|alt.badge.img
  • Author
  • Freshman II
  • October 15, 2026

​@SaulGomez61  I just built this customization for you and attached the customization package here. Please deploy it to your instance, test the functionality, and let me know if you have any questions or encounter any issues.

 

Thank you so much! I truly appreciate you taking the time to build and share this customization package with me. 🌟
I will deploy it to my test instance right away, verify the functionality across the different quote statuses, and let you know how it goes. I'll keep you updated as soon as the testing is complete.
Thanks again for your amazing support!
Translate