If I have an Action button added on a Graph, how can I programmatically control whether it is enabled or disabled? For example, if I want to disable the button, related to a particular field in my Main DAC, how should I do that?
Within the DACs row selected you can call on your action SetEnabled to indicate if the button is enabled or not.
Example:
protected virtual void MyDac_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
myButtonAction.SetEnabled(true /*false*/);
}
public PXAction<MyDac> myButtonAction;
[PXUIField(DisplayName = "My Button", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = false)]
[PXButton]
public virtual IEnumerable MyButtonAction(PXAdapter adapter)
{
reteurn adapter.Get();
}
Related
I would like to see the code behind the grid actions button. let say buttons in the grid sectoin of Bills and Adjustment Screen are marked with orange boxes.
I would like to see how the code is configured behind the buttons.
Where can I find the file or code in the Acumatica website folder?
Especially I want code behind the "ADD SUBCONTRACT" button.
The code for the buttons/actions looks like it comes from the construction edition found in PX.Objects.CN.Subcontracts.AP.GraphExtensions.ApInvoiceEntryAddSubcontractsExtension (PX.Objects.CN.dll)
Snippets of related code:
[PXButton]
[PXUIField(DisplayName = "Add Subcontracts", FieldClass = "DISTR", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
public virtual IEnumerable addSubcontracts(PXAdapter adapter)
{
this.Base.checkTaxCalcMode();
if (!this.ShouldAddSubcontracts())
return adapter.Get();
this.Base.updateTaxCalcMode();
return this.addSubcontract(adapter);
}
[PXButton]
[PXUIField(DisplayName = "Add Subcontract", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = false)]
public virtual IEnumerable addSubcontract(PXAdapter adapter)
{
return ApInvoiceEntryAddSubcontractsExtension.AddLines(new Func<PXAdapter, IEnumerable>(this.Base1.AddPOOrder2), adapter);
}
[PXButton]
[PXUIField(DisplayName = "Add Subcontract Line", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
public virtual IEnumerable addSubcontractLines(PXAdapter adapter)
{
this.Base.checkTaxCalcMode();
return this.ShouldAddSubcontractLines() ? this.addSubcontractLine(adapter) : adapter.Get();
}
[PXButton]
[PXUIField(DisplayName = "Add Subcontract Line", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = false)]
public virtual IEnumerable addSubcontractLine(PXAdapter adapter)
{
return ApInvoiceEntryAddSubcontractsExtension.AddLines(new Func<PXAdapter, IEnumerable>(this.Base2.AddPOOrderLine2), adapter);
}
private static IEnumerable AddLines(
Func<PXAdapter, IEnumerable> addLine,
PXAdapter adapter)
{
try
{
return addLine(adapter);
}
catch (PXException ex) when (ex.MessageNoPrefix == "Failed to add one or more lines from the PO order. Please check the Trace for details.")
{
throw new Exception("SC Error: Failed to add one or more lines from the Subcontract. Please check the Trace for details.");
}
}
Looking at this code we can see it will use AddPOOrder2 from PX.Objects.PO.GraphExtensions.APInvoiceSmartPanel.AddPOOrderExtension from PX.Objects.dll
This code is found in the source availabine in Acumatica as:
[PXUIField(DisplayName = Messages.AddPOOrder, MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = false)]
[PXLookupButton]
[APMigrationModeDependentActionRestriction(
restrictInMigrationMode: true,
restrictForRegularDocumentInMigrationMode: true,
restrictForUnreleasedMigratedDocumentInNormalMode: true)]
public virtual IEnumerable AddPOOrder2(PXAdapter adapter)
{
bool isInvoice = (Base.Document.Current.DocType == APDocType.Invoice),
isPrepayment = (Base.Document.Current.DocType == APDocType.Prepayment);
if (Base.Document.Current != null &&
isInvoice &&
Base.Document.Current.Released == false &&
Base.Document.Current.Prebooked == false)
{
List<POOrder> orders = poorderslist.Cache.Updated.RowCast<POOrder>().Where(rc => rc.Selected == true).ToList();
foreach (POOrder rc in orders)
{
Base.InvoicePOOrder(rc, false);
}
Base.AttachPrepayment(orders);
}
return adapter.Get();
}
The Base call here is referring to APInvoiceEntry
when you decompile the PX.Objects.dll file we can find code for "ADD PO"
PX.Objects.PO.GraphExtensions.APInvoiceSmartPanel.AddPOOrderExtension
but, I need code for ADD Subcontracts
I Wanted make the Multiselect Dropdown to be mandatory field,i have used the PXDefault() Attribute at Dac level,it is throwing validation but the Madatory symbol is not displaying in the UI.
[PXDBString(250, IsUnicode = true)]
[PXUIField(DisplayName = "Mapped Warehoueses",Required =true)]
[PXDefault()]
[KNFNWarehousePrefetch()]
public virtual string MappedWarehoueses { get; set; }
public abstract class mappedWarehoueses : IBqlField { }
When that happens, you can add the asterisk symbol using the RowSelected Event:
Here is a field without the asterisk:
This it the DAC Definition:
[PXDBString(100, IsUnicode = true)]
[PXUIField(DisplayName = "Nickname")]
Then, the RowSelected event is defined:
protected virtual void [DACName]_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
PXUIFieldAttribute.SetRequired<[DACName].nickname>(sender, true);
After that, the asterisk is visible in the UI:
Note that the field does not become mandatory. Only the symbol was added in the UI.
I was asked to make what I thought would be a very simple customization, hide the Promised On field on the PO Order Entry page. I opened the PO301000 screen in the customization editor, highlighted Promised On, clicked Attributes and clicked Override on Screen Level. I changed the resulting code on POOrderEntry to:
namespace PX.Objects.PO
{
public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
#region Event Handlers
[PXDBDate()]
[PXDefault(typeof(POOrder.orderDate), PersistingCheck = PXPersistingCheck.Nothing)]
[PXUIField(DisplayName = "Promised On", Visibility = PXUIVisibility.Visible, Visible = false)]
protected virtual void POOrder_ExpectedDate_CacheAttached(PXCache cache)
{
}
#endregion
}
}
To my surprise, it did not work, the Promised On field is still visible and I do not know why. The version is 18.100.0062.
It looks like there is a RowSelected event in POOrderEntry that sets the visibility based on if it is a blanket PO. Since this is later in the chain of events it overrides the CacheAttached event.
You can get what you want by adding your own RowSelected event. Here's an example.
protected void POOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
PXUIFieldAttribute.SetVisible<POOrder.expectedDate>(cache, null, false);
}
GeorgeM use the code below. The trick is to call baseMethod before making changes to the visible state of the field.
namespace PX.Objects.PO
{
public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
[PXOverride]
protected virtual void POOrder_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected baseMethod)
{
baseMethod(cache, e);
PXUIFieldAttribute.SetVisible<POOrder.expectedDate>(cache, null, false);
}
}
}
I'd like to add a custom button to the header of the Bills and Adjustments screen that will contain custom actions in a dropdown, ala the 'Actions' button that's already there (I don't want to add these actions to the existing 'Actions' button - I want my own dropdown containing custom actions).
I know how to add actions to the existing 'Actions' button, but is there a way to do what I'm looking to do?
It is the same step just using your own drop button. You need to add your "Actions" button and then do the same steps to the other buttons to add them to your main drop down button.
Here is a quick example below. I created a MyDropMenu action button which all of my other buttons live under:
//within initialize or graph constructor...
MyDropMenu.AddMenuAction(MyAction1);
MyDropMenu.AddMenuAction(MyAction2);
MyDropMenu.AddMenuAction(MyAction3);
//...
public PXAction<PrimaryDac> MyDropMenu;
[PXUIField(DisplayName = "My Drop Menu", MapEnableRights = PXCacheRights.Select)]
[PXButton(MenuAutoOpen = true)]
protected IEnumerable myDropMenu(PXAdapter adapter)
{
return adapter.Get();
}
public PXAction<PrimaryDac> MyAction1;
[PXUIField(DisplayName = "My Action 1", MapEnableRights = PXCacheRights.Select)]
[PXButton]
protected IEnumerable myAction1(PXAdapter adapter)
{
return adapter.Get();
}
public PXAction<PrimaryDac> MyAction2;
[PXUIField(DisplayName = "My Action 2", MapEnableRights = PXCacheRights.Select)]
[PXButton]
protected IEnumerable myAction2(PXAdapter adapter)
{
return adapter.Get();
}
public PXAction<PrimaryDac> MyAction3;
[PXUIField(DisplayName = "My Action 3", MapEnableRights = PXCacheRights.Select)]
[PXButton]
protected IEnumerable myAction3(PXAdapter adapter)
{
return adapter.Get();
}
You also need to add the callback command for the drop menu action to the page like this...
<px:PXDSCallbackCommand Name="MyDropMenu" Visible="True" CommitChanges="true" StartNewGroup="true" ></px:PXDSCallbackCommand>
I tested this on a Sales Order Extension replacing PrimaryDac to SOOrder and shows up as:
I have to adjust how an action works. I know that I cannot adjust the code that runs the action itself, so is there any way to execute extra code when a specific action has been executed?
You simply declare the Action in your extension the same as the base action to "override"
Here is an example overriding the View Source Document action on GL Journal Entry:
public class JournalEntryMyExtension : PXGraphExtension<JournalEntry>
{
public PXAction<Batch> viewDocument;
[PXLookupButton]
[PXUIField(DisplayName = "View Source Document", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
public virtual IEnumerable ViewDocument(PXAdapter adapter)
{
// Logic Before Base Action
Base.viewDocument.Press(adapter);
// Logic After Base Action
return adapter.Get();
}
}
Here is the action direct from the base graph for comparison:
public PXAction<Batch> viewDocument;
[PXUIField(DisplayName = Messages.ViewSourceDocument, MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXLookupButton()]
public virtual IEnumerable ViewDocument(PXAdapter adapter)
{
if (this.GLTranModuleBatNbr.Current != null)
{
GLTran tran = (GLTran) this.GLTranModuleBatNbr.Current;
OpenDocumentByTran(tran, BatchModule.Current);
}
return adapter.Get();
}