Как появление IEM-систем
сделало ERP устаревшими >

Архитектура



Платформа Ultimate Solid является программным комплексом трехуровневой архитектуры и включает в себя:

  • сервер базы данных (Oracle 11gR2 Enterprise Edition или Oracle 12c Enterprise Edition);
  • сервер приложений;
  • сервер печати;
  • клиентские приложения.

Общая модель взаимодействия представлена на схеме:

Как правило (и мы настоятельно рекомендуем), основной сервер базы данных (Database server, далее DBS) располагается в дата-центре. Для повышения устойчивости к отказам оборудования, снижения риска потери данных, а также для распределения нагрузки мы рекомендуем установить standby (резервный) сервер/кластер серверов.

Из аналогичных соображений отказоустойчивости и производительности сервер приложений (Application Server, далее AS), осуществляющий процессинг бизнес-логики и напрямую обменивающийся потоками данных с сервером БД, так же может быть масштабирован в кластер. Вследствие чревзвычайно высокой интенсивности обмена данных в связке AS-DBS они должны быть расположены в непосредственной близости друг от друга — как минимум, в рамках одной локальной сети.

В противоположность AS-DBS сервер печати (print server — PS) располагается в местах обитания собственно печатающих устройств и сотрудников, что позволяет существенно снизить нагрузку на каналы связи за счет передачи меньшего объема данных.

С помощью экранной логики клиентских приложений (client applications — CA) пользователь просматривает, вводит и редактирует данные.

Логика композиции решений на платформе Ultimate Solid

Эксплуатируемая заказчиком человекозаменяющая управляющая система предприятия на платформе Ultimate Solid, состоит из двух логически различных сущностей:


Платформа Ultimate Solid инвариантная часть системы (в дальнейшем термины «платформа» и «ядро» используются как взаимозаменяемые), изменяется только вендором (разработчиками Ultimate). Она (в частности) обеспечивает функционирование второй, изменяемой партнерами или независимыми разработчиками, части, называемой пространство бизнес-логики.

Пространство бизнес-логики содержит сценарии обработки бизнес-правил, сами бизнес правила, экранные формы и так далее и тому подобное. Конкретное наполнение пространства бизнес-логики, например, соответствующее конкретному клиенту или чуть более обще конкретному варианту бизнеса называется конфигурацией пространства бизнес-логики. Или коротко просто конфигурацией.

Развернутое ПО в виде платформы и заданной конфигурации у конкретного клиента называется инсталляцией. Готовый комплект платформы и конфигурации называется решением и обычно имеет тоже имя что и конфигурация. Например, для конфигурации e-Trade решение будет так же называться Ultimate e-Trade. В дальнейшем мы так же как синонимы будем использовать термины система, продукт и решение.



Платформа обеспечивает функционирование всего программного комплекса в целом и предоставляет следующие инструменты и механизмы:

  • хранения пользователей, их авторизации и проверки прав;
  • коммуникации между приложениями;
  • доступа к СУБД (сохранения объектов системы в базу данных);
  • управления изменениями конфигураций (механизм версионирования);
  • преобразования «сырых данных» из БД в объекты системы;
  • интеграции с другими системами — SOAP, JSON, REST, XML etc;
  • среду разработки и изменения конфигурации.


Пространство бизнес-логики или конфигурация(например, e-Trade, e-Service)—это набор метаданных, описывающих бизнес-объекты и непосредственных данных:

  • документы;
  • связи между справочниками и документами;
  • итоги;
  • обработчики, описывающие логику взаимодействия бизнес-объектов;
  • серверные модули;
  • клиентские модули;
  • права пользователей.


Общая модель представлена на схеме:

Конфигурация целиком хранится в базе данных. В качестве СУБД используется Oracle 12c Enterprise Edition, где имеется две схемы:

  • Kernel— статичная, именно из этой схемы Application Server при запуске загружает конфигурацию;
  • Ultimate— прикладная, в ней создаются таблицы и хранятся данные прикладной области.

