Article by Andrei Matys, Software Engineer at ACBaltica.
This is the first article in a series of technical notes that will be published on the ACBaltica website. In it, Andrei Matys, a software engineer in the development department of the CX direction of our company, will tell general information about MDRs in SAP Cloud Application Studio.
In this article, I would like to tell you about mass data runs (MDRs) in SAP Sales/Service Cloud.
MDR provides functionality for periodical background data processing. For example: periodical customer analyzing, periodical sending of data to external systems or just updating a huge amount of data. In simple cases, we can use workflows instead of MDRs, but in complex cases we can’t do like this.
Main elements of MDR are business object with query and action and MDR. Query is used for retrieving data from database. Action contains business logic to be executed. This information is shown in picture 1.
Picture 1 – General structure
Sequence of steps is shown in picture 2.
Picture 2 – Steps of MDR run
To start MDR we need to create MDR run and schedule it. At the right time MDR run starts and executes query on business object. Action is executed on the returned data amount. After processing of data MDR run finishes.
In SAP Cloud Application, you can create two types of action:
mass enabled – process N records per execution;
not mass enabled – process 1 record per execution.
An example of mass enabled processing data script:
import ABSL;
// Iterate through records
foreach(var i in this) {
// Do something you want
}
An example of not mass enabled processing data script:
import ABSL;
// Type codes
var EMAIL = "39";
// Row with TypeCode is just an example
if(this.TypeCode == EMAIL){
// Do something you want with the current record
}
What type of action should we use in MDR? Let’s figure it out.
Example: we want to send notifications (standard system notifications or emails) from ABSL periodically. We can create a business object, which will store all information about notifications and also will contain action, which will be used for sending notifications.
Business object:
businessobject NotificationStore {
[AlternativeKey] element NotificationUUID : UUID;
element SourceUUID : UUID;
element SourceName : LANGUAGEINDEPENDENT_ENCRYPTED_EXTENDED_Name;
element SourceType: BusinessTransactionDocumentTypeCode;
element RecipientUUID : UUID;
element RecipientName : LANGUAGEINDEPENDENT_ENCRYPTED_LONG_Name;
element RecipientType: RecipientTypeCode;
element Status : StatusCode; // custom codelist
element ChannelType : ChannelTypeCode; // custom codelist
element CreationDateTime: GLOBAL_DateTime;
element SendDateTime: GLOBAL_DateTime;
action SendNotifications;
}
Action SendNotifications:
import AP.Common.GDT as apCommonGDT;
// Channel type
var EMAIL = "01";
var NOTIFICATION = "02";
// Filter notifications
var notifications = this.Where(n => n.ChannelType == NOTIFICATION);
var emails = this.Where(n => n.ChannelType == EMAIL);
// Send notifications
foreach(var oneNotification in notifications){
// Do something
}
// Send emails
foreach(var oneEmail in emails){
// Do something
}
MDR settings will look like in picture 3.
Picture 3 – MDR settings
All these settings will work as in picture 4.
Picture 4 – Scheme for mass enabled action
Mass enabled action is very useful in case if our business object stores data, which we can process per one script execution. For example, select all notifications and send them according to a channel type. Action will receive all rows and process them.
What about cases, when can we use not mass enabled script? One new condition should be added to the task of the previous example: we want to separate business logic and persistence. The solution for this is adding new business object to the existing one:
businessobject Sender {
[AlternativeKey] element SenderType : SenderTypeCode; // custom codelist
action SendEmails;
action SendStandartNotifications;
action Run;
}
Action SendStandartNotifications:
import AP.Common.GDT as apCommonGDT;
// Channel type
var EMAIL = "01";
var NOTIFICATION = "02";
// Notification status
var NOT_PROCESSED = "00";
// Get notifications using query
var queryNotifications = NotificationStore.QueryByElements; // Use standard query for example
var selParamsNotifications = queryNotifications.CreateSelectionParams();
// Add selection parameters (if needed)
selParamsNotifications.Add(queryNotifications.ChannelType, "E", "EQ", NOTIFICATION);
selParamsNotifications.Add(queryNotifications.Status, "E", "EQ", NOT_PROCESSED);
var resultNotifications = queryNotifications.Execute(selParamsNotifications);
// Send notifications
foreach(var oneNotification in resultNotifications){
// Do something
}
Action Run will look like:
import ABSL;
var EMAILS_SENDER = "001";
var NOTIFICATIONS_SENDER = "002";
switch(this.SenderType){
case EMAILS_SENDER {
this.SendEmails();
}
case NOTIFICATIONS_SENDER {
this.SendNotifications();
}
}
MDR settings will look like in picture 5.
Picture 5 – MDR settings
Scheme for the not mass enabled action in this case will look like in picture 6.
Picture 6 – Scheme for not mass enabled action
So, we looked through two main ways of creating MDRs.
1. Business object + data + action (mass enabled).
2. Business object + data and Sender + action (not mass enabled).
Also exist:
3. Business object + data + action (not mass enabled). Action will be called for every row. In script we don’t need to have cycle through this.
4. Business object + data and Sender business object + action (mass enabled).
5. In the main (Run) action we should add iteration through this.
Main ideas of using not mass enabled action and some additional object are:
- Separation of logic and persistence (BO for business logic, BO for saving data);
- Impossibility of dynamic argument usage in MDR run;
- Standard BO, where we can’t add custom action (example, Account);
- Complex selection logic and etc.
Important: rows in DB should exist for action execution. It means that for sender BO you should create rows manually (using WS or UI).
In the end, let’s sum up theoretical information:
- MDR provides functionality for periodical background data processing;
- Main elements: BO (action and query required), MDR;
- For scheduling MDR you should create and schedule run;
- Mass data run executes query, to get data from business object, query returns data and action on these data is executed.
- Additional object is not obligatory.
P.S
If you need to do a lot of different general tasks in background you can create multifunctional business object:
import AP.Common.GDT as apCommonGDT;
businessobject MultifunctionalBO raises MsgInfo_EN {
message MsgInfo_EN text "Message: &1": LANGUAGEINDEPENDENT_EXTENDED_Text;
[Label("Type")] element Action : MDRActionCode;
action Run;
action ActionOne; // Action name is an example
action ActionTwo; // Action name is an example
}
And action Run will start needed scripts.
We designed this service to help you leverage all the benefits of SAP CRM on-premise - even if the software isn't supported by the vendor anymore. The service ensures that your system remains viable and stable and enables consistent performance of your CRM solution. We also help you cover security risks, perform bug fixes, and overcome the challenges caused by limited support from the vendor. We'll also help you integrate your on-prem CRM with new systems and applications (SAP and non-SAP, including those in the cloud). And there's even more: with this service, you ensure your system can evolve to meet the new challenges of an ever-changing business landscape and suit your unique needs.