В книжках давно и часто говорят, что ERP-системы должны быть онлайновыми — то есть, отражать состояние бизнеса в режиме «сейчас» или даже немного прогнозировать будущее; то же самое говорят и про управленческий учет.
По факту же ERP во многом остаются системами «посмертного» учета, как и обычные бухгалтерские программмы, и, пока учетный документ не будет проведен, система не покажет эту хоз. операцию менеджерам.
В этой статье я хочу обсудить, как решать одну из таких проблем в общем виде — так, чтобы любая информация об операции отражались в ERP-системе как только о ней становится хоть что-то известно предприятию.
Что нужно бизнесу. Пример 1
Рассмотрим некий тип операций: например, закупки. Каждая закупка проходит минимум три этапа информации о себе, которые фиксируются разными документами:
- заявка на закупку, поданная сотрудником руководству компании;
- заказ поставщику;
- документ о получении товара от поставщика (рис. 1).
Рис. 1. Последовательность документов о закупке
Если мы строим отчеты за прошлый год — понятно, что в них нужно учитывать только фактические закупки (по данным документов «Поступление товара»).
Но когда мы строим оперативные отчеты (которые строятся за «сегодня», за «завтра», за текущую неделю/месяц, которые еще не завершились), нельзя дожидаться, пока в систему будут введены фактические поступления. Наряду с ними, нужно учитывать и заказанные, и заявленные закупки.
Рис. 2. Правила среза данных о закупках в отчетах и аналитике
Отчет должен принять во внимание каждую из закупок по самым свежим данным, известным о ней.
Это касается как отчетов, так и любых расчетов (аналитики).
Например, при попытке создать новую заявку, нужно проверять доступные остатки лимитов закупок по статье:Брать последнюю информацию особенно важно, поскольку данные об одной и той же операции в разных документах могут различаться.
Доступный остаток = Лимит на месяц — Сумма закупок за месяц
И здесь сумма закупок должна включать: фактически прошедшие поступления товаров; поступления, ожидаемые по заказам; заявки на закупку (как минимум, утвержденные) на данный месяц.
Это нормально: например, в заявке на закупку может предполагаться одна дата поступления товара, в заказе поставщику она может совпадать с заявочной, а фактическое поступление — пройти в другой день.
Это обеспечит плавность, так что ни в один момент времени в аналитику не будет попадать два разных документа по одной операции; и не возникнет ситуации, когда операция не попадает в отчет, хотя о ней есть хотя бы какая-то информация в системе.
Пример 2 (посложнее)
Рассмотрим более сложный пример из другой сферы: управление платежами. Здесь точно так же используется три документа:
- заявка на оплату (поданная руководству компании одним из подразделений);
- платежное поручение (поданный компанией в банк «заказ» списать денежные средства с расчетного счета);
- банковская выписка (отчетный документ от банка о фактически проведенном платеже).
Но информация об одном и том же платеже в компании проходит семь этапов, на каждом из которых отдельные реквизиты платежа могут уточняться и изменяться.
Табл. 1
Вообще, в бизнесе различаться на разных этапах могут любые данные — даты платежей; банковские счета; статьи; суммы; ставки НДС; номера договоров и т.д.
И, естественно, каждый платеж также должен попадать в аналитику только по самой «свежей» информации о нем.
В каких еще сферах может встречаться эта задача?
Возможно, во всех. Как минимум:
- в производстве (где используется заказ на производство, план производства);
- в транспортной логистике (заказ на транспортировку);
- в управлении складом (расходные ордеры).
Как происходит сейчас
Обычно в ERP-системах логика ввода и хранения данных, отчетов и расчетов привязывается не к сквозному объекту учета («платеж» или «закупка»), а к отдельным документам. В результате складываются различные проблемные ситуации.
1) Отчеты и аналитика только по фактическим документам.
Утвержденные заявки и даже заказы при этом не учитываются, хотя, как мы уже рассмотрели выше, для бизнеса это необходимо.
2) Отдельные отчеты и аналитика по плановым документам (заказам, заявкам, потребностям).
В таких отчетах часто используется, в том числе, информация из тех плановых документов, которые уже исполнены. Однако, это неправильно: всю информацию из исполненной заявки, насколько это возможно, нужно замещать информацией из созданного по ней фактического документа, во всех управленческих отчетах.
3) Со временем, по мере возникновения потребности, фактические отчеты и расчеты иногда дорабатывают так, чтобы в них «попадали» еще и плановые документы. Но в них обычно не прописывают условие для плавной актуализации данных, например: [Если в выписке заполнена дата платежа — использовать её; если нет — использовать ожидаемую дату по заявке]. А значит, если в выписке пропущены какие-то отдельные поля — они не заместятся заявочными.
4) И наоборот, для решения проблемы №2 в плановые отчеты иногда искусственно добавляется уточняющая информация из фактических документов. Но эти доработки также выполняются достаточно индивидуально, без решения задачи в общем виде.
5) Информацию, полученную на этапе «звонок из банка», вписать элементарно некуда.
Для этого этапа нужно либо создавать отдельный документ, хотя с точки зрения логики бизнеса это не обосновано, либо позволять изменять уже зафиксированный документ (например, платежное поручение или даже заявку на оплату), что также неправильно: каждый документ должен хранить те данные, которые были актуальны на момент его фиксации.
Как итог, описанная задача иногда решается, но на основе заранее ограниченных вводных данных в каждом конкретном случае. В данной статье я предлагаю обсудить ее решение в общем виде.
Логика решения
Паттерн 1: все о платеже — в одну строку
Самый простой вариант решения — создать объект «платеж», всю информацию о котором записывать в строку: всё новые данные о нем просто дописываются всё правее и правее во всё новые столбцы.
Рис. 3. Продольная информация о платеже
В этом случае отчеты должны будут использовать по каждому сквозному реквизиту (дата платежа; банковский счет) сведения, которые находятся правее других. А если информации там не будет хватать — проверять все левее и левее.
Обращаю ваше внимание, что здесь я пока говорю о логике, а не о прикладной архитектуре. В зависимости от конкретной ситуации, эта таблица может как существовать в ERP-системе и постоянно обновляться по мере создания/изменения документов, так и формироваться в ходе запросов.
Плюсы этого паттерна:
- Такая таблица максимально приближена к логике бизнеса, и по ней легко проверять данные
- В отчетах можно легко фильтровать нужные версии (этапы) данных о платеже, принимая/убирая из внимания те или иные столбцы
- При такой конструкции dramatically проще анализировать расхождения между разными документами по одному платежу (поскольку сравнивать колонки одной таблицы в реляционных ERP очень несложно даже с помощью пользовательских конструкторов отчетов). Тогда как при другой архитектуре это может быть непросто
Минусы:
- Такой подход хорош только когда число этапов (версий данных об операции) заранее известно. Но если этапов много и они могут периодически добавляться, в систему придется добавлять много столбцов, и каждый раз делать это программно. А в базах данных (SQL), как мы знаем, столбцы обходятся дороже строк
Обратите внимание, что я не показал в примере разные столбцы для разных этапов согласования документа заявки. Дело в том, что этапов в маршрутах согласования в компании может быть очень много, и их количество может постоянно изменяться пользовательскими настройками. Создавать на каждый этап согласования одного документа отдельные столбцы и поддерживать их — это чересчур.
- В этом варианте система сама по себе не будет «знать», что «Дата платежа» из заявки и «Дата платежа» из выписки — с точки зрения бизнеса один и тот же реквизит платежа. Таким образом, каждый раз при добавлении каждого столбца в таблицу, код каждого отчета и расчета скорее всего придется дописывать, добавляя в него чтение и интерпретацию этого столбца.
Паттерн 2: каждый новый этап данных — новой строкой
В более универсальном виде можно сделать так: записывать каждый новый этап (версию) данных не в столбцы, а в строки. При этом id у каждого платежа будет одним и тем же по всем строкам (см. нижняя таблица на рисунке).
А на основе этой таблицы будет постоянно обновляться срез, который содержит только одну — самую актуальную — версию данных по каждому реквизиту (см. верхняя таблица).
Рис. 4. Построчная информация о платежах
По этой схеме лучше всего видно, что задача в общем виде становится очень похожей на те задачи, которые решаются при построении хранилищ данных (DWH). При этом таблицу версий можно рассматривать по смыслу близкой к таблице-сателлиту в методологии Data Vault.
Еще раз обращаю ваше внимание, что я все еще говорю о логике, а не о прикладной архитектуре. В зависимости от конкретной ситуации, обе эти таблицы могут существовать в системе постоянно, а могут рассматриваться как логическое представление сводной информации о платежах.
Плюс такой логики:
- У каждого платежа есть единая структура реквизитов. Система будет знать, что дата — это дата, а банковский счет — это банковский счет
- При этом для каждого платежа можно создавать сколько угодно новых этапов (в том числе, новых документов) — причем делать это значительно проще, чем в другой бизнес-архитектуре. Несложно сделать так, чтобы новые этапы создавались в пользовательском режиме
А вот дальнейшие плюсы и минусы будут зависеть от выбранного варианта реализации.
А теперь наконец о прикладной архитектуре
ВАРИАНТ РЕАЛИЗАЦИИ 2.1: ОБЕ ТАБЛИЦЫ ПОСТОЯННО СУЩЕСТВУЮТ В СИСТЕМЕ
Плюсы
- Максимальная скорость формирования отчетов
Минусы
- В отчетах нельзя будет задавать фильтры по версиям данных.
Делаем вывод, что такой подход хорош в случаях, когда правила получения актуального среза для разных целей в компании одинаковы.
Основная трудоемкость:
Основной задачей в этом случае является разработка механизма постоянной автоматической актуализации среза.
ВАРИАНТ РЕАЛИЗАЦИИ 2.2: ТАБЛИЦА ВЕРСИЙ ПОСТОЯННО СУЩЕСТВУЕТ, АКТУАЛЬНЫЙ СРЕЗ — НЕТ
В этом случае Таблица версий ведется и пополняется постоянно, а Актуальный срез — рассматривайте как промежуточный результат запроса, заложенного в отчетах и расчетах.
Тогда каждый отчет и расчет сможет обращаться к полной таблице версий и выбирать из нее те данные, которые ему нужны. При этом нужные фильтры по версиям можно будет настраивать в каждом отчете, и они могут различаться.
Плюсы:
- Максимальная гибкость и универсальность. Пользователь сам может фильтровать, какие версии данных по каждому платежу ему нужны в том или ином отчете.
Минусы
- Низкая скорость. Проверять полную таблицу версий при каждом формировании отчета — достаточно долго. На больших объемах данных такая архитектура может вызывать критичное падение производительности отчетов и расчетов.
Основная трудоемкость:
При этом для всех отчетов можно разработать единый механизм получения данных (правила которого должны настраиваться пользовательском режиме)
Выводы
- Мы в общем виде сформулировали задачу: необходимость работы со сквозной информацией о хоз. операции (начиная с ее предварительного прогнозирования в графиках движения активов, заявках и внутренних заказах и заканчивая фактическими документами и их дальнейшими корректировками), постоянно срезая о ней самую последнюю информацию в разрезе каждого реквизита.
- На мой взгляд, важно помнить об этой задаче и проектировать способы ее решения заранее. Решать ее лучше на этапе разработки ERP-продуктов (тиражных и заказных), а не на этапе их внедрения и сопровождения.
- Очевидно, что кроме двух приведенных подходов, могут быть другие, в том числе промежуточные и смешанные варианты решения этой задачи. Было бы интересно послушать опыт других людей и обсудить оптимальные прикладные варианты, адаптированные к разным бизнес-условиям.
- В представленной постановке видно, что задача сводится к логике и проблемам, которые встречаются в сфере Data engineering. Надеюсь, что мои публикации помогут сблизить архитекторов транзакционных (классических ERP) и аналитических (DWH) систем в понимании задач управленческого учета.
- Если в будущем найдется время, было бы неплохо опубликовать более развернутое описание проблем и решений, с учетом ввода информации на разных этапах и возможного отказа от документов в их классическом понимании в ERP.
Также с коллегами планируем реализовать MVP для иллюстрации решения в общем виде на базе различных платформ. Приглашаем присоединиться всех желающих.
Рекомендации бизнесу
По каждой операции выясните:
- отражается она только фактическим документом или также используются предварительные (заказы, заявки, графики)?
- существуют ли другие предварительные события, которые вносят уточнения в предстоящую хоз. операцию (например, звонки от поставщика с уточняющей информацией о поставке), но которые не требуют создания на них отдельного документа?
- с какой задержкой отражается фактический документ в информационной системе?
- должна ли предварительная информация об операции учитываться в отчетах и расчетах; если да — какая именно и при каких условиях?
Обсудите с вашим подрядчиком, как и какие предварительные сведения смогут отражаться в информационной системе и приниматься во внимание в отчетах и расчетах.
Рекомендации разработчикам и специалистам по внедрению
- Помните об этой проблеме всегда, когда приступаете к автоматизацию любой задачи оперативного учета и управления.
- Перед внедрением, заранее предупреждайте бизнес об этом проблеме (лучше письменно), учитывайте ее в бюджетах и оценках.
- Если связка разных этапов информации (документов и иных) по определенному сквозному виду операций понадобится — разрабатывайте эту связку до того, как начнете разрабатывать отчеты и алгоритмы. Чем позже вы начнете ее проектировать — тем сложнее и дороже она обойдется.
Рекомендации вендорам (разработчикам тиражируемых программных продуктов)
Не пожалейте ресурсов на системное решение этой проблемы. Или, по крайней мере, не создавайте архитектурных препятствий для ее решения «внедренцами».
JYE
В той же 1С эти проблемы уже решены
Andrew-BUSINESS Автор
Простите, но Вы либо не читали статью (внимательно), либо не работали с 1С (что вряд ли), либо мне остается только догадываться о причинах этого комментария.
JYE
Статью прочитал и 1с много где внедрял, а вот зачем эта статья с описанием велосипедов, да еще и не до конца правильными так и не понял
Andrew-BUSINESS Автор
Рад бы предложить Вам на выбор один из двух вариантов:
1. Вы выбираете любую конфигурацию 1С и находите несколько отличий от того, что написано в статье.
2. Вы называете конкретную тиражируемую конфигурацию 1С и конкретный документ, где, как Вам кажется, эти проблемы решены. А я нахожу отличия и указываю Вам на них.
Но пока что настоятельно предлагаю первый вариант.
JYE
Ниже написал как в 1с это реализовано
gennayo
В типовых от 1С не решены. А на платформе 1С это решается просто, да.
JYE
Я имею ввиду конфигурации КА2, ERP, УТ11 — в части платежей, там есть заявки на расходование денежных средств и лимиты по оплате, соответственно, при формировании заявки этот лимит уменьшается, если у заявки будет статут «отвергнут», то она освободит лимит, есть так же платежный календарь, который показывает на несколько дней вперёд сколько денег у вас будет с учетом текущего состояния расчётных счетов и касс, а так же запланированных заявок.
Есть заказы покупателям, которые учитываются в свободном остатке товаров, соответственно если есть заказ и его строки стоят в статусе к обеспечению или отгрузка, то свободный остаток уменьшается и при подборе товара в новый заказ или изменении существующего заказа это будет учитываться, система не даст поставить к отгрузке товар, даже если он есть на складе, но зарезервирован другими заказами. Для анализа доступности товара есть соотв. отчет
Andrew-BUSINESS Автор
Уже лучше. Даже поставил плюс.
Но это именно частная реализация, а не решение в общем виде. До него еще много гэпов:
1. Вы сами говорите, что в связке участвуют только Заявка на расходование и Списание. Как вы заметили, платежное поручение не учитывается (хотя я о нем писал, как и о «звонке из банка»).
Это значит, что если в поручении указаны другие, уточненные данные, в сравнении с заявкой — программа их не учтет, она все равно будет использовать в расчетах/отчетах заявку и ее реквизиты до тех пор, пока Ваш бухгалтер не проведет списание и не свяжет его с нужной заявкой.
Это не реалтаймовость. Если что, Таблица 1 в статье — не надуманная фантазия, она составлена на основе реальной практики.
2. Условия по типу {Если в списании не указано подразделение — брать его из заявки} не прописаны. Данные берутся либо из заявки целиком, либо из списания целиком.
3. Если вы попробуете такое условие дописать (а тем более сделать это по цепочке из 3х или более видов документов) — вы построите запросы через связку документов, про производительность которой Вы сами все понимаете. Для более-менее крупных объемов данных нужна другая архитектура (например, через регистры).
Кстати, даже в разных продуктах 1С используются разные подходы. Например, еще одна реализация была, кажется, в УТ10, когда общий регистр представлял собой единый актуализированный срез по товарной операции, и разные документы в цепочке по очереди проводили в него данные. Причем когда свежий документ отменялся, в нее обратно подставлялись данные из предыдущего документа. Но у этого подхода другая обратная сторона — очень сложный код механизма проведения/отмены проведения, и при попытке его доработать (например добавить в цепочку еще один кастомный документ) разработчикам приходится очень непросто.
Кстати, уже планировали с партнерами из сферы 1С сделать MVP на этой платформе для демонстрации решения в общем виде. Но пока это вопрос времени.
JYE
1. Списание ДС — это и есть платежка, только там есть признак проведена она банком или нет. Пока не проведена, расход бюджета делается из заявки, как только проведена, делается фактическое списание ДС, расход бюджета сторнируется. В некоторых организациях делали еще более глубоко. Бюжет -> Договор ->Заявка -> ПП. Таким образом нельзя было назаключать договоров сверх бюджета.
2. Обычно такого не допускаем, т.к. бюджет верстается в разрезе ЦФО, и будет хрень
3. В 1с есть регистры, которые сильно ускоряют такие вещи
Andrew-BUSINESS Автор
Точно, с 1С: Бухгалтерией перепутал.
Так и надо. Но опять же, не типовом функционале
Не понял, о чем вы, но это просто пример (который легко решается автозаполнением в платежке ЦФО равным значению из заявки — костыль, но все же), не суть принципиально
Я это только что написал:)