Ядро недоступно для изменения прикладным разработчиком, однако предоставляет интерфейс и инструменты для реализации бизнес-логики. Сама бизнес-логика, исполняемая на сервере приложений, реализуется в виде классов на C#, унаследованных от соответствующих классов платформы (в дальнейшем такие классы будут называться скриптами). Экранная логика выполняется на клиентском приложении и реализуется в виде модулей на любом .NET совместимом языке.

Система предоставляет прикладному разработчику готовые:

  • механизмы авторизации и аутентификации;
  • механизмы преобразования объектов, их выгрузки и сохранения в базу данных;
  • редактор бизнес-объектов и бизнес-логики;
  • механизмы коммуникации между частями приложения;
  • механизмы быстрого прототипирования пользовательских интерфейсов;
  • обновление системы без перезапуска и многое другое.

Задачей прикладного разработчика является создание с помощью этих инструментов новой и/или внесение изменений в существующую конфигурацию, которая представляет собой совокупность справочников, документов, итогов, обработчиков, экранных форм и т.д., а также их описаний.

Средства описания предметной области

Описание предметной области система предлагает формулировать путем перечисления справочников, развязочных таблиц, документов, итогов и скриптов, обрабатывающих различные события в системе.

Для хранения статических редко изменяющихся данных предназначены справочники и развязочные таблицы. Не будет чересчур грубым их представление просто в виде таблиц.
Это одни из самых простых объектов в системе. Например, список товаров продаваемых или производимых компанией — хороший пример для реализации в виде справочника.

Как только система узнает описание нового справочника (его имя, набор полей и т.д.), разработчик сразу получает в свое распоряжение форму для списка записей справочника и форму для редактирования записи. Это позволяет быстро перейти к реализации прочей логики, не теряя время на разработку интерфейса. Для реализации связи многие-ко-многим предназначены развязочные таблицы. Описание свойств развязочной таблицы позволяет системе автоматически сгенерировать и предложить пользователю или разработчику готовый интерфейс для управления данными.

К более сложным объектам относятся документы и итоги.

Документы содержат информацию о некоем событии в предметной области (например, продаже товара).
Документы — составные объекты, в отличие от справочников. Каждый документ состоит из общей шапки (набора полей, который есть в любом документе системы), шапки — набора полей который есть только в данном документе и набора табличных частей (возможно пустого, а может и нет — количество табличных частей для одного документа не ограничено, это сильно упрощает формулирование сложной бизнес-логики).

Табличная часть позволяет сохранить список записей внутри одного документа (товарные строки как наиболее востребованный — но далеко не единственный — пример). С документами тесно связано понятие итога.

Итог — это объект системы, который позволяет описать измеряемый показатель предметной области и хранит его историю изменения. Итог можно так же представлять в виде многомерного куба: в системе используется та же терминология — измерения и переменные. Таким образом, документ сохраняет информацию о событии и преобразует свои данные в набор изменений итогов. Пример итога — остатки товаров на складах. Это объект системы, который хранит информацию о том, какое количество товара осталось на каждом из складов. Соответственно документ продажа уменьшает значение итога остатки товаров на складах (для товаров из документа).


Далее будет использоваться терминология:

  • справочник (синоним для тип справочника) — тип справочника задает набор полей и прочие свойства;
  • запись справочника — конкретная строка (или конкретный объект системы) справочника;
  • развязочная таблица (синоним для тип развязочной таблицы) — аналогично справочнику определяет какие поля есть в развязочной таблице;
  • тип документа — описание набора полей шапки документа и прочих свойств;
  • документ — один конкретный документ содержащий информацию об одном событии.


Ниже — более формальное описание объектов системы.

Справочники

Справочники хранят информацию об объектах описываемой модели.
В системе для каждого справочника генерируется класс для представления одной записи справочника. Кроме того, система генерирует SQL скрипт для создания в СУБД необходимых таблиц и прочих объектов для хранения справочника. Соответственно, каждый справочник содержит записи, поля которых могут принимать значения следующих типов:

  • числа — целые и дробные (для разных типов используется разное визуальное отображение);
  • строки — короткие (2048 символов) и длинные (размер которых ограничен только дисковым пространством сервера);
  • даты;
  • логический (булев) тип;
  • бинарные данные (например, фотографии);
  • ссылки на другие справочники.

