Что такое SAP PaPM? SAP Profitability and Performance Management – это инструмент для расчетов на базе SAP HANA, можно сказать инструмент для создания “считалища”. Типичным примером таких расчетов является дифференциация затрат, когда имеется модель учета затрат, состоящая из сотен, а может и тысяч объектов учета, десятки или сотни тысяч документов на входе и десятки или сотни продуктов на выходе. Задача показать какие элементы затрат или аналитики первичных документов попали в конечный продукт после множества циклов перерасчетов между объектами учета.

Решение данной задачи будет нужно налоговикам, для вычисления налоговой стоимости продукта, так как налоговая стоимость первичных затрат отличается от бухгалтерской. Экономисты смогут подробно проанализировать состав затрат на продукт. В отчетности можно исключить внутригрупповые обороты, понимая какие затраты от компаний группы попали в продукт.
Для решения этой задачи нужно протянуть аналитику первичных затрат по всей цепочке перерасчетов. Объем данных в результате расчетов может составлять десятки или сотни миллионов позиций. Стандартный функционал учетной системы этим не занимается, а если и занимается, то с ограничениями и сильным влиянием на производительность. Как быть?
Часто на ERP-проектах помимо транзакционной системы есть еще и аналитическая система и когда появляется задача с выполнением сложных вычислений над большим объемом данных возникает вопрос: “Где считать?”. Если побеждает или проигрывает (тут с какой стороны посмотреть) ERP, то с использованием ABAP создают сложные программы для расчетов, которые очень нестабильно работают и с которыми постоянно возникают проблемы. Если используется BW, то примерно такая же ситуация, в Expert Routine вставляется код для расчетов и это плохо работает. Я несколько раз слышал: “Ну вот, сломали BW, из хранилища сделали считалище…”. Понятно, что есть истории успеха (success story) и найдутся счастливые разработчики и пользователи прекрасной системы, которая хорошо работает, но что-то мне такие не попадались (понимаю, это моя проблема).
Возвращаясь к вариантам решения задачи и к теме “считалища”, можно посмотреть на SAP PaPM (SAP Profitability and Performance Management). Это инструмент для выполнения расчетов над бизнес-данными с использованием настраиваемых цепочек функций. Так как под функции генерируются хранимые процедуры БД SAP HANA и вычисления происходят на уровне базы данных, а потоки данных можно распараллелить и пакетировать, обработка большого объема данных происходит достаточно быстро.
PaPM предоставляет возможность быстро создавать модель данных за счет предопределенных типов функций, способен извлекать и агрегировать данные из различных систем и локальной или удаленных баз данных, выполнять различные сложные вычисления над детальными данными и записывать результаты в другие приложения для дальнейшей обработки. PaPM позволяет:
Управлять конфигурациями функций, с помощью которых консультанты (в логике SAP даже бизнес-пользователи) создают подробные модели расчетов и распределений без сложного кодирования.
Обрабатывать данные почти в реальном времени из физических или виртуальных источников как в локальной базе данных, так и через удаленное подключение к другим базам данных (см. SDA) без необходимости физической репликации/сохранения исходных данных.
Обеспечивать полную прозрачность методологии распределения и результатов расчетов вплоть до уровня отдельных позиций.
Запускать модели с гибко определенными параметрами моделирования для анализа “что, если”.
Переносить результаты расчета/распределения обратно в другие приложения – в главную книгу в S/4HANA, в хранилища данных планирования в SAP BPC, в объекты BW4HANA и т.д.
Пример итеративного распределения затрат по базе
Новый функционал лучше изучать на конкретном примере. Для навигации по статьям и понимания как работает PaPM придумал себе пример и реализовал его в своей системе. Ниже дано описание логики процесса расчета и ссылки на статьи, в которых более подробно описываются используемые (и не только используемые) функции. Также можно скачать транспортный запрос в котором сохранена среда с функциями и тестовыми данными, которые я использовал в примере.

Важные моменты примера:
Часть затрат возвращается на объекты-отправители (например, котельная дала горячую воду и пар ремонтному цеху, а он, помимо прочего, отремонтировал что-то в котельной). То есть имеем итерации распределения затрат.
При распределении нужно учесть, что для конкретных объектов-отправителей, есть набор объектов-получателей. То есть нужно предварительно сформировать наборы объектов-получателей, по которым распределять затраты. В нашем случае объекты-отправители тоже выступают в качестве получателей затрат, но не для всех отравителей действительны все получатели.
Нужно обрабатывать наборы объектов из п. 2, для этого нужен цикл.
Входные данные:

