I think this is probably just something stupid, but I'm trying to add a custom menu to the Customer form. I've used this code:
public override void Initialize()
{
base.Initialize();
this.SpeedyActions.AddMenuAction(BtnCreateMenu1);
this.SpeedyActions.AddMenuAction(BtnCreateMenu2);
}
public PXAction<PX.Objects.AR.Customer> BtnCreateMenu1;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Menu Item 1")]
protected void btnCreateMenu1()
{
// Logic
}
public PXAction<PX.Objects.AR.Customer> BtnCreateMenu2;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Menu Item 2")]
protected void btnCreateMenu2()
{
// Logic
}
public PXAction<PX.Objects.AR.Customer> SpeedyActions;
[PXButton(SpecialType = PXSpecialButtonType.Report, MenuAutoOpen =true)]
[PXUIField(DisplayName = "Speedy Actions")]
protected void speedyActions()
{
//code logic here
}
I've got basically the same code on the sales order form and it works perfectly. I suspect that I'm maybe using the wrong code here PX.Objects.AR.Customer and I've also tried CR.BAccount, but can't seem to make it work. Anyone have some thoughts?
I would try
Base.report.AddMenuAction(BtnCreateMenu1)
Related
I'm trying to override the Cancel Order button in Purchase Order screen, but I didn't found the Acumatica existing source code in POOrderEntry.
Can anyone help me on this. Thanks in advance.
Technically you can do the following:
public class POOrderEntryExt : PXGraphExtension<POOrderEntry>
{
public MyCancelButton<POOrder> Cancel;
}
public sealed class MyCancelButton<TNode> : PXCancel<TNode> where TNode : class, IBqlTable, new()
{
public MyCancelButton(PXGraph graph, string name) : base(graph, name)
{
}
public MyCancelButton(PXGraph graph, Delegate handler) : base(graph, handler)
{
}
[PXUIField(DisplayName = "Cancel", MapEnableRights = PXCacheRights.Select)]
[PXCancelButton]
protected override IEnumerable Handler(PXAdapter adapter)
{
//DO SOME STAFF HERE
throw new PXException("Very bad idea");
return base.Handler(adapter);
}
}
But I DON'T RECOMMEND you doing that because the "Cancel" action is doing a lot of very important staff and messing it up is pretty easy.
I recommend considering other ways to do what you want to do. May be to place the logic in the Persisting or Verifying handlers.
I have been trying to add custom DAC record which is the in database. But it is now working. Here is how I have tried to accomplish.
public class SquarePOSTransactionInquiry : PXGraph<SquarePOSTransactionInquiry>
{
public PXSave<MasterTable> Save;
public PXCancel<MasterTable> Cancel;
public PXFilter<MasterTable> MasterView;
public PXSelect<INSquarePOSTransaction> INSquarePOSTransactions;
public PXAction<MasterTable> calc;
[PXUIField(DisplayName = "Sync Square Transactions")]
[PXProcessButton()]
protected virtual IEnumerable Calc(PXAdapter adapter)
{
PXLongOperation.StartOperation(this, () =>
{
using (var scope = new PXTransactionScope())
{
INSquarePOSTransaction trans = new INSquarePOSTransaction();
trans.TransacationCD = "new";
trans.Description = "Another new";
var test = this.INSquarePOSTransactions.Insert(trans);
this.INSquarePOSTransactions.Cache.IsDirty = true;
//this.INSquarePOSTransactions.Update(trans);
this.Actions.PressSave();
scope.Complete();
}
});
return adapter.Get();
}
public SquarePOSTransactionInquiry()
{
}
[Serializable]
public class MasterTable : IBqlTable
{
}
}
I tried setting cache IsDirty property to false, but that didn't help too. But the strange part is updating the DAC is working. I have even looked into other Business Logic codes from other pages and it looks same like I have tried above. Could you please tell me what I am missing?
Thanks.
Within the method that you pass to StartOperation(),
you have to create a new instance of the graph and invoke the processing method on that instance.
I want to execute some code (to change the shipment date) upon the 'Confirm Shipment' action on the Shipments screen (SO302000).
I was thinking that this would be the way to do it:
public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
[PXOverride]
public virtual void ConfirmShipment(SOOrderEntry docgraph, SOShipment shiporder)
{
Base.ConfirmShipment(docgraph, shiporder);
//Add my code to do something here...
}
}
When I try this, I get a shipment counter error. Is there a better way to do this?
From a similar case:
How to add custom business logic to Acumatica framework's Actions?
public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
public PXAction<SOShipment> action;
[PXButton]
[PXUIField(DisplayName = "Actions", MapEnableRights = PXCacheRights.Select)]
protected IEnumerable Action(PXAdapter adapter
,[PXIntList(new int[] { 1 }
,new string[] { "Confirm Shipment" })
,PXInt] int? actionID)
{
//actionID = 1 means the Confirm Shipment action was the one invoked
if (actionID == 1)
{
Base.Document.Current.ShipDate = Base.Accessinfo.BusinessDate;
Base.Document.Update(Base.Document.Current);
}
//calls the basic action that was invoked
return Base.action.Press(adapter);
}
}
When I do a custom logic before the APPROVE in requisition screen, it seems like the logic is triggered after. My code is as below.
public PXAction<RQRequisition> action;
[PXUIField(DisplayName = "Actions")]
[PXButton]
protected virtual IEnumerable Action(PXAdapter adapter,
[PXInt][PXIntList(new int[] { 1, 2 }, new string[] { "Approve", "Reject" })] int? actionID,
[PXBool]bool refresh,
[PXString]string actionName)
{
if (adapter.Menu == "Approve")
{
SIApprovalInfo.updateNextApprover(this.Base);
}
return Base.action.Press(adapter);
}
and I tried this action without calling the return Base.action.Press(adapter);
Sample code:
public PXAction<RQRequisition> action;
[PXUIField(DisplayName = "Actions")]
[PXButton]
protected virtual IEnumerable Action(PXAdapter adapter,
[PXInt][PXIntList(new int[] { 1, 2 }, new string[] { "Approve", "Reject" })]int? actionID,
[PXBool]bool refresh,
[PXString]string actionName)
{
if (adapter.Menu == "Approve")
{
SIApprovalInfo.updateNextApprover(this.Base);
}
return adapter.Get();
}
Still the document is getting approved somehow. So where exactly is this approval getting triggered? How can I add my custom logic before that action?
I suggest a workaround which would be the create your own action, add it to the menu and depending on your business logic, call the Approval. Here is the basic snippet you could use :
using PX.Data;
using System.Collections;
namespace PX.Objects.RQ
{
public class RQRequisitionEntry_Extension : PXGraphExtension<RQRequisitionEntry>
{
public override void Initialize()
{
Base.action.AddMenuAction(CustomApprove);
CustomApprove.SetEnabled(true);
}
public PXAction<RQRequisition> CustomApprove;
[PXButton]
[PXUIField(DisplayName = "Custom Approve")]
protected virtual IEnumerable customApprove(PXAdapter adapter)
{
PXCache cache = Base.Caches[typeof(RQRequisition)];
var requisition = Base.Document.Current;
if (Base.Approval.Approve(requisition))
{
requisition.Approved = true;
yield return Base.Document.Update(requisition); ;
}
else
{
throw new PXInvalidOperationException(PXLocalizer.Localize("Approval failed"));
}
}
}
}
I have to copy the custom field values from opportunity to sales order while converting the opportunity to sales order.
I have come across a sample code to pass custom field from sales order to shipment and I have tried to use the code for overriding the “create sales order” action.
The following code snippet I have used in OpportunityMaint extension class
public PXAction action;
[PXButton]
[PXUIField(DisplayName="Actions",MapEnableRights=PXCacheRights.Select,MapViewRights=PXCacheRights.Select)]
protected IEnumerable Action( PXAdapter adapter,
[PXIntList(new int[] {1,2,3}, new string[] {"Create Account","Create Sales order","Create Invoice"}),PXInt]
int? actionId,
[PXString]
string ActionName)
{
if(actionId == 2)
{
// Implement So Order row insert handler
}
return Base.Action.Press(adapter);
}
The piece of code is not triggering.
Looking forward for better solution to implement this option
Regards,
R.Muralidharan
You will need to override the CreateSalesOrder action. Below is a snippet of code where I had to push the opportunity down to the sales order.
public class OpportunityMaint_Extension : PXGraphExtension<OpportunityMaint>
{
public PXAction<CROpportunity> createSalesOrder;
[PXUIField(DisplayName = Messages.CreateSalesOrder, MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
public virtual IEnumerable CreateSalesOrder(PXAdapter adapter)
{
PXGraph.InstanceCreated.AddHandler<SOOrderEntry>((graph) =>
{
graph.RowInserted.AddHandler<SOOrder>((cache, args) =>
{
var soOrder = (SOOrder)args.Row;
var soOrderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(soOrder);
foreach (CROpportunity opportunity in adapter.Get())
{
soOrderExt.UsrOpportunityID = opportunity.OpportunityID;
}
});
});
return Base.createSalesOrder.Press(adapter);
}
}