Справочники бывают плоскими и древовидного типа. Различаются они формой отображения содержимого — в табличном или древовидном виде соответственно

Для хранения взаимосвязей между справочниками в системе используются развязочные таблицы. Развязочные таблицы не имеют собственной формы отображения, но их данные доступны для просмотра и редактирования в экранных формах тех справочников, которые они связывают. С помощью развязочных таблиц задаются, например, отношения склады-товары, когда большой ассортимент товаров хранится на многих складах:

Помимо самих связей между справочниками развязочные таблицы могут также хранить и дополнительные значения. Примером может служить ситуация, когда помимо отношения склады-товары необходимо хранить значение минимально необходимого запаса товара на складе:

Итоги

Итоги содержат информацию о текущем состоянии измеряемых показателей компании и историю их изменений. Каждое изменение итога называется движением. Проводя аналогию с бухгалтерским учетом, можно сказать, что итоги являются дальним потомком концепции бухгалтерского счета, а движения, соответственно, — бухгалтерских проводок.

Итоги состоят из измерений и переменных. Каждое измерение итога — ссылка на справочник. Итоги могут иметь множество измерений, являясь, таким образом, многомерными кубами.
Движения показывают по каким измерениям и какие изменения происходят для каждой переменной.

Итоги могут быть балансовыми и небалансовыми.
При внесении изменений в балансовые итоги применяется правило двойной записи, когда каждое движение имеет парное движение (с противоположным знаком — дебет и кредит) и их сумма всегда равна нулю.
При внесении изменений в небалансовый итог двойная запись не применяется. Соответственно нельзя сделать движение между балансовым и небалансовым итогами.

Для каждого итога система способна автоматически сгенерировать стандартную форму отчета, которая имеет настраиваемые механизмы детализации и фильтрации.

На первый взгляд может показаться, что итоги не отличаются от описанных выше развязочных таблиц.
Однако это не так.
Отличие состоит в том, что хранимые в развязочных таблицах значения не являются измеряемыми показателями, а задаются вручную. Если возникнет желание реализовать итоги с помощью развязочных таблиц, придется с нуля разрабатывать механизмы их заполнения, отчетные формы и прочие инструменты.

Документы

Документы содержат информацию о произошедших событиях, на основании которых генерируются движения — изменения итогов. Аналогично справочникам система для каждого типа документа генерирует класс для хранения одного документа.

Тип документов задает:

  • набор полей в шапке;
  • набор табличных частей;
  • набор подтипов документа.

Документ состоит из:

  • общей шапки — набора полей, который присутствует во всех типах документов;
  • шапки — набора полей, который есть только в документе данного типа;
  • набора табличных частей — принадлежащего документу массива данных тех же типов, что и для справочников.

Сами по себе табличные части — отдельные объекты и описываются так же отдельно.
В типе документа определяется набор входящих в него типов табличных частей. При этом в документе может быть две табличных части одинакового типа. Аналогично справочникам система генерирует для каждого типа табличной части класс для представления одной записи. В отличие от справочника, у записи табличной части есть предопределенный набор полей, который позволяет привязать ее к документу.

Потребность в тех или иных типах документов определяет бизнес-логика. Это могут быть, например документы прихода, кассовые документы, инвентаризации etc.

Событие, информацию о котором хранит документ, может быть растянуто во времени, например, продажа проходит через этапы заказа, набора на складе, оплаты и выдачи. Если информация о промежуточных этапах не обладает безусловной ценностью, можно несколько пожертвовать ее доступностью (информация останется, но не в столь явном виде) в пользу удобства пользователя или разработчика и представить этапы как подтипы документа. Аналогия подтипа документа — состояние. Для каждого типа документа разработчик задает возможные подтипы. Кроме описания предметной области и отображения текущего состояния администратор системы распределяет права на отдельные подтипы системы — например, он может выдать права на выполнение всех операций в одном подтипе и только на чтение в остальных подтипах.

