RowSelecting does not execute - acumatica

I use the RowSelecting event, in order to perform a BQL query. I choose this event, since adding a BQL in RowSelected event is not advisable. My purpose is to assign a non-DB bound field (a boolean), which is used to enable/disable a field. During RowSelected event, the value is read, and a particular field is enabled/disabled, based on that value.
While using the debugger, I notice RowSelecting event does not fire when the form is first opened. Cancel button causes event to fire. Then I notice the api documentation...RowSelected & FieldSelecting events happen during sequence of events - display of record. RowSelecting is not mentioned.
My goal is to disable a field based on some BQL. What is the best way to perform the BQL and disable the field? Should I use RowSelected? Documentation says to avoid it. In my case, I refer to SO invoice entry form...specifically SOInvoice DAC.

You can extend the DAC in the Graph to add a PXUIEnabled Attribute to do this.
I updated my example to include a non-databound field that controls enabling and disabling another field.
In the SOInvoiceExt DAC Extension I have...
public class SOInvoiceExt : PXCacheExtension<PX.Objects.SO.SOInvoice>
{
#region UsrExtRefNbrDisabled
[PXBool]
[PXUIField(DisplayName = "ExtRefNbr Disabled?")]
public virtual bool? UsrExtRefNbrDisabled { get; set; }
public abstract class usrExtRefNbrDisabled : PX.Data.BQL.BqlBool.Field<usrExtRefNbrDisabled> { }
#endregion
}
Then I added the new custom field to the screen. Ensure that you set CommitChanges to True.
Then in the Graph Extension, I merged the PXUIEnabled attribute with the CachedAttached event
[PXUIEnabled(typeof(Where<SOInvoiceExt.usrExtRefNbrDisabled, NotEqual<True>>))]
[PXMergeAttributes(Method = MergeMethod.Merge)]
protected virtual void SOInvoice_ExtRefNbr_CacheAttached(PXCache cache)
{ }
I was able to check/uncheck the box and it enabled/disabled the field.
Here is an old blog post on the subject: https://asiablog.acumatica.com/2016/11/pxuienabled-and-pxuirequired-attributes.html

Probably the best way to do this would be to make your NonDB field a calculated field and then setEnabled from RowSelected.
https://www.acumatica.com/blog/using-the-pxformula-attribute-to-simplify-your-code/
Otherwise, create a BQl query in FieldDefaulting.

Related

How can I change the date range for the MRP Exceptions data?

I want to change the date where the MRP Exception data (created using the Regenerate MRP process screen) cuts off (as of now, it seems to use the current business date). I found the following logic in the MRPEngine BLC, and I think this is where I would add an OR, using a custom field to add an additional date to the following BQL statements:
....
so - my question is, is there an easier way to add an additional date (ORed to the current business date) to the where clause in this method without re-writing the entire business logic / associated methods included in this call?
Thanks...
I think the only way will be to overwrite that function in a graph extension
public class MRPEngine_Extension : PXGraphExtension<PX.Objects.AM.MRPEngine>
{
#region Event Handlers
public delegate void MrpExceptionsAllDelegate();
[PXOverride]
public void MrpExceptionsAll(MrpExceptionsAllDelegate baseMethod)
{
//do your changed logic here
}
#endregion
}

How can I disable the Copy/Paste Save Template action?

Acumatica offers a great feature to Save as Template which makes creating new records from the template faster and easier. However, I have a use case where I need a more interactive sort of template in which the user can create a list of 100 items and then select which items to include when creating the new record.
In this case, the standard feature for Save as Template could be confusing, especially for new users learning the system. I have been asked to disable Save as Template on the Copy/Paste menu on my custom screen and transition to this new feature. I do not want to disable Copy/Paste entirely, just the Template functionality. If I disable Copy/Paste in Access Rights, the entire menu disappears. However, the template options do not appear in Access Rights.
Copy/Paste appears to be accessible via code as the PXAction CopyPaste which can be hidden or disabled, but again, I cannot find SaveTemplate as a child that I can control.
How can I disable/hide Save as Template (CopyPaste#SaveTemplate) on an Acumatica screen, either programmatically, in access rights, or in workflow? This menu is part of the standard Acumatica menu system when specifying a primary DAC when defining the graph. Alternatively, I think it enabled via the PXCopyPasteAction<> action if manually defining buttons on the page.
You can create your own PXCopyPasteAction by just extending the base class and then adding it to your graph
quick example below
public class CustomCopyPasteAction: PXCopyPasteAction<SOOrder>
{
public CustomCopyPasteAction(PXGraph graph, string name): base(graph, name) { }
protected override void RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
base.RowSelected(cache, e);
bmSaveTemplate.Enabled = false;
}
}
The CopyPaste action is coming predefined as part of the PXGraph<TGraph,TPrimary> class. So you should be able to just simply do CopyPaste.SetEnabled(false) in the RowSelected event handler of your graph.
Another option is to try to override the CanClipboardCopyPaste virtual function of the PXGraph class.
public class PXGraph<TGraph, TPrimary> : PXGraph where TGraph : PXGraph where TPrimary : class, IBqlTable, new()
{
public override bool CanClipboardCopyPaste()
{
return true;
}
/// <summary>The action that saves changes stored in the caches to the database. The code of an application graph typically saves changes through this action as well. To invoke it from code, use the PressSave() method of the Actions property.</summary>
public PXSave<TPrimary> Save;
/// <summary>The action that discard changes to the data from the caches.</summary>
public PXCancel<TPrimary> Cancel;
/// <summary>The action that inserts a new data record into the primary cache.</summary>
public PXInsert<TPrimary> Insert;
/// <summary>The action that deletes the Current data record of the primary cache.</summary>
public PXDelete<TPrimary> Delete;
/// <summary>The action that is represented on the user interface by an expandable menu that includes Copy and Paste items.</summary>
public PXCopyPasteAction<TPrimary> CopyPaste;
/// <summary>The action that navigates to the first data record in the primary data view. The data record is set to the Current property of the primary cache.</summary>
public PXFirst<TPrimary> First;
/// <summary>The action that navigates to the previous data record in the primary data view. The data record is set to the Current property of the primary cache.</summary>
public PXPrevious<TPrimary> Previous;
/// <summary>The action that navigates to the next data record in the primary data view. The data record is set to the Current property of the primary cache.</summary>
public PXNext<TPrimary> Next;
/// <summary>The action that navigates to the last data record in the primary data view. The data record is set to the Current property of the primary cache.</summary>
public PXLast<TPrimary> Last;
}

