Disabling fields on Bills and Adjustments doesn't seem to work - acumatica

I have a custom dropdown field on Bills and Adjustments which I want to determine when to disable specific fields on the screen. I'm using the following logic, which doesn't seem to work (the commented lines didn't work either). I've set the commitchanges to true on the user field - and I've stepped through the code to make sure it's getting hit:
protected virtual void APInvoice_UsrPOStatus_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
{
var apr = (APRegister)e.Row;
if (apr == null) return;
var aprext = PXCache<APRegister>.GetExtension<APRegisterExt>(apr);
if (aprext == null) return;
if (aprext.UsrPOstatus != "Open")
{
PXUIFieldAttribute.SetEnabled<APRegister.docType>(sender, apr, false);
PXUIFieldAttribute.SetEnabled<APRegister.refNbr>(sender, apr, false);
//PXUIFieldAttribute.SetEnabled<APInvoice.docType>(Base.Document.Cache, null, false); //(OpenSourceDataDetail.Cache, null, true);
//PXUIFieldAttribute.SetEnabled<APInvoice.refNbr>(Base.Document.Cache, null, false);
}
}
I get no errors, but nothing happens. Is it not possible to disable these fields?
I'm also not sure whether to use APInvoice or APRegister for these statements.

When a field enabled state and visibility can't be changed it's usually because a later event overrides your changes.
The base graph of the graph extension you're working on (APInvoiceEntry) calls SetEnabled on these fields in the APInvoice_RowSelected event.
To override these calls you should override the same event in your extension, then your event handler will be the last one executed.
protected virtual void APInvoice_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
  APInvoice apInvoice = e.Row as APInvoice;
  if (apInvoice == null)
  {
    return;
  }
  PXUIFieldAttribute.SetEnabled<APInvoice.docType>(cache, apInvoice, false);
  PXUIFieldAttribute.SetEnabled<APInvoice.refNbr>(cache, apInvoice, false);
}

Related

How can I force a field to be enabled on the Bills and Adjustments screen's Document Details grid

I'm currently trying to force a field to be enabled on the RowSelected event, which I've gotten to work before, but now it doesn't.
When a Bill is in a status where the grid is disabled, I have two added user fields that I want to remain enabled.
The code I'm using is this, which I thought would work:
protected virtual void APTran_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
var aptran = e.Row as APTran;
if (aptran != null)
{
PXUIFieldAttribute.SetEnabled<APTranExt.usrGrantID>(cache, aptran, true);
PXUIFieldAttribute.SetEnabled<APTranExt.usrReimbursementPeriod>(cache, aptran, true);
}
}
But it doesn't work.
Any ideas?
Thanks...
Most probably what is happening is that the view currently has the allow update set to false this overrides the enabled state which you are setting. One way to bypass this is that for that status you set the allow update to true. Then force the whole grid to be disabled apart from the two fields which you want. Example Below:
protect virtual void APInvoice_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
if (e.Row is APinvoice row)
{
if (status)
{
Transactions.Cache.AllowUpdate = true
PXUIFieldAttribute.SetEnabled(Transactions.Cache, null, false);
PXUIFieldAttribute.SetEnabled<APTranExt.usrGrantID>(Transactions.Cache, null, true);
PXUIFieldAttribute.SetEnabled<APTranExt.usrReimbursementPeriod>(Transactions.Cache, null, true);
}
}
}

How to attach an event to the Residential Delivery checkbox on the Customers screen in 2020R2?