Тут и базы (определяются 38* счетами) и сами затраты для распределения (не 38* счета).
Структура цепочки функций в PaPM

Контейнер 1 – Необогащенные данные
1. Все входные данные находятся в одном файле на сервере приложения, файл загружается функцией Файловый адаптер.

Можно, конечно, положить данные в таблицу сторонней БД и настроить SDA для виртуализации данных и полного отсутствия репликации. Но пока так.
Описание работы функции в статье Файловый адаптер (File Adapter с типом Import).
2. Из загруженных данных нужно:
Выбрать записи затрат (не 38* счета).
Получить список уникальных объектов-отправителей в этих затратах и пронумеровать их. Для объектов-отправителей далее будут подобраны объекты-получатели.
Пронумеровать записи затрат для того, чтобы далее, при распределении в цикле, по номеру цикла выбирать записи затрат и соответствующие затратам наборы объектов-получателей.
2.1. Отфильтровали записи затрат и дополнительно переложили значения объектов затрат в другое поле, так как потом, при формировании пар отправитель-получатель, PaPM запутается в двух полях, которые называются одинаково, но используются по-разному.


Используем функцию Структура переноса. Описание работы функции в статье Структура переноса (Transfer Structure).
2.2. Выбрали уникальные объекты затрат.

Используем функцию Представление для группирования (GROUP BY) и нумерации с помощью ROW_NUMBER(). Описание работы функции в статье Представление (View) в PaPM.
2.3. Пронумеровали записи затрат уникальными номерами, чтобы далее в функции распределения выбирать записи затрат и соответствующие наборы отправитель-получатель.

Используем функцию Соединение и два правила, соединенные Left Outer Join.

Получили нумерацию затрат уникальными номерами объектов. Результат работы функции сохраняется в Таблице модели. Описание работы функции в статье Соединение (Join) в PaPM.
Контейнер 2 – Обогащение данных
3. Необходимо к объекту учета затрат подобрать объекты-получатели. Во входных данных есть пары отправитель-получатель для баз распределения. На основе этих данных для каждого уникального объекта затрат, используя функцию Соединение и два правила, соединенные Inner Join, получаем набор баз для распределения:


Описание работы функции в статье Соединение (Join) в PaPM.
Контейнер 3 – Распределение
4. Теперь нужно суммы затрат распределить пропорционально базе для объекта затрат и сохранить первичную аналитику в распределенных данных. Все это нужно сделать в цикле выбирая для каждого повторения по его номеру строку затрат и соответствующий набор баз. Для организации цикла используется функция Представление

которая вызывает функцию Программа записи (это обязательное условие, с другими типами функций это не работает)

которая в свою очередь вызывает функцию Аллокация и записывает результат в Таблицу модели:

Для организации итерации используется смещение, которое объект-получатель, перекладывает в объект-отправитель в распределенных данных

и цикл повторяется. Для того, чтобы это работало только когда было обратное распределение затрат на объекты-отправители, значения объектов-отправителей после смещения сравниваются с оригинальным значениями объектов в затратах (CASE WHEN ZRCNTR_SEND = ZRCNTR_ORIG THEN HSL ELSE 0 END).
Получаем желаемый результат:

Описание работы функции в статье Распределение (Allocation) в PaPM.
Важно отметить, что PaPM обладает механизмом разделения объема данных по потокам и пакетам. То есть возможно параллельное выполнение расчетов, что значительно сокращает время их выполнения (см. Приложения PaPM: Администрирование и Моделирование).
Контейнер 4 – Проверка
5. Для проверки правильности распределения агрегируем результат по номеру документа, для сравнения с данными на входе. Используем функцию Представление с группировкой и функцией SUM()


или так, если добавить объект-получатель:

В качестве заключения
Наверное, в определенных ситуациях, когда алгоритмы расчетов стабильны и из раза в раз выполняется один и тот же код, собственная разработка на SQL будет проще, быстрее и дешевле чем PaPM. Но если требуется именно моделирование, когда алгоритмы расчетов меняются и необходимо гибко управлять логикой расчетов, то без инструмента управления элементами расчетов (хранимыми процедурами), последовательностью их выполнения, организации запусков, контроля хода выполнения и обработки результатов не обойтись. Создавать это самостоятельно - трата сил, времени и денег, в то время как уже есть SAP PaPM.