As per title. A new action menu is automatically added to the bottom of the list. Is there a way to force them to appear on specific index or just before/after a specific action ?
Thanks in advance
In Automation Steps screen, in Actions tab you can find the button REORDER ACTIONS, this may help you.
PXGraph class has an action collections declared as:
public readonly PXActionCollection Actions;
It is a class deriving from .Net framework OrderedDictionary.
You can access it directly in your class deriving from PXGraph:
this.Actions
In the context of a graph extension deriving from PXGraphExtension it is available though Base member:
Base.Actions
Look at the public methods exposed by Actions, I think Move might be able to swap the Actions order in the menu. Here is some usage examples:
public PXAction<APInvoice> release;
public PXAction<APInvoice> prebook;
// Resolving name with static check
Base.Actions.Move(nameof(release), nameof(prebook));
// Using action display name with runtime check
Base.Actions.Move("Release", "Pre-book");
Related
If I create a UserControl, to create and edit an instance of a data class e.g. Person in C# WindowsForms (call it PersonControl), the framework automatically adds an instance of Person in PersonControl.Designer with some default values for the properties and fills the item controls with those values. This behavior has a number of side effects which I would like to avoid.
Question: is there a defined way to prevent creation of a data class instance in UserControl.Designer?
I think you missing the DesignerSerializationVisibility attribute. If you have a custom control every public property that you add will automatically be serialized. You can use this attribute to disable the serialization for a property. I also recommend to add the Browsable attribute which will hide the property from the designer. If you want more control over serialization, like you want to serialize only when another property is set to true you can create a special named method which will then called by the designer Defining Default Values with the ShouldSerialize and Reset Methods. There was a MSDN Magazine where a lots of winform learning resource was relased there are some gems about winform internal working. If you interested in you can quickly look trhrough it. My favorite is. Create And Host Custom Designers With The .NET Framework 2.0
Sorry but i didn't mention another attribute DefaultValue You can use the attribute the following way.
public partial class PersonEditControl : UserControl
{
[DefaultValue(null)] // This attribute tells the designer if the property value matches what we specified in the attribute(null) it should not store the property value.
public PersonData? Person { get; set; }
public PersonEditControl()
{
InitializeComponent();
}
}
We are in to acumatica 20 r2 and when we publish the custom package, the default report menu print salesorder/quote option disappears.
We have custom reports which are added by overriding the initialize method of salesorderentry graph in my extension.
public override void Initialize()
{
base.Initialize();
base.Base.report.AddMenuAction(embroideryreport);
base.Base.report.AddMenuAction(embroiderysoreport);
base.Base.report.AddMenuAction(screenprintreport);
base.Base.report.AddMenuAction(screenprintsoreport);
}
I am not able to figure out the reason for missing report. I have upgraded the workflow to latest version and still having the issue.
UPDATE
I did not call base.Initialize() initially and since the default report is not coming, I thought it may be due to not invoking the base method.
I have tried bahaa-zantout suggestion and the base report is already tagged to the report menu and when I commented on the code in Initialize method for adding the report the default report appeared again under-report menu.
It looks like there is conflict in the workflow and I am not able to figure it out.
I have tried to add those report in the workflow action section and tagged them to Report and the entire report menu disappeared
Change you initialization method to....
public override void Initialize()
{
base.Base.report.AddMenuAction(embroideryreport);
base.Base.report.AddMenuAction(embroiderysoreport);
base.Base.report.AddMenuAction(screenprintreport);
base.Base.report.AddMenuAction(screenprintsoreport);
}
From Acumatica DEV documentation portal
You do not need to explicitly invoke the Initialize() method on the previous extension levels; these methods are called automatically. Invoking base.Initialize() makes no sense, because the base variable points to the base class, which is PXGraphExtension (not the base graph). The PXGraphExtension class defines Initialize() as an empty method.
You could attempt the following in attempt to restore the toolbar menu item.
Navigate to the Sales Order screen in the customization project
Go to the Actions
Locate the missing print options (ie. printSalesOrder) and place the Toolbar folder in the original folder in this case "Reports". If it doesn't work try moving to "Actions" and see if it appears.
See example screenshot.
I am not sure it is due to this statement or not but when I changed the following statement it fixed the issue
[PXButton(SpecialType = PXSpecialButtonType.ReportsFolder)]
to
[PXButton]
for Report action
public PXAction<SOOrder> embroideryreport;
[PXUIField(DisplayName = "Embroidery Production Report", MapEnableRights = PXCacheRights.Select)]
//[PXButton(SpecialType = PXSpecialButtonType.ReportsFolder)]
[PXButton]
I have created a new CREATE QUOTE button on Requisition screen that replace the standard button which located at Action menu. After trying to hide it on RQRequisition_RowSelected event, the button still appear and able to click when the requisition is on Pending Quote Status. Kindly need advice how to hide it.
Customized Requisition Screen
To hide or show an action button, you should redefine the Visible parameter of the PXUIField attribute for the button.
You can change attributes of an action button by using one of the following approaches:
Dynamically at run time, in the Initialize() method of the graph
extension
Statically, by overriding the action attributes in the
graph extension
To Hide an Action Button at Run Time
In the graph extension, add the following code.
public override void Initialize()
{
base.Initialize();
Base.MyAction.SetVisible(false);
}
In the added code, replace MyAction with the action name.
To Hide or Show an Action Button Statically
To override action attributes in a graph extension statically, you should declare both the graph member of the PXAction type and the delegate. You should attach a new set of attributes to the action delegate, declared within the graph extension. Also, you need to invoke the Press() method on the base graph action. Having redeclared the member of PXAction, you prevent the action delegate execution from infinite loops.
Explore the original action declaration and copy the declaration to the graph extension.
In the action declaration, set to false the Visible parameter of the PXUIField attribute, as the following code snippet shows.
...
[PXUIField(…, Visible = false)]
...
Replace the action delegate with the following code template.
public virtual IEnumerable myAction(PXAdapter adapter)
{
return Base.MyAction.Press(adapter);
}
In the code template, replace myAction and MyAction with the appropriate names.
In the template, redefine the action delegate arguments and return type according to the signature of the base action delegate.
If you have a customization that replaces an original action
declaration statically, after upgrading Acumatica ERP to a new
version, a new functionality of the same action may became
unavailable.
Also, if a callback command for the button is declared in the PXDataSource control, you can hide the button by customizing the ASPX code. To do this, in the Layout Editor, expand the PXDataSource control, select the appropriate PXDSCallbackCommand element, and set to False the Visible property of the element.
CREATE QUOTE button on the Requisition screen is implemented like a normal action in the RQRequisitionEntry BLC:
public class RQRequisitionEntry : PXGraph<RQRequisitionEntry>
{
...
public PXAction<RQRequisition> createQTOrder;
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
[PXUIField(DisplayName = Messages.CreateQuotation)]
public virtual IEnumerable CreateQTOrder(PXAdapter adapter)
{
...
}
...
}
However, CREATE QUOTE button is added into the Actions drop down via Automation Steps:
With that said, the best way to customize the CREATE QUOTE button is by re-declaring the action within the RQRequisitionEntry BLC extension following sample below. I would be happy to come up with a more specific sample, if you provide additional details regarding your request.
public class RQRequisitionEntryExt : PXGraphExtension<RQRequisitionEntry>
{
public PXAction<RQRequisition> createQTOrder;
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
[PXUIField(DisplayName = RQ.Messages.CreateQuotation)]
public virtual IEnumerable CreateQTOrder(PXAdapter adapter)
{
return Base.createQTOrder.Press(adapter);
}
}
I have written an Orchard Module and would like an item to appear in a Navigation list when the module is Enabled. Ideally, I would like to be able to remove the item when the Module is disabled.
Where should I hook into to for when the module is enabled and disabled?
How do I programmatically add a menu item to an already existing Navigation?
You can implement the IMenuProvider interface for this. An example implementation might look something like this:
namespace Orchard.Bar {
public class SuperMenuProvider : IMenuProvider {
private readonly IOrchardServices _orchardServices;
public SuperMenuProvider(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void GetMenu(IContent menu, NavigationBuilder builder) {
string position = "10";
builder.Add(T("Foo"), position, item => item.Url("http://foo.com").AddClass("someClass"));
builder.Add(T("Bar"), position + ".1", item => item.Action("Index", "Foo", new { area = "Orchard.Bar" }));
if (_orchardServices.Authorizer.Authorize(Orchard.Security.StandardPermissions.AccessAdminPanel)) {
builder.Add(T("Secure FooBar"), position + ".2", item => item.Action("Index", "Secure", new { area = "Orchard.Bar" }));
}
}
}
}
This will appear on all menus on the front end. You may want to put in the name of the menu you are targeting if you know for sure that is what it is called (default in Orchard is "Main Menu", people don't generally change it to be honest). This could be a little brittle, so you may want it customizable, either with a site setting or you could create a part that you attach to the menu content type that lets the admin specify whether to show your menu items on the said menu.
An alternative approach would be to hook into the modules enable event using IFeatureEventHandler and using the content manager to create menu items with urls and adding them to a specified Menu. I don't really recommend this approach; you lose control of the menu items (e.g. to update a url), they can be removed from the menu accidentally, you have to know the name of the Menu you are adding them to, you are more limited (cant do permissions checks etc.).
I assume you are talking about showing up on the front end. If you talking about the admin menu then check out pretty much any module for a file generally called AdminMenu.cs, plenty of examples :)
The question doesn't specify what the module does so I guess we're to assume that it creates a content type. In that case you have (at least) two options:
In the Content Type's Content Definition go to Add Parts and add the Menu part. This will allow you to add a content item to a menu from the item's content editor.
From the Navigation menu choose the appropriate Menu and select add a Content Menu Item. Note that the content type must be set as "listable" in Content Definition in order for the items to be listed as a choice.
Disabling the module should remove the item from the navigation in either case.
I have a requirement where i need to weld a ContentPart to all the content types. Please guide me what is the best place to write this code.
I looked into the Orchard source code where InfosetPart is being welded with all content types in ContentHandlerBase's Activating method.
Following the InfosetPart weld mechanism i created one class inheriting from ContentHandlerBase and in Activating method i placed a break point with following condition which is getting hit again and again (more than once for one content type)
context.ContentType == "Page"
I'm not sure if it should be as it is because ideally it should hit this condition only once.
The way you are implementing it is correct. Your code is executed multiple times because content handlers are invoked for each content item, and not just for the content type. This also allows you to weld your part to only some of you content items, not all items of a specified type.
You wrote that you created a subclass of ContentHandlerBase. You should use ContentHandler as a base class.
Below is a simple code example how this should be done.
public class MyPartHandler : ContentHandler
{
protected override void Activating(ActivatingContentContext context) {
context.Builder.Weld<MyPart>();
}
}