Business Account(BAccount) Fielddefaulting not working - acumatica

I'm having an issue with this particular field defaulting method working. I've done many in the past with no issues. For some reason it's not assigning the ClassID on the Business Accounts page. I've gone through the debugger and stepped through cus.CustomerClassID which contained the correct value; additionally e.NewValue was assigned correctly in the debugger. But when the page actually opens the field remains blank. Is there a special case with field defaulting for BAccountMaint due to the generic inquiry?
protected void BAccount_ClassID_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e, PXFieldDefaulting InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
BAccount row = (BAccount)e.Row;
AR.Customer cus = PXSelect<AR.Customer, Where<AR.Customer.acctCD, Equal<Required<AR.Customer.acctCD>>>>.Select(Base, row.AcctCD);
if (row.AcctCD != null)
{
e.NewValue = cus.CustomerClassID;
e.Cancel = true;
}
}

Achieved a correct result by using rowselecting event instead of field defaulting.

Related

BQL expression in FieldDefaulting for Current User

I'm trying to set the default value of a custom field to the defContactID of the currently logged in user. I cannot get the BQL correct, any advise?
namespace PX.Objects.PJ.DailyFieldReports.PJ.Graphs
{
public class DailyFieldReportEntry_Extension : PXGraphExtension<DailyFieldReportEntry>
{
protected void DailyFieldReport_UsrOwner_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e, PXFieldDefaulting InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = e.Row as DailyFieldReport;
//BQL Statement to pull the EPEmployee record for the currently logged in employee
e.NewValue = EPEmployee.defContactID;
}
}
}
To get the logged in user details you can use the AccessInfo object which is in every graph. Accessinfo.UserContactID will retrieve the logged in user contact ID.
you can also use this by specifying it in the PXDefault attribute, without having the need to use the field event. In this case:
[PXDefault(typeof(AccessInfo.userContactID))

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."

I need to conditionally set a field to be required

I'm customizing the Sales Order screen as follows:
I've added a custom boolean field added to the Order Types screen called 'Require Customer Order Number'.
I've added code to the BLC of the Sales Order screen where I want to conditionally make the CustomerOrderNumber field required, based on whether the 'Require Customer Order Number' field is checked or not.
I'm using the SOOrder_RowSelected event as follows:
protected virtual void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
var soorder = (SOOrder)e.Row;
if (soorder == null) return;
string ordtype = soorder.OrderType;
var soot = (SOOrderType)PXSelect<SOOrderType,
Where<SOOrderType.orderType, Equal<Required<SOOrderType.orderType>>>>.Select(Base, ordtype);
if (soot != null)
{
var sootext = PXCache<SOOrderType>.GetExtension<SOOrderTypeExt>(soot);
if (sootext != null)
{
PXUIFieldAttribute.SetRequired<SOOrder.customerOrderNbr>(sender, sootext.UsrRequireCustOrdNbr == null ? false : (bool)sootext.UsrRequireCustOrdNbr);
}
}
}
This DOES put an asterisk on the CustomerOrderNumber field - but it doesn't spawn an error upon save if that field is empty.
Another issue is my PXSelect to get the record out of SOOrderType ALWAYS returns a null for the check box user field, even if it has a 'True' value in the database (which is why I put the ternary operator on the call). Even if I hard-code a 'true' value in the PXUIFieldAttribute.SetRequired call, it still doesn't spawn the error to prevent a save. The asterisk is there, but it doesn't work.
If I use a Cache_Attached event to add [PXDefault] it works perfectly - but this doesn't help me - I need it conditionally set.
Any ideas?
Required is used only for displaying the asterisk. PXDefault attribute is the one that makes the field mandatory based on PersistingCheck property value.
The issue is that PXUIFieldAttributes like PersistingCheck can only be set once at the time of graph creation. You can set it dynamically in the constructor/Initialize method but if you change the property after that it has no effects.
When I need a field to be mandatory based on a dynamic condition I remove the PXDefault attribute and validate the field manually in event handlers like RowPersisting:
public void PMTimeActivity_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
{
PMTimeActivity timeActivity = e.Row as PMTimeActivity;
if (timeActivity != null && PMTimeActivity.timeSpent == null)
{
PXUIFieldAttribute.SetError<PMTimeActivity.timeSpent>(sender, timeActivity, "'Time Spent' cannot be empty."));
}
}

Acumatica - Set checkbox to true based on a different field

