I am trying to customize the approve button and I can't find the right method to do it.
Could you tell me how I can manipulate that event.
Thanks in advance.
button to customize
Method
I looked around at the ExpenseClaimEntry, and the approval is added from the class ExpenceClaimApproval. You can browse the code through the Code Library in an extension Library under the folder App_Data\CodeRepository\PX.Objects\EP\ExpenseClaimEntry.cs. The derived type is declared in the Descriptor\Attribute.cs file. There is a StatusHandler you can set that is executed upon approval/denial.
I built this test graph and was able to break in the middle of the approval process:
public class ExpenseClaimEntry_Extension : PXGraphExtension<ExpenseClaimEntry>
{
public void CustomApprovalAction(EPExpenseClaim item)
{
//do something
}
public override void Initialize()
{
base.Initialize();
Base.Approval.StatusHandler += CustomApprovalAction;
}
}
Related
In an Acumatica code extension, I am attempting to create a workflow extension for BusinessAccountWorkflow. It adds a few actions that I want to suppress. My extension’s Configure method override basically doesn’t do anything, so that the base method doesn’t create actions. My override method doesn’t seem to be running, though, because the actions still appear, and my breakpoint isn’t hit. Below is the extension. What could I be missing to get this override to run?
public class BusinessAccountWorkflowExt : PXGraphExtension<BusinessAccountWorkflow,
BusinessAccountMaint>
{
public static bool IsActive() => false;
public override void Configure(PXScreenConfiguration configuration)
{
var context = configuration
.GetScreenConfigurationContext<BusinessAccountMaint, BAccount>();
context.AddScreenConfigurationFor(screen =>
{
return screen;
});
//context.RemoveScreenConfigurationFor();
}
}
Tony, your code sample sets IsActive to false which should disable the graph extension. This doesn't exactly seem to behave the same on workflows as it does normal graph extensions, so I'm not sure if it causes any harm.
Next, I think you really want to use UpdateScreenConfigurationFor instead of AddScreenConfigurationFor. This lets you tap into the defined workflow and add actions or alter conditions. For instance, you can update an action to be .IsHiddenAlways() if you don't want it to show in any condition. (Alternatively, you can hide it via permissions and never have to code for that!)
Take a look at standard workflow source code that ends _ApprovalWorkflow.cs for examples of how Acumatica updates an existing workflow to insert Approve and Reject functionality as well as altering transitions to inject the Pending approval state.
To be able to add your own actions, it's pretty simple code. Below is an example of how I injected my own actions into the menu for the Sales Order Entry screen, which honestly has a crazy complex workflow overall. However, always adding my buttons to the menu doesn't require touching any of that standard complexity.
using PX.Data;
using PX.Data.WorkflowAPI;
using SSCS;
namespace PX.Objects.SO.Workflow.SalesOrder
{
public class SOOrderEntry_Workflow_SSCS : PXGraphExtension<SOOrderEntry>
{
public static bool IsActive() => true; // Insert your own logic here
#region Initialization
public override void Configure(PXScreenConfiguration config)
{
Configure(config.GetScreenConfigurationContext<SOOrderEntry, SOOrder>());
}
protected virtual void Configure(WorkflowContext<SOOrderEntry, SOOrder> context)
{
context.UpdateScreenConfigurationFor(screen =>
{
return screen
.WithActions(actions =>
{
actions.Add<SOOrderEntry_Extension>(g => g.RecordOutage, a => a.WithCategory(PredefinedCategory.Actions));
});
});
}
#endregion
}
}
Where I added actions in the above sample using actions.Add, you would want to use actions.Update to alter the definition of the action. This is where you would put .IsHiddenWhen(condition) or .IsHiddenAlways().
I am trying to sign out a user once a process is completed, I tried using the PXAccess or the PXAccessInfo classes in order to do so but did not manage to find a correct way in logging out a user. Are there any other means in signing out a user which I might have glossed over?
I adapted the standard SignOut code so it can be run from a graph extension instead of a Aspx.cs web page. It is equivalent to this SignOut menu item:
In this example I put the code in SOOrderEntry Initialize override so it signs out the current user as soon as you navigate to the SalesOrderEntry graph. You can put it in an Action event handler but I haven't tested it in a PXLongOperation context which runs in a separate thread context:
public class SOOrderEntry_Extension:PXGraphExtension<SOOrderEntry>
{
public override void Initialize()
{
System.Web.UI.Page page = System.Web.HttpContext.Current.Handler as System.Web.UI.Page;
if (page != null)
{
PX.Data.PXLogin.LogoutUser(PX.Data.PXAccess.GetUserName(), page.Session.SessionID);
PX.Common.PXContext.Session.SetString("UserLogin", string.Empty);
string absoluteLoginUrl = PX.Export.Authentication.AuthenticationManagerModule.Instance.SignOut();
page.Session.Abandon();
PX.Data.Auth.ExternalAuthHelper.SignOut(System.Web.HttpContext.Current, absoluteLoginUrl);
PX.Export.Authentication.FormsAuthenticationModule.
RedirectToLoginPage(PX.Data.Auth.ExternalAuthHelper.SILENT_LOGIN + "=None", true);
}
}
}
I'm interested in hooking into the print report action on a Sales Order to mark the SO "Traveler Printed" when someone has printed that particular report. Suggestions for how to accomplish this? I know it's done on the PO but I'm struggling to parse out the where and how of it.
In Customization Project Editor Code section, create a graph extension for SOOrderEntry.
Customization Project Editor has an Override Method feature that is handy for generating the event handler prototype:
You can then edit the generated stub definition like this:
namespace PX.Objects.SO
{
public class SOOrderEntry_Extension:PXGraphExtension<SOOrderEntry>
{
#region Event Handlers
public delegate IEnumerable ReportDelegate(PXAdapter adapter, String reportID);
[PXOverride]
public IEnumerable Report(PXAdapter adapter, String reportID, ReportDelegate baseMethod)
{
if (reportID == "SO641010")
{
PXTrace.WriteInformation("I'm doing my things here, after report action has been invoked, just before report is actually launched.");
}
return baseMethod(adapter,reportID);
}
#endregion
}
}
I am trying to customise an Acumatica Processing Page by adding my own processing button. I have tried the usual methods of extending the processing page but unfortunately the button is not displayed on the page.
public class APPrintChecks_Extension : PXGraphExtension<APPrintChecks>
{
public PXAction<APPayment> Test;
[PXProcessButton]
[PXUIField(DisplayName = "Button Test")]
protected virtual IEnumerable test(PXAdapter adapter)
{
return adapter.Get();
}
}
I do not want to override the existing functionality provided by the processing button and as such would like to add my own.
Thanks.
The primary view of the Process Payments / Print Checks page is Filter which is of type PrintChecksFilter. So you need to have your PXAction on that Type. Try to replace
public PXAction<APPayment> Test;
with
public PXAction<PrintChecksFilter> Test;
I have certain pages that I want accessible only to users that are accessing the site from within a given IP range. For all other users, these pages should be inaccessible, and their respective links not visible in the menu/navigation.
I'm new to OrchardCMS, can someone provide some general guidance and point me in the right direction?
There two aspects to answer your question.
1. To check access to orchard content items and menu item relative to it:
To achieve this, you can implement new IAuthorizationServiceEventHandler to replace the default roles based authorization service, the best sample for you is ContentMenuItemAuthorizationEventHandler which you can find under Orchard.ContentPicker module, I included a sample code to explain the usage of this handler:
public class CustomAuthorizationEventHandler :
IAuthorizationServiceEventHandler{
public ContentMenuItemAuthorizationEventHandler() {
}
public void Checking(CheckAccessContext context) { }
public void Adjust(CheckAccessContext context) {
//Here you can put your business to grant user or not
context.Granted = true; //Roles service will look to this value to grant access to the user
context.Adjusted = true;
}
public void Complete(CheckAccessContext context) {}
}
2. To check access to some actions.
To achieve this, you can implement new IAuthorizationFilter to check access to some actions in your system:
public class CustomAuthorizationFilter : FilterProvider, IAuthorizationFilter {
public void OnAuthorization(AuthorizationContext filterContext) {
if (!Granted) {
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
The solutions mentioned by #mdameer are ok, but you will run into difficulties when using containers, lists, projections and stuff.
I had a similar task but with date time ranges. See my question and answer to the task to get an idea how to tackle this via a custom part:
How to skip displaying a content item in Orchard CMS?