How do I use the user set value of a DAC extension to enable/disable a UI field of the Base DAC? - acumatica

I added a bool field to APVendorPrice that needs to be enabled only when a SiteID is entered in the APVendorPriceMaint graph. Likewise, if it is set true, it needs to disable the SiteID field. By creating a graph extension for APVendorPriceMaint, I can tap into the APVendorPrice_RowSelected event to enable/disable my custom field easily. However, when I set my new field to Commit Changes = true, the user entry value of my DAC extension field is lost to me.
How do I get the user entered value on my DAC extension field?
protected virtual void APVendorPrice_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected baseEvent)
{
APVendorPrice row = (APVendorPrice)e.Row;
APVendorPriceExt vendorPriceExt = sender.GetExtension<APVendorPriceExt>(row);
baseEvent(sender, e);
PXUIFieldAttribute.SetEnabled<APVendorPrice.siteID>(sender, row, vendorPriceExt?.UsrMyField != true);
PXUIFieldAttribute.SetEnabled<APVendorPriceExt.UsrMyField>(sender, row, row?.SiteID != null);
}
The GetExtension always returns the saved value rather than seeing that the user toggled the value.
How do I see the user entered value for UsrMyField so that I can enable/disable access to SiteID?

Related

How can I save value of user-defined in the database without clicking the save button

I have created a user-defined field (Last Activity Date) on the Opportunities (CR304000) screen which is populated from the last Start Date of the activity on the Activities tab of the Opportunities screen (CR304000) on RowSelected as shown on screenshot one. When an activity is added for an opportunity, the user is not required to click the save button on the form of the opportunity, therefore the user-defined field I have added does not save the value to the database. I would like the value of the user-defined field to be saved to the database whenever an activity is added to the opportunity and the value of the user-defined field changes without having to click the save button on the opportunity form as I need to use it on a generic Inquiry.
Screenshot 1
Code Snippet:
protected void CROpportunity_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
var row = (PX.Objects.CR.CROpportunity)e.Row;
if (row == null)
{
return;
}
CRActivity cRActivity = PXSelect<CRActivity, Where<CRActivity.refNoteID, Equal<Required<PX.Objects.CR.CROpportunity.noteID>>>, OrderBy<Desc<CRActivity.startDate>>>.Select(Base, row.NoteID);
if (cRActivity == null)
{
return;
}
CROpportunityExt cROpportunityExt = row.GetExtension<CROpportunityExt>();
cROpportunityExt.UsrLastActivity = cRActivity.StartDate;
Base.Opportunity.SetValueExt<CROpportunityExt.usrLastActivity>(Base.Opportunity.Current, cROpportunityExt.UsrLastActivity);
Base.Save.SetPressed(true);
}
In my opinion, push the value to the opportunity instead from the CRActivityMaint graph in the CRActivity RowPersisted event instead of pulling it from the activity in CROpportunity RowSelected. It is not good practice to change values of DAC rows in the RowSelected event.
Your code would be as follows
In CRActivityMaintExt
In RowPersisted
if (!(e.Row?.EntityDescription?.ToLower().Contains("opportunity") ?? false)) return;
CROpportunity opportunity = SelectFrom<CROpportunity>.Where<CROpportunity.noteID.IsEqual<#P.asGuid>>.View.Readonly.Select(Base, e.Row.RefNoteID);
if (opportunity is null) return;
var oppExt = opportunity.GetExtension<YourExtension>();
oppExt.YourValue = e.Row.SomeValue;
Base.Caches<CROpportunity>().PersistUpdated(opportunity);

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

Copying the value from a custom field to TaxRegistrationID field in RowPersisting event

I'm trying to copy the value from a custom field called "customerExt.UsrRfc" to TaxRegistrationID field but it doesn't work in Customers screen, I'm using Customer_RowPersisting event handler.
This is the customerExt.UsrRfc field:
This is the TaxRegistrationID field:
This is the RowPersisting event:
protected void Customer_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
{
Customer row = (Customer)e.Row;
if (row == null)
{
return;
}
var customerExt = row.GetExtension<BAccountExt>();
row.TaxRegistrationID = customerExt.UsrRfc;
}
I tried to copy the value to another field like "Account Ref #" and it works fine.
Can you help me with this?
The TaxRegistrationID field in the screenshot is from Location DAC instead of Customer:
You need to change the solution to update the field in the correct view.

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

How to enable a custom field on PO301000 when the PO is in Open status?

I have added a customization to the PO Entry screen, PO.30.10.00. The customization adds four date fields, a combobox text field, and a string(10) field.
Right now, the fields are only editable when the PO is on hold. The user wants to be able to edit these fields at any time. They are using these fields to keep track of different POs and will build Generic Inquiries on them so they can communicate the statuses of the POs by maintaining these fields.
The Promise Date is editable when the PO is in Open status. We would like these custom fields to be editable like the Promise Date is.
The Purchase Orders screen is heavily driven by Automation Steps. This fact makes changes to automation steps a mandatory step needed to enable a custom field when the PO is in Open status:
To enable Custom Text Fields on the Purchase Order Summary area and the Document Details grid, one should modify the NL Open step by adding 2 lines as shown in the screenshot above.
After you added those lines, Custom Text Field becomes editable on the Purchase Order Summary area, however, the Custom Text Field column is still read-only in the Document Details grid because of how POLine_RowSelected handler is implemented in the POOrderEntry BLC:
[Serializable]
public class POOrderEntry : PXGraph<POOrderEntry, POOrder>, PXImportAttribute.IPXPrepareItems
{
...
protected virtual void POLine_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
POLine row = (POLine)e.Row;
POOrder doc = this.Document.Current;
if (row == null) return;
if (IsExport) return;//for performance
bool isLinkedToSO = row.Completed == true && IsLinkedToSO(row);
if (this.Document.Current.Hold != true || isLinkedToSO)
{
PXUIFieldAttribute.SetEnabled(sender, e.Row, false);
...
}
...
}
...
}
To enable the Custom Text Field column for editing, you should additionally subscribe to POLine_RowSelected handler within your POOrderEntry BLC extension as shown in the code snippet below:
public class POOrderEntryExt : PXGraphExtension<POOrderEntry>
{
public void POLine_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
POLine line = (POLine)e.Row;
POOrder order = Base.Document.Current;
if (order == null || line == null || Base.IsExport) return;
if (order.Status == POOrderStatus.Open)
{
PXUIFieldAttribute.SetEnabled<POLineExt.usrCustomTextField>(sender, line, true);
}
}
}
Once you made changes in Automation Steps and subscribed to POLine_RowSelected handler within a POOrderEntry BLC extension your custom fields on both the Purchase Order Summary area and the Document Details grid should be open for editing when the PO is in Open status:

Resources