I need to change the default value of the Residential Delivery checkbox on the Customers AR.30.30.00 screen (Shipping tab) to checked by default. See screenshot:
In 2017R2, this event handler worked without error:
public class CustomerMaint_Extension : PXGraphExtension<CustomerMaint>
{
protected virtual void LocationExtAddress_CResedential_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
var row = (LocationExtAddress)e.Row;
if (row != null)
{
e.NewValue = true; // checked by default
}
}
}
I'm updating this customization for 2020R2. It appears that LocationExtAddress has been replaced with DefLocationExt in newer versions. (Resedential is mis-spelled intentionally in the code... that's how Acumatica defined it.) I've tried changing the event handler to:
protected virtual void DefLocationExt_CResedential_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
var row = (DefLocationExt)e.Row;
if (row != null)
{
e.NewValue = true; // checked by default
}
}
But this results in a run-time error:
Failed to subscribe the event PX.Objects.AR.CustomerMaint_Extension::DefLocationExt_CResedential_FieldDefaulting in the graph PX.Objects.AR.CustomerMaint. The method signature looks like an event handler, but the cache DefLocationExt has not been found in the list of auto-initialized caches. Remove unused event handlers from the code.
How can I attach an event to this field in 2020R2?
Try a generic event handler and see if you get the same result.
It might look something like this.
protected virtual void _(Events.FieldDefaulting<PX.Objects.CR.Standalone.Location.cResedential> e)
{
var row = (PX.Objects.CR.Standalone.Location)e.Row;
if (row != null)
{
e.NewValue = true; // checked by default
}
}

In the Bills and Adjustment screen I need to set Project and Task to be conditionally enabled

I have a customization to the Bills and Adjustments screen where I need the Project and Task in the grid section to be enabled beyond what is specified in the source code.
In order to do this, I've used an overridden RowSelected event, but this doesn't seem to work. The additional context here is that the Approval Map settings come into play.
Here is the code to override the RowSelected event that I thought would work but doesn't:
protected void APInvoice_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var apinv = (APInvoice)e.Row;
if (apinv != null)
{
APRegister apreg = PXSelect<APRegister, Where<APRegister.refNbr, Equal<Required<APRegister.refNbr>>>>.Select(Base, apinv.RefNbr);
if (apreg.Released != true)
{
PXUIFieldAttribute.SetEnabled<APTran.projectID>(Base.Transactions.Cache, null, true);
PXUIFieldAttribute.SetEnabled<APTran.taskID>(Base.Transactions.Cache, null, true);
}
}
}
Can someone explain why this doesn't enable these fields? Is there another way to do this (short of completely replicating the RowSelected event in the source code)?
Thanks much...
Not sure if the cache you're referring to is in the same 'state'(for a lack of a better word). try swaping out Base.tran.... with the PXCache that you are receiving "cache"
protected void APInvoice_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
try
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
PXUIFieldAttribute.SetEnabled<APTran.projectID>(cache, null, true);
PXUIFieldAttribute.SetEnabled<APTran.taskID>(cache, null, true);
}
catch(System.Exception) {}
}
Per Acumatica support:
"I've tested this on 20R102 and 20R109.
It only worked on the later which means that this is most likely a bug.
I will check this with engineering but I am aware of some APInvoice bugs that were solved starting 20R104."

Enable SOLine field after Order Completed

I need to enable the Salesperson ID and Commissionable fields of Sales Order Lines for Sales Orders in the Completed state.
I referenced the question here about enabling fields in the SOOrder header: How to enable CustomerOrderNbr field in Sales Order screen?
I added the two fields to the Automation Steps for the SO Complete step
And added customization code:
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
public void SOOrderLine_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SOOrderLine line = e.Row as SOOrderLine;
if (line == null) return;
PXUIFieldAttribute.SetEnabled<SOOrderLine.salesPersonID>(sender, line, true);
PXUIFieldAttribute.SetEnabled<SOOrderLine.commissionable>(sender, line, true);
}
}
However, the fields are still disabled. Is there something I'm missing?
I have a similar requirement with one of my clients. You're on the right track with automation steps, but you need something else to enable editing. Here are the two event handlers we use:
protected void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
// Make the promised on ship date field editable even after the order has been completed.
// This code is not enough to make the feature work - automation steps need to be modified for SO Completed and SO Invoiced to ensure the
// caches are not disabled.
sender.AllowUpdate = true;
Base.Transactions.Cache.AllowUpdate = true;
}
protected void SOLine_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
if (Base.Document.Current != null)
{
//Automation steps were modified to keep the transactions grid enabled for the completed status; we are manually disabling it here but leaving the promised on ship date field editable.
if(Base.Document.Current.Status == SOOrderStatus.Completed)
PXUIFieldAttribute.SetEnabled(sender, e.Row, false);
PXUIFieldAttribute.SetEnabled<SOLineExt.usrPromisedShipOnDate>(sender, e.Row, true);
PXUIFieldAttribute.SetEnabled<SOLineExt.usrLateReasonCode>(sender, e.Row, true);
}
}
To finish out the solution to this, in this case I found it was not necessary to Enable the full Sales Order Line via Automation Steps and then disable it via SOLine_RowSelect. It was, however, necessary to add the Sales Order > Order Nbr field to the automation steps (to make the document Save available after changing the Sales Order line). And strangely it was also necessary for us to give this Customization Project a higher Level than the others implementing it after other customizations that may have made changes to the same screen or objects.
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
protected void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
sender.AllowUpdate = true;
Base.Transactions.Cache.AllowUpdate = true;
}
protected void SOLine_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
if (Base.Document.Current != null)
{
PXUIFieldAttribute.SetEnabled<SOLine.salesPersonID>(sender, e.Row, true);
PXUIFieldAttribute.SetEnabled<SOLine.commissionable>(sender, e.Row, true);
}
}
}