I know that this is basic stuff and conditions, but I have an issue with a line that already exists in a service order. So we have Service Orders that will be imported into Acumatica and will already have a line. When in the Acumatica system someone will go to the Service Order screen (SD300100) and make the changes they wish after the import. In this case, they will change the Warranty Status, a custom field that we made, and it will change some values in the details and header. I have everything working, except for the first line that is brought in from the import on the detail line. So this order will come in with a line already inserted into the Labor tab. My issue is when we change the Warranty Status to warranty it should check another custom field's box called Warranty down in the detail line. I have this working for any newly inserted line but I can't get it with the already existing line. I have tried RowUpdated, RowUpdating, RowInserted, RowInserting on both the Header and Labor line data views. As well as the FieldUpdated, FieldUpdating and Selecting, on the header warranty selector and the Warranty checkbox in the details under the labor tab.
Here is my code:
public PXSelect<FSSODet, Where<FSSODet.sOID, Equal<Current<FSSODet.sOID>>>> FSSODets;
protected void FSServiceOrder_Usrwarrstat_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
var row = (FSServiceOrder)e.Row;
if (row == null) return;
FSSODet line = FSSODets.Current;
if (line == null) return;
if (line != null){
FSServiceOrderExt rowExt = PXCache<FSServiceOrder>.GetExtension<FSServiceOrderExt>(row);
if(rowExt == null)
return;
if (rowExt.Usrwarrstat == null)
return;
if (rowExt.Usrwarrstat == "W"){
cache.SetValueExt<FSSODetExt.usrwarrantydetail>(line, true);
}
}
}
This was the last way I tried before going to here. If anyone has a different way, I can provide code for any of the methods metioned above, RowUpdated, RowUpdating, etc. Commit Changes is set to true on both fields.
In short, when the Usrwarrstat field is set to "W" in the Service Order header, I want the Usrwarrantydetail in the Labor Tab/Details to be set to true.
Update 1: So I used the 1st answer suggestion below and it did change the checkbox to checked, but it happens no matter what the status is. I only need it to be check if it is set to "W" or "P", the only the other option is "N" so I added a check to if it is set to "N" then it would be false. However, it is still saving it as true.
Here is the updated code:
public PXSelect<FSSODetService, Where<FSSODetService.sOID, Equal<Current<FSSODetService.sOID>>>> FSSODets;
protected void FSServiceOrder_Usrwarrstat_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
var row = (FSServiceOrder)e.Row;
if (row == null) return;
FSSODetService line = FSSODets.Current;
if (line == null) return;
if (line != null){
FSServiceOrderExt rowExt = PXCache<FSServiceOrder>.GetExtension<FSServiceOrderExt>(row);
if(rowExt == null)
return;
if (rowExt.Usrwarrstat == null)
return;
if (rowExt.Usrwarrstat == "W" || rowExt.Usrwarrstat == "P"){
FSSODets.Cache.SetValueExt<FSSODetExt.usrwarrantydetail>(line, true);
}
if (rowExt.Usrwarrstat == "N"){
FSSODets.Cache.SetValueExt<FSSODetExt.usrwarrantydetail>(line, false);
}
}
}
}
Overall the logic looks good. There's a Cache object mismatch that could prevent SetValueExt from working:
// When this event handler is called by the framework
// PXCache cache object will be of type FSServiceOrder
// because the event is bound on FSServiceOrder DAC
protected void FSServiceOrder_Usrwarrstat_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
When you call SetValueExt you should use a cache object of matching type:
// cache reference is of type FSServiceOrder but we want to modify FSSODetExt DAC field
cache.SetValueExt<FSSODetExt.usrwarrantydetail>(line, true);
// With extensions you have to use the base DAC cache
// you already declared a DataView on FSSODet so you can use it's cache reference
FSSODets.Cache.SetValueExt<FSSODetExt.usrwarrantydetail>(line, true);
Besides the DAC cache reference mismatch there's a possibility that you do successfully modify the field value but another event handler/mechanism modifies it again after you.
To check that you can declare a event handler on the target field, put a breakpoint in it and debug it using visual studio debug stack trace window. The stack trace will show which methods lead to the field modification.
protected void FSSODet_Usrwarrantydetail_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
Also make sure Usrwarrstat field has the CommitChanges = True property set in the ASPX file or else modifying the field on screen won't execute the associated FieldUpdated event handler.

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

Resources