Кастомизируем Бизнес Пак
У меня есть несколько новостей по популярной программе Бизнес Пак 7-ой версии.
Начнем с хороших. Во-первых, для хранения данных вместо формата DBF (который был известен еще царю Гороху) теперь используется Embedded Firebird. Во-вторых, в программу встроен скриптовый движок, который позволяет изменить или дополнить имеющийся функционал.
Плохих новостей тоже две. Во-первых, язык для скриптования — MzScheme. (Хорошо, что они Forth не выбрали.) Во-вторых, нет никакой документации и уже имеющиеся скрипты не содержат ни одного информативного комментария.
Условия задачи
Попробуем сделать на базе Бизнес Пак (далее — БП) свое решение для стола заказов. Стол заказов обслуживает частных клиентов из нескольких населенных пунктов. Обслуживание заключается в выписывании счетов. В счет включаются товары из нескольких групп.
Фото-отчет
Чтобы вы поняли, о чем идет речь, — несколько скриншотов.
Было:

Стало:




Just do it
Системные скрипты БП находятся в каталоге scm. Скрипты, описывающие документы — в каталоге documents. Шаблоны печатных форм — в каталоге reports.
Для начала удалим лишние файлы: из каталога documents — все, кроме файла dictionary.scm, а из каталога reports — все, кроме файла bpfunc.pas.
Все сущности, хранящиеся в БД, описываются списком tables в файле scm\meta.scm.
Со справочниками все просто. Мы добавим две новые сущности:
(tables
...
(Settlement
(desc "Населенные пункты")
(fields
(Name (type LongString) (caption "Наименование") (tags def desc))
)
)
(Client
(desc "Клиенты")
(fields
(Settlement (type Settlement) (caption "Населенный пункт"))
(Name (type LongString) (caption "ФИО") (tags def desc))
(Address (type LongString) (caption "Адрес"))
(Phone (type LongString) (caption "Телефон"))
)
)
Список fields здесь задает полный перечень атрибутов, а type описывает тип данных. Доступные типы данных и их соответствие SQL-типам можно посмотреть в этом же файле в списке types.
Здесь же в списке indexes можно определить индексы для таблиц базы данных, например так:
(indexes
...
(Client
(Name))
(Settlement
(Name))
При обработке файла meta.scm БП выполнит для наших сущностей такие SQL-операторы:
CREATE TABLE "tSettlement" (
"fObject" CHAR(12) NOT NULL,
"fName" VARCHAR(250) DEFAULT '' NOT NULL
);
ALTER TABLE "tSettlement" ADD CONSTRAINT PK_SETTLEMENT PRIMARY KEY ("fObject");
CREATE INDEX I_SETTLEMENT2_N0 ON "tSettlement" ("fName");
CREATE TABLE "tClient" (
"fObject" CHAR(12) NOT NULL,
"fSettlement" CHAR(12) DEFAULT '000000000000' NOT NULL,
"fName" VARCHAR(250) DEFAULT '' NOT NULL,
"fAddress" VARCHAR(250) DEFAULT '' NOT NULL,
"fPhone" VARCHAR(250) DEFAULT '' NOT NULL
);
ALTER TABLE "tClient" ADD CONSTRAINT PK_CLIENT PRIMARY KEY ("fObject");
ALTER TABLE "tClient" ADD CONSTRAINT FK_CLIENT_SETTLEMENT FOREIGN KEY ("fSettlement") REFERENCES "tSettlement" ("fObject");
CREATE INDEX I_CLIENT1_N0 ON "tClient" ("fName");
Обратите внимание, БП сам управляется с первичными и внешними ключами.
В файле scm\layout.scm дополним список defaults следующими «магическими» элементами:
(defaults
...
(Settlement
(dataset ds-settlement-min)
(form form-settlement-std))
(Client
(dataset ds-client-min)
(form form-client-std))
Почему «магическими»? Потому, что достоверно установить, что именно они означают, не удалось. Но они нужны.
С документами чуть-чуть иначе. Дело в том, что в БП все документы, вне зависимости от их вида, являются одной сущностью — Doc. В принципе, наш документ (а это заказ), отличается от прочих документов БП лишь тем, что второй контрагент — не фирма, а определенный нами выше Client. Самым простым решением будет дополнить описание Doc таким образом:
(Doc
...
(Client
(type Client))
Такое решение, конечно же, отразиться на всех других документах, но… Во-первых, в нашей системе других документов и не будет, и, во-вторых, атрибут Client у документа будет отображаться в интерфейсе пользователя только там, где мы явным образом это разрешим.
На этом модификация имеющихся скриптов завершена. Имейте в виду, в БП встроена система обновления через интернет, и вполне может быть, что очередное обновление перепишет модифицированные нами файлы. Со всеми вытекающими…
Все остальное наше творчество будем записывать в файл documents\order.scm. Почему именно «order»? Потому, что в дистрибутиве БП нет файла с таким именем, значит автообновление нам не грозит. И еще, «order» — это «заказ» в переводе на великий и могучий.
В файле documents\order.scm находятся скрипты, описывающие интерфейс пользователя. В нашем примере таких скриптов — четыре, все они перечислены в списке export, что делает их доступными для ядра БП:
(define export '(export
(forms form-settlement-dict
form-client-dict
doc-order
arch-order)))
form-NNN-dict представляет собой скрипт интерфейса пользователя для справочника NNN, а doc-MMM и arch-MMM — для документа MMM и архива документов MMM соответственно.
Названия скриптов интерфейса пользователя используются в именовании файлов с печатными формами в каталоге reports. Имя файла печатной формы выглядит так: SSS.MMM.fr3, где SSS — имя скрипта интерфейса пользователя, а MMM — название печатной формы в интерфейсе пользователя. Например, печатная форма для справочника клиентов в нашем примере может называться form-client-dict.Список клиентов.fr3, а печатная форма для заказа — doc-order.На кухню.fr3. Самый простой способ создать печатную форму — отредактировать одну из готовых печатных форм БП.
К сожалению, большую часть того, что я «накопипастил» в файл documents\order.scm связно объяснить я не могу. Поэтому предлагаю заинтересовавшимся скачать мое готовое решение и «скопипастить» что-нибудь из него.
Updated: трансляция meta.scm в SQL
Updated: индексы
Какая интересная штука! Надо бы покурить на досуге…