How to make Acumatica custom action update the current record

I'm trying to make a custom action update a custom field on the current record. Eventually I need to work through all the deatils to collect some data, but for now I just need to click the button and have it update the current record. More or less, I think I fail to understand how to get the data that would be in a row level event like this protected void SOOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
public PXAction<PX.Objects.SO.SOOrder> LookupShipping;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Lookup Shipping Rates")]
protected void lookupShipping()
{
SOOrder TheRow = Base.Document.Current;
}
Thanks in advance.
If you are trying to update custom fields...
First, you will want to connect to the DAC Extension via:
SOOrderExt sOOrderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(TheRow);
Then you need to update the field value. Assuming you are in a Graph Extension, you will need to utilize "Base" to access the cache.
Base.Caches[typeof(SOOrder)].SetValueExt<SOOrderExt.usrCustomField>(TheRow, InsertValueHere);
Once you update all field values, you need to actually update the cache itself.
Base.Caches[typeof(SOOrder)].Update(sOOrderExt);
And don't forget to save the record, assuming this button should be a one-stop shop.
Save.Press();
If you are trying to simply update the values in the existing view, you can do it very easily.
TheRow.FieldName = InsertValueHere;
Document.Current.Update(TheRow);
Save.Press();
You can see some good alternatives to updating values in HB_Acumatica's answer to where I asked something similar...
What is the proper way to update values of DAC's retrieved via PXResultset?

Limiting Projects based on selector

I would like to filter the records shown on the Projects screen. I've been given the directive to see if limiting the Selector for projects (re-writing the PXSelector for the ProjectID?) would also limit the records that show up on the screen, i.e., a user would not be able to navigate to records that aren't displayed by the Selector. I don't think that's the case, as the screen's view is not limited by what is chosen by the Selector - but I wanted to verify this.
Also - as far as limiting the records that show up in the Selector (possibly re-writing the Selector/BQL using a where clause?) - I looked at the source DAC, and for the life of me I can't figure it out. There is a PXSelector on the ContractID, which doesn't use the SubstituteKey that I'm familiar with, and the ContractCD also has several attributes with which I'm unfamiliar - namely the PXRestrictor AND the PXDimensionSelector.
Bottom line:
1.) What's the best way to limit the records for Project shown in the screen's Selector? Can I just add to the PXRestrictor attribute?
2.) Would limiting the Selector's results also limit what the user can navigate to on the screen using the navigation buttons?
Whenever you need to restrict access to primary records on a data entry screen, it's always required to customize both the lookup DAC key field and the primary data view. By design, in Acumatica key fields in DAC and the primary data view are completely independent, that is why it's required to modify both pieces to achieve the desired result.
For example, to deny access to canceled projects on the Projects screen, you should add PXRestrictorAttribute to PMProject's ContractCD field and also re-declare Project primary data view:
public class ProjectEntryExt : PXGraphExtension<ProjectEntry>
{
public class cancelled : Constant<string>
{
public cancelled() : base(ProjectStatus.Cancelled) {; }
}
[PXViewName(Messages.Project)]
public PXSelect<PMProject, Where<PMProject.baseType, Equal<PMProject.ProjectBaseType>,
And<PMProject.nonProject, Equal<False>, And<PMProject.isTemplate, Equal<False>,
And<PMProject.status, NotEqual<cancelled>,
And<Match<Current<AccessInfo.userName>>>>>>>> Project;
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXRestrictor(typeof(Where<PMProject.status, NotEqual<cancelled>>),
"Given Project/Contract '{0}' is cancelled", typeof(PMProject.contractCD))]
public void PMProject_ContractCD_CacheAttached(PXCache sender) { }
}

Custom field checkbox is greyed out (read only) on Void Payment

I have a custom field on the Payments and Applications screen. That when I void a payment I cannot edit my custom field on there. The payment is in the balanced state and it lets me edit the Hold checkbox as well as the application date. But I cant figure how to make my custom field editable as well?
Here is my DAC declaration on ARRegister Extension class
#region UsrMAFOManuallyAddToRex
[PXDBBool]
[PXUIField(DisplayName = "Manually Add Payments To Rex", Visibility = PXUIVisibility.Visible)]
public virtual bool? UsrMAFOManuallyAddToRex { get; set; }
public abstract class usrMAFOManuallyAddToRex : IBqlField { }
#endregion
First of all,
i am wondering why you need your field to be editable in a voided payment.
When i checked the source of acumatica, i saw in the row selected event of ARPayment have the code which disables the whole cache [which may include your custom field too], this might be the reason why it is disabled in a voided payment.
If you really want to enable, you might need a custom code to enable the cache and disable the rest.

Resources