Skip to main content
Question

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

  • October 15, 2026
  • 2 replies
  • 16 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!

2 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