We often come across scenarios when we need to create an MDR which needs to be executed via some action or event.
We will not go through entire MDR creation , since there are many blogs out there! 😉
However before going through the technicalites of the topic I would give you a brief on Use case and why we needed this.
Use Case :
Our scenario include Opportunities , So we have scenario like Main Opportunities and Child Opportunities and we have an action in our system which creates this kind of child opportunities.
After the child opportunites are created then Routing Matrix gets triggered and determines the parties which needs to work on those child opportunities. ( Define Rules for Opportunity parties )
So as you can see based on multiple criterias the parties are getting determined. Now in some case none of this conditions are met and the opportunity is “Unassigned” but how would we know that oppi is unassinged!! Because routing matrix is called after saving , so before save code wont help!
so what to do!?
So ideally one cas use normal WF rules on created on and trigger the action to check! This will work just fine but sometimes System is still processing routing and the WF rules gets failed ( of course we can rerun it ) but we wanted a fallback job which checks if this child opportunity which got created is unassigned or not!
So as we know we have to create a customBO for our MDR since we cant create MDR on standard object ( Which is a limitiation but thats how system is designed )
A. Create a MDR
- Create a Bo and MDR and its screens.
- Create a query.
- Create and define Action.
- Workcenter View assignments
for details check : https://blogs.sap.com/2016/05/17/how-to-schedule-a-batch-job-using-mdr-in-c4c/
B. Call this MDR via ABSL
There is a import file import AP.PlatinumEngineering; which is designed for this!
Note : platinumengineering will not recieve 24/7 support and you can raise only in medium prio ticket if something goes wrong! 🙁 yeah but thats how it is!
- Call the method from required event , in my case it is CreateChildOppi action which gets triggered from a butyton and then BeforeSave of Opport-Root (for child opportunities)
- Created a method to Create MDR
- Schedule-Start the MDR which in turn will call the action created in A.3.
B.1 Call the method with correct ID sequence createchild(buttton), beforesave
CreateChild method ( of course there is more code in this method but for this blog this is relavent)
var OppMaint : elementsof OppAssignMaint; OppMaint.OpportId = Opp.ID; var OppMaintBO : OppAssignMaint = OppAssignMaint.Create(OppMaint);
OppAssignMaint is my custom BO , which is filled with ID from action
var OppMaint = OppAssignMaint.Retrieve(this.ID); OppMaint.checkAssignmentStart();
B.2 : Create MDR Action ( checkAssignmentStart)
import ABSL; import AP.PlatinumEngineering; var MDRO_ID : XPEString; var QueryParam : QueryParameter; var ParameterName : QueryParameter.ParameterName; var MDRName = "BGJAssignment"; // This is the name of my MDR var MDRNamespace = ""; MDRO_ID.Clear(); MDRO_ID = this.GetFirst().OpportId.content; // This should be the ID for the run var mdrCreateInstanceResult = MDRO.CreateInstance( MDRName, MDRNamespace, MDRO_ID); QueryParam.ParameterName = "SelectByOpportId"; //MyQuery QueryParam.Sign = "I"; QueryParam.Option = "EQ"; QueryParam.Low = this.GetFirst().OpportId.content; var mdrAddParameterResult = MDRO.AddSelectionParameter(MDRName,MDRNamespace,"SelectByOpportId",MDRO_ID,QueryParam); MDRO.Activate(MDRName,MDRNamespace,MDRO_ID); this.checkAssignmentSchedule();
So break it down : BGJAssignment is my MDR name in PDI
SelectByOpportId because OpportId is my query parameter
B.3 Schedule the MDR after few mins or seconds based on your requirments
import ABSL; import AP.PlatinumEngineering; var QueryParam : QueryParameter; var MDRO_ID : XPEString; var MDRName = "BGJAssignment"; var MDRNamespace = ""; var MessageList : MessageList; var MessageText : MessageType.Text.content; MDRO_ID.Clear(); MDRO_ID = this.GetFirst().OpportId.content; var currentTime = Context.GetCurrentGlobalDateTime(); var min = 2; var sec = 0; var StartDuration = Library::Duration.Create ( 0, 0, 0, 0, min, sec ); // 5 sec var startTime = currentTime.AddDuration (StartDuration); MessageList = MDRO.ExecuteDateTime(MDRName,MDRNamespace,startTime,MDRO_ID); MessageText = MessageList.MessageTypeItem.GetFirst().Text.content;
B.4 Check in your MDR screen if it worked or not 😉
This is it folks, I think this is pretty cool if you want a baground job to work for related items or something! plus its in background so “Hopefully” performance will not hit on front end.
Please go through below blogs for more info :
Thank you so much if you have read till this 😀 and have a nice day!