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

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;
}
}

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 Count records in a related table and allow user to override

I have a custom field on the CRActivity table in which I need to store the number of records in a related table. I am trying to set the field to the value when screen CR306030 opens. The user needs to be able to override the calculated number so, I'm thinking that I need logic on the calculation to check if the custom field is > 0, in which case, don't populate the custom field and assume it's already been set.
Previously, I've tried to do this in the Field_Selecting events but, this is not working. I'm thinking I might be able to use a PXFormula attribute. Any suggestions?
I tried making a custom attribute which is close but, it won't save the values to the db. The save button enables, I can click it and it looks like it saves but, no dice. Some mundane detail, I'm sure.....
Here's my custom attribute:
public class CFCountIfZeroAttribute : PXIntAttribute
{
public override void FieldSelecting(PXCache cache, PXFieldSelectingEventArgs e)
{
if (e.Row == null)
return;
CRActivity activity = (CRActivity)e.Row;
CRActivityExt activityExt = activity.GetExtension<CRActivityExt>();
if (activityExt.usrCustomField <= 0)
{
int aggregateValue = BQLToFind();
e.ReturnValue = aggregateValue;
cache.SetValue<CRActivityExt.usrCustomField>(e.Row, aggregateValue);
cache.IsDirty = true;
}
}
}
Thanks!
I don't think I've ever done a count within a PXFormula, but what if you created a custom attribute?
[DBUIInt()]
[EditableCount()]
public virtual int? CountField
public class EditableCountAttribute
{
public override void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
if (e.Row != null)
{
//if CountField is 0, lookup the count from another table
}
}
}
This is just off the top of my head. You could pass the field you're counting into the attribute if you wanted to do this elsewhere.

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);
}
}
}

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

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);
}

Sales Order SOLines Conditionally Disabled tranDesc being overridden

I have custom code on the Sales Order form that prevents editing SOLine descriptions unless it's a specific SOLine Code. I see that my custom code is being reached, but it seems that something else is overriding my logic, enabling editing on the field after I disable it. I was wondering if there are pre-defined automations that might be doing this for the Sales Order screen, or if there is some other place I should be looking to prevent this behavior.
//I had debug code that validated that RowSelected and SetEnabled were begin called
public class SOOrderEntry_Extension:PXGraphExtension
{
#region Event Handlers
protected void SOLine_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
if(InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (SOLine)e.Row;
if(row != null && row.InventoryID.HasValue) {
//Only allow editing of parts description if the partno is 'NOTE'
InventoryItem inventoryItem = PXSelect<InventoryItem, Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>.Select(this.Base, row.InventoryID);
if(inventoryItem.InventoryCD == "NOTE") {
PXUIFieldAttribute.SetEnabled<SOLine.tranDesc>(cache, row, true);
} else {
PXUIFieldAttribute.SetEnabled<SOLine.tranDesc>(cache, row, false);
}
}
}
}
Unfortunately, your RowSelected handler will make no effect on the Line Description column because of how automation steps are configured for the Sales Orders screen:
In order to keep Line Description open for editing, you should change a number of Automation Steps disabling the entire Document Details grid on Sales Orders and subscribe to RowSelected handler for the SOOrder DAC to allow editing on the cache level for the SOOrder and SOLine DACs. Below are the changes required to enable Line Description for completed sales orders (if necessary, similar changes should be made to other Automation steps defined for the Sales Orders screen):
Subscribe to SOOrder_RowSelected handler to allow editing on the cache level for the SOOrder and SOLine DACs:
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
public void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SOOrder order = e.Row as SOOrder;
if (order != null && order.Status == SOOrderStatus.Completed)
{
sender.AllowUpdate = true;
Base.Transactions.Cache.AllowUpdate = true;
}
}
}
Modify Sales Orders' SO Completed automation step to open Line Description for editing. In addition to enabled Line Description, it's necessary to enable at least one of the SOOrder fields, otherwise the Save button will never become enabled for completed sales orders:

Resources