How to enable a custom field on GL301000 when the Batch is Posted?

I need to add a custom checkbox named "Cleared" to the detail lines in Acumatica's Journal Transactions page (GL301000). Users must be able to check this box after the batch is Posted. When the user checks the box another custom field titled "Date Cleared" should record the date and time. Both values must be saved in the database. Acumatica disables the detail lines after the batch is posted. How can I do this?
I see an answer to a similar question here. The JournalEntry BLC seems to disable the detail lines using the ReadOnlyStateController rather than the CommonTypeStateController in the GetStateController method, so I believe this solution needs to be different. Also, the Journal Transactions page does not seem to be driven by automation steps like this similar question.
You are correct the Journal Transaction page is not driven by automation steps.
If you want to enabled your custom Fields on the GLTran(lines) of this screen, you need to override both GLTran_RowSelected and Batch_RowSelected on your JournalEntry graph extension. Also, you can reuse the IsBatchReadonly function used on the GetStateController method.
On the Batch_RowSelected event handler you will:
-Check if batch is readOnly using the isBatchReadOnly function from the GetStateController method.
-Then, set allowUpdate to true on the caches.
-Set readonly false to all GLTran Fields
-Then set readonly true to all GLTran fields but your Custom Fields.
Then on the GLTran_RowSelected event handler you will setEnabled your Custom Fields.
See sample below:
public class JournalEntry_Extension : PXGraphExtension<JournalEntry>
{
protected void GLTran_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected del)
{
GLTran row = (GLTran)e.Row;
if (del != null)
del(cache, e);
if (row != null)
{
PXUIFieldAttribute.SetEnabled<GLTranExt.usrCustomField1>(cache, row, true);
PXUIFieldAttribute.SetEnabled<GLTranExt.usrCustomField2>(cache, row, true);
}
}
protected void Batch_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected del)
{
Batch row = (Batch)e.Row;
if (del != null)
del(cache, e);
if (row != null)
{
if (IsBatchReadonly(row))
{
//Set Cache Allow Update
cache.AllowUpdate = true;
Base.GLTranModuleBatNbr.Cache.AllowUpdate = true;
//First Set ReadOnly false to all fields
PXUIFieldAttribute.SetReadOnly(Base.GLTranModuleBatNbr.Cache, null, false);
//Then Set ReadOnly true to all fields but your custom ones
PXUIFieldAttribute.SetReadOnly<GLTran.accountID>(Base.GLTranModuleBatNbr.Cache, null, true);
PXUIFieldAttribute.SetReadOnly<GLTran.subID>(Base.GLTranModuleBatNbr.Cache, null, true);
.......
}
}
}
//Function used on the GetStateController method
private bool IsBatchReadonly(Batch batch)
{
return (batch.Module != GL.BatchModule.GL && Base.BatchModule.Cache.GetStatus(batch) == PXEntryStatus.Inserted)
|| batch.Voided == true || batch.Released == true;
}
}

Resources