Как сказано выше, документы хранят информацию о событии, а итоги позволяют разложить эту информацию на разные срезы. Преобразование данных в документе в движения итога делается в специальных программах — транзакционных скриптах или обработчиках проведения, которые пишет прикладной разработчик.
Эти скрипты запускаются при каждом сохранении документа, и система позаботится о том, чтобы набор движений был сохранен в базе данных оптимальным образом. Кроме транзакционных скриптов при сохранении срабатывает еще несколько скриптов, которые позволяют проверить произвольные бизнес-правила. Подробно последовательность запуска описана в следующих главах.


Рассмотрим на примере взаимосвязь документов, итогов и работу обработчика проведения.

Для начала купим товар «1» у поставщика «1» на склад «1».
Приход оформляется с помощью документа типа закупка. В его шапке ссылками на соответствующие справочники указываются поставщик и склад, на который будет осуществлен приход, а в табличной части перечисляются покупаемые товары:

В этом процессе будут задействованы 3 справочника:

При сохранении документа «1» вызывается обработчик проведения и генерирует движение «504». На основании этого движения платформа вносит следующие изменения в итоги:

  • в итог «остатки на складе (движения)» добавляется строка, увеличивающая остаток товара «1» на складе «1» на количество и сумму прихода;
  • в итог «долг контрагентов» добавляется строка, уменьшающая долг поставщика «1» на сумму прихода.

Для итога «остатки на складе (движения)» в приведенном примере поля документ, товар и склад являются измерениями и ссылаются на соответствующие таблицы, а поля количество и сумма — переменными.

После покупки продадим этот же товар.
Продажа оформляется с помощью документа типа продажа. В его шапке ссылками на соответствующие справочники указываются клиент и склад, с которого будет осуществлена продажа, а в табличной части перечисляются покупаемые товары. Сопутствующая продаже оплата оформляется документом типа оплата в кассу. В его шапке указываются клиент и касса, в которую осуществляется оплата, а в табличной части указывается сумма платежа:

На этом этапе в дополнение к предыдущим в процесс включается еще один справочник:

При сохранении документа «3» вызывается обработчик проведения и генерирует движения «505» и «506». На основании этих движений ядро вносит следующие две пары изменений в итоги:

  • в итог «остатки на складе (движения)» добавляется строка, уменьшающая остаток товара «1» на складе «1» на количество расхода и сумму, соответствующую себестоимости предыдущего прихода
  • в итог «продажи» добавляется строка, увеличивающая количество продаваемого товара «1» клиенту «2» на сумму себестоимости продажи;
  • в итог «продажи» добавляется строка, уменьшающая количество продаваемого товара «1» клиенту «2» на сумму продажи (по отпускной цене), таким образом за счет разницы цен у нас образуется валовая прибыль;
  • в итог «долг контрагентов» добавляется строка, увеличивающая долг клиента «2» на сумму продажи.

При сохранении документа «2» вызывается обработчик проведения и генерирует движение «507».
На основании этого движения ядро вносит следующие изменения в итоги:

  • в итог «долг контрагентов» добавляется строка, уменьшающая долг клиента «2» на сумму оплаты;
  • в итог «наличные» добавляется строка, увеличивающая остаток денег в кассе «1» на сумму оплаты.

В реальности из-за разницы закупочных цен на товары себестоимость вычисляется не так однозначно, как показано в этом примере.


Рассмотрим как раз такой случай. Купим товар «1» у другого поставщика «3» по цене, отличающейся от предыдущей (документ «4»), а затем продадим его еще раз клиенту «4» (документы «5» и «6»):

При сохранении документа «4» вызывается обработчик проведения и генерирует движение «508». На основании этого движения ядро вносит следующие изменения в итоги:

  • в итог «остатки на складе (движения)» добавляется строка, увеличивающая остаток товара «1» на складе «1» на количество и сумму прихода;
  • в итог «долг контрагентов» добавляется строка, уменьшающая долг поставщика «3» на сумму прихода.


При сохранении документа «6» вызывается обработчик проведения и генерирует движения «509» и «510». На основании этих движений ядро вносит следующие две пары изменений в итоги:

  • в итог «остатки на складе (движения)» добавляется строка, уменьшающая остаток товара «1» на складе «1» на количество расхода, сумма этого списания, будучи себестоимостью — расчетной величиной, подлежит вычислению, потому движение создается с пустым полем;
  • в итог «продажи» добавляется строка, увеличивающая количество продаваемого товара «1» клиенту «4», поле сумма опять, будучи себестоимостью, остается пустой;
  • в итог «продажи» добавляется строка, уменьшающая количество продаваемого товара «1» клиенту «4» на сумму продажи (по отпускной цене);
  • в итог «долг контрагентов» добавляется строка, увеличивающая долг клиента «4» на сумму продажи.

При сохранении документа «5» вызывается обработчик проведения и генерирует движение «511». На основании этого движения ядро вносит следующие изменения в итоги:

  • в итог «долг контрагентов» добавляется строка, уменьшающая долг клиента «4» на сумму оплаты;
  • в итог «наличные» добавляется строка, увеличивающая остаток денег в кассе «1» на сумму оплаты.

Незаполненные при записи движений переменные итогов называются аналитическими. В случае итога «остатки на складе (движения)» — это переменная сумма. В случае покупки сумма нам известна, потому она в составе проводки попадает в итог, но при расходе она требует вычисления, поэтому поле остается незаполненным. Переменная же количество — оперативная, нам всегда однозначно известно какое количество товара мы приходуем, списываем, перемещаем или продаем.


Чтобы объяснить, как вычисляется себестоимость, придется более подробно рассмотреть структуру хранения итогов.

Каждый итог реализован с помощью четырех таблиц, две из которых оперативные и две аналитические. По аналогии с переменными в оперативные таблицы информация попадает сразу по факту записи движения, в аналитические по результату расчета итогов. Причем оперативные таблицы могут содержать аналитические переменные, как, например, таблица итога «остатки на складе (движения)». Как раз аналитические переменные оперативного итога и остаются незаполненными, если движение не содержит их вычисляемых значений.

Различить таблицы можно по префиксам:

TB_tablename — оперативная сводная таблица, в которой для каждого набора измерений хранится только один набор сводных значений переменных. В приведенном примере это таблица «остатки на складе (сводные)», где для каждого товара на складе хранится только текущий остаток и его стоимость;

TR_tablename — оперативная детализированная таблица, в которой хранятся все движения. Просуммировав их переменные для определенного набора измерений можно получить сводное значение, которое хранится в TB_tablename. Дополнительно в этой таблице хранится информация о документах и движениях, приведших к изменениям. В приведенном примере это таблица «остатки на складе (движения)»;

TD_tablename — аналитическая детализированная таблица, в которой хранятся те же движения, что и в TR_tablename, только уже рассчитанные. Заполняется по результату расчета итогов. В приведенном примере это таблица «остатки на складе (движения аналитические)»;

TT_tablename — аналитическая сводная таблица, в которой для каждого набора измерений хранится только один набор сводных значений переменных из таблицы TD_tablename. В приведенном примере это таблица «остатки на складе (сводные аналитические)».


Для последнего примера таблицы итога «остатки на складе» после расчета себестоимости будут выглядеть следующим образом:

Сам расчет себестоимости производится обработчиком — драйвером итога. В системе реализован метод подсчета себестоимости по FIFO, в соответствии с которым драйвер итога и рассчитывает себестоимость продажи, делая две записи в таблице «остатки на складе (движения аналитические)». Разработчик имеет возможность реализовать расчет иным методом, например, по LIFO или среднему, написав свой драйвер итога — хотя подобное действие будет не более, чем данью доисторическим временам управленческого учета, когда правильный расчет себестоимости FIFO был невозможен по причине невероятной трудоемкости.

Расчет итогов производится автоматически обычно раз в час, но актуальность итогов может быть еще меньше: если внести исправления в какой-либо документ, в результате которых движения изменят итоги задним числом, данные будут актуальны по дату этого документа. В этой связи отчет по итогам может быть актуален на дату меньше текущей. Информация о дате актуальности отчета отображается в его экранной форме.
 

. . .



Выше были приведены выдержки из документации разработчика по платформе Ultimate Solid. Соответственно, продолжение — в ней же.

Как появление IEM-систем сделало ERP устаревшими