Это первая статья из серии технических заметок, которые будут опубликованы на сайте AtlantConsult. В нем Андрей Матыс, инженер-программист отдела разработки направления CX нашей компании, расскажет общую информацию об MDR в SAP Cloud
В этой статье я бы хотел рассказать про создание массовых прогонов данных (MDRs) в SAP Sales/Service Cloud. Для именования технических элементов будем использовать английский язык.
Массовые прогоны данных предназначены для периодической фоновой обработки данных. Например, анализ данных по клиентам, отправка данных во внешние системы по расписанию, обновления большого объема данных согласно некоторым условиям. В простых случаях возможно использовать правила потоков операции (workflow) вместо фоновых прогонов, но мы не сможем сделать так в сложных ситуациях.
Элементы, необходимые для фонового прогона: бизнес-объект (BO) с выборкой (query) и действием (action). Под действием понимается функция в бизнес-объекте. Выборка используется для извлечения записей из базы данных. Действие содержит бизнес-логику для выполнения. Эта информация представлена на рисунке 1.
Рисунок 1 – Общая структура
Последовательность шагов представлена на рисунке 2.
Рисунок 2 – Шаги прогона (MDR run)
Для того чтобы запустить MDR необходимо создать прогон (MDR run) и запланировать его. Прогон запустится в запланированное время и совершит ряд действий: выполнит выборку записей по бизнес-объекту из БД, а затем вызовет действие на отобранных записях. После выполнения действия и сохранения данных прогон завершит свою работу.
Используя SAP Cloud Application, есть возможность создать два тип действия:
- массовая обработка (mass enabled) – для обработки N записей за одно выполнение;
- не массовая обработка (not mass enabled) – обработка 1 записи за одно выполнение.
Приведем пример скрипта с массовой обработкой данных:
import ABSL;
// Iterate through records
foreach(var i in this) {
// Do something you want
}
Пример скрипта не с массовой обработкой данных:
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
}
Какой из типов действий следует использовать? Давайте разберемся.
Рассмотрим пример: периодическая отправка стандартных уведомлений (notifications) или электронных писем (emails) используя ABSL. Создадим бизнес-объект, который будет хранить в себе всю информацию о уведомлениях (в том числе и о электронных письмах). Данный объект также имеет действие, которое предназначено для отправки уведомлений.
Бизнес-объект:
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;
}
Действие 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
}
Настройки фонового прогона представлены на рисунке 3.
Рисунок 3 – Настройки фонового прогона
Взаимодействие всех элементов, которые были описаны выше, можно представить схематически (рисунок 4).
Рисунок 4 – Схема взаимодействия с использованием скрипта с массовой обработкой
Действие с массовой обработкой очень полезно, когда бизнес-объект хранит непосредственно данные, которые должны быть отобраны обработаны. Например, отобрать все неотправленные уведомления и отправить их в соответствии с каналом.
Разберем возможные ситуации, когда можно использовать действие не с массовой обработкой. Вернемся к предыдущему примеру и добавим дополнительное условие: разделить бизнес-логику и хранение данных. В данном случае нам потребуется один дополнительный объект:
businessobject Sender {
[AlternativeKey] element SenderType : SenderTypeCode; // custom codelist
action SendEmails;
action SendStandartNotifications;
action Run;
}
Действие 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
}
Действие Run:
import ABSL;
var EMAILS_SENDER = "001";
var NOTIFICATIONS_SENDER = "002";
switch(this.SenderType){
case EMAILS_SENDER {
this.SendEmails();
}
case NOTIFICATIONS_SENDER {
this.SendNotifications();
}
}
Настройки фонового прогона будут выглядеть как на рисунке 5.
Рисунок 5 – Настройки фонового прогона
Схема взаимодействия всех элементов с использованием действия с не массовой обработкой данных представлена на рисунке 6.
Рисунок 6 – Схема взаимодействия с использованием скрипта с не массовой обработкой
Мы рассмотрели два способа создания фоновых прогонов.
1. Бизнес-объект + данные + действие (массовая обработка);
2. Бизнес-объект + данные и промежуточный объект (отправитель) + действие (не с массовой обработкой).
Также возможны варианты:
3. Бизнес-объект + данные + действие (не с массовой обработкой). Действие будет вызываться для каждой строки отдельно. Цикл в скрипте больше не нужен.
4. Бизнес-объект + данные и промежуточный объект + действие (массовая обработка). В главном действии нужно добавить цикл по this.
Зачем использовать действия с не массовой обработкой:
- Разделение логики и хранения данных (отдельные объекты для логики и хранения данных);
- Необходимы динамические параметры в выборке;
- Стандартный объект, который нельзя расширить на действие (например, Account);
- Сложная логика выбора данных из объекта и др.
Важно: для выполнения действия строки в БД должны существовать. Это означает, что для промежуточного бизнес-объекта необходимо добавить строки в БД вручную (использую веб-сервис или пользовательский интерфейс).
Подытожим все вышесказанное:
- Фоновые прогоны позволяют периодически обрабатывать достаточно большие объемы данных;
- Составляющие: бизнес-объект (действие и выборка обязательны), фоновый прогон данных (MDR);
- Для запуска фонового прогона необходимо создать сущность прогона и запланировать её;
- Общая логика работы: запуск, выполнение выборки, выполнение действия на возвращенных данных;
- Промежуточный объект не является обязательным.
P.S
Если Вам необходим мультифункциональный «комбайн» для выполнения различных технических работ, можно использовать следующий шаблон:
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
}
Действие Run будет стартовать необходимые скрипты в зависимости от поля типа Action.