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

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

Related

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.

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

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?

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.

Unbound fields on DAC extension - where to populate?

I have extended the CRMarketingListMember DAC in order to include a number of unbound fields. I'm adding these new unbound fields to the List Members grid on CR204000 and need to execute some code in order to put values into these fields when the List Members grid is displayed. The problem is that my unbound fields are always blank in the grid. I've tried extending the CRMarketingListMaint graph and putting the code that populates the unbound fields into the CRMarketingList_RowSelected() event but that, of course, doesn't work.
Thanks for the help!
RowSelecting is the proper event in which to populate unbound fields, if doing additional BQL selects make sure to wrap the logic in a new PXConnectionScope.
Example Below :
public virtual void ARInvoice_RowSelecting(PXCache sender, PXRowSelectingEventArgs e)
{
ARInvoice row = e.Row as ARInvoice;
if (row != null)
{
using (new PXConnectionScope())
{
ARRegisterExtension rowExt = PXCache<ARRegister>.GetExtension<ARRegisterExtension>(row);
var result = PXSelect<.....>
rowExt.UsrISExternalTax = result.IsExternalTax;
}
}
}

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