From 5ef2bfcd788bc91acdc993c5cae0fb2c741aff5f Mon Sep 17 00:00:00 2001 From: fontvielle Date: Thu, 22 Oct 2026 16:50:50 +0300 Subject: [PATCH] =?UTF-8?q?DEPO=20=D0=BD=D0=B0=20Firebird=202.5:=20=D1=82?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D1=8B=20=D0=B8=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D1=8B=20=D0=BE=D0=B1=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20M2M=20(=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=20=D1=81=20MSSQL),=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B0,=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BE=D0=BD=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=B3=D0=BB=D1=83=D1=88=D0=BA=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Логика процедур Фонтвьель (22.10.2026) на PSQL; привязки к справочникам клиента — FTV_M2M_SETTINGS; текст ошибки — в COMMENT через контекст транзакции. README — что проверить на базе клиента. Проверено на встроенном Firebird 2.5.9 (test/run.sh): все ветки событий, операция с проводкой, справочник, ошибки. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn --- .../fancy-m2m-firebird/00_FTV_M2M_TABLES.sql | 168 +++++ .../fancy-m2m-firebird/10_FTV_M2M_PROCS.sql | 624 +++++++++++++++++ .../fancy-m2m-firebird/20_FTV_M2M_GRANTS.sql | 346 ++++++++++ deploy/depo/fancy-m2m-firebird/README.md | 47 ++ deploy/depo/fancy-m2m-firebird/test/run.sh | 29 + deploy/depo/fancy-m2m-firebird/test/smoke.sql | 48 ++ .../fancy-m2m-firebird/test/stub_fancy.sql | 635 ++++++++++++++++++ 7 files changed, 1897 insertions(+) create mode 100644 deploy/depo/fancy-m2m-firebird/00_FTV_M2M_TABLES.sql create mode 100644 deploy/depo/fancy-m2m-firebird/10_FTV_M2M_PROCS.sql create mode 100644 deploy/depo/fancy-m2m-firebird/20_FTV_M2M_GRANTS.sql create mode 100644 deploy/depo/fancy-m2m-firebird/README.md create mode 100755 deploy/depo/fancy-m2m-firebird/test/run.sh create mode 100644 deploy/depo/fancy-m2m-firebird/test/smoke.sql create mode 100644 deploy/depo/fancy-m2m-firebird/test/stub_fancy.sql diff --git a/deploy/depo/fancy-m2m-firebird/00_FTV_M2M_TABLES.sql b/deploy/depo/fancy-m2m-firebird/00_FTV_M2M_TABLES.sql new file mode 100644 index 0000000..2260a18 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/00_FTV_M2M_TABLES.sql @@ -0,0 +1,168 @@ +/* Bridge&Join — трансферные таблицы обмена M2M для Fancy DEPO на Firebird 2.5. + Аналог таблиц FTV_M2M* версии MSSQL. Отличия: + - ID — генератор + триггер (в 2.5 нет IDENTITY); + - GUID — CHAR(36) в верхнем регистре (как отдаёт MSSQL uniqueidentifier); + - COMMENT / M2M_REJECT_CODE varchar(MAX) — BLOB SUB_TYPE TEXT; + - ACTIVE bit — SMALLINT; + - FTV_M2M_SETTINGS — привязки к справочникам клиента (в MSSQL-версии они зашиты в тексты процедур). + Скрипт можно выполнять повторно: существующие объекты не пересоздаются (кроме триггеров и исключения). */ + +SET TERM ^ ; + +EXECUTE BLOCK AS +BEGIN + IF (NOT EXISTS (SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'FTV_M2M')) THEN + EXECUTE STATEMENT 'CREATE TABLE FTV_M2M ( + ID INTEGER NOT NULL PRIMARY KEY, + GUID CHAR(36) NOT NULL, + STATE VARCHAR(64) DEFAULT ''TODO'' NOT NULL, + TIMENEW TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + TIMEBEG TIMESTAMP, + TIMEEND TIMESTAMP, + "COMMENT" BLOB SUB_TYPE TEXT, + DIRECTION VARCHAR(4) NOT NULL, + CONTRAGENT_M2M_CODE VARCHAR(255) NOT NULL, + DEPONENT_NAME VARCHAR(255) NOT NULL, + DEPONENT_DOC VARCHAR(255) NOT NULL, + DOC INTEGER, + CONTRAGENT INTEGER, + DEPONENT INTEGER)'; + + IF (NOT EXISTS (SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'FTV_M2M_LINES')) THEN + EXECUTE STATEMENT 'CREATE TABLE FTV_M2M_LINES ( + ID INTEGER NOT NULL PRIMARY KEY, + GUID CHAR(36) NOT NULL, + REFERENCE VARCHAR(36), + STATE VARCHAR(64) DEFAULT ''TODO'' NOT NULL, + TIMENEW TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + TIMEBEG TIMESTAMP, + TIMEEND TIMESTAMP, + ISIN VARCHAR(12), + SEC_CODE VARCHAR(255), + AMOUNT NUMERIC(18,7), + PLACE_NUMBER VARCHAR(128), + LINK_NUMBER VARCHAR(64), + DEPO_NUMBER VARCHAR(128), + DOC INTEGER, + DOL INTEGER, + SHARE INTEGER, + PLACE INTEGER, + DEPO INTEGER, + "COMMENT" BLOB SUB_TYPE TEXT)'; + + IF (NOT EXISTS (SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'FTV_M2M_EVENTS')) THEN + EXECUTE STATEMENT 'CREATE TABLE FTV_M2M_EVENTS ( + ID INTEGER NOT NULL PRIMARY KEY, + GUID CHAR(36), + REFERENCE VARCHAR(36), + STATE VARCHAR(64) DEFAULT ''TODO'' NOT NULL, + TIMENEW TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + TIMEBEG TIMESTAMP, + TIMEEND TIMESTAMP, + "COMMENT" BLOB SUB_TYPE TEXT, + EVENT_TYPE VARCHAR(64) NOT NULL, + EVENT_DATE TIMESTAMP NOT NULL, + M2M_REJECT_CODE VARCHAR(1000), + PARAMETERS VARCHAR(4000))'; + + IF (NOT EXISTS (SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'FTV_M2M_HANDBOOK')) THEN + EXECUTE STATEMENT 'CREATE TABLE FTV_M2M_HANDBOOK ( + ID INTEGER NOT NULL PRIMARY KEY, + INN VARCHAR(12) NOT NULL, + PARTICIPANT_CODE VARCHAR(12), + KIND VARCHAR(8) NOT NULL, + NAME_FULL VARCHAR(255), + NAME_SHORT VARCHAR(128), + NAME_DISPLAY VARCHAR(255), + NAME_ENG VARCHAR(255), + HANDBOOK_AT TIMESTAMP, + UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, + ACTIVE SMALLINT DEFAULT 1 NOT NULL)'; + + /* Привязки к справочникам Fancy клиента: в MSSQL-версии (Фонтвьель) — числа в текстах процедур. + Заполняются при установке; пустое значение — процедура останавливается с понятной ошибкой. */ + IF (NOT EXISTS (SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'FTV_M2M_SETTINGS')) THEN + EXECUTE STATEMENT 'CREATE TABLE FTV_M2M_SETTINGS ( + NAME VARCHAR(64) NOT NULL PRIMARY KEY, + VAL INTEGER, + "COMMENT" VARCHAR(255))'; + + IF (NOT EXISTS (SELECT 1 FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME = 'FTV_M2M_GEN')) THEN + EXECUTE STATEMENT 'CREATE GENERATOR FTV_M2M_GEN'; + IF (NOT EXISTS (SELECT 1 FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME = 'FTV_M2M_LINES_GEN')) THEN + EXECUTE STATEMENT 'CREATE GENERATOR FTV_M2M_LINES_GEN'; + IF (NOT EXISTS (SELECT 1 FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME = 'FTV_M2M_EVENTS_GEN')) THEN + EXECUTE STATEMENT 'CREATE GENERATOR FTV_M2M_EVENTS_GEN'; + IF (NOT EXISTS (SELECT 1 FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME = 'FTV_M2M_HANDBOOK_GEN')) THEN + EXECUTE STATEMENT 'CREATE GENERATOR FTV_M2M_HANDBOOK_GEN'; + + IF (NOT EXISTS (SELECT 1 FROM RDB$INDICES WHERE RDB$INDEX_NAME = 'FTV_M2M_GUID')) THEN + EXECUTE STATEMENT 'CREATE INDEX FTV_M2M_GUID ON FTV_M2M (GUID)'; + IF (NOT EXISTS (SELECT 1 FROM RDB$INDICES WHERE RDB$INDEX_NAME = 'FTV_M2M_LINES_GUID')) THEN + EXECUTE STATEMENT 'CREATE INDEX FTV_M2M_LINES_GUID ON FTV_M2M_LINES (GUID)'; + IF (NOT EXISTS (SELECT 1 FROM RDB$INDICES WHERE RDB$INDEX_NAME = 'FTV_M2M_EVENTS_STATE')) THEN + EXECUTE STATEMENT 'CREATE INDEX FTV_M2M_EVENTS_STATE ON FTV_M2M_EVENTS (STATE)'; + IF (NOT EXISTS (SELECT 1 FROM RDB$INDICES WHERE RDB$INDEX_NAME = 'FTV_M2M_EVENTS_GUID')) THEN + EXECUTE STATEMENT 'CREATE INDEX FTV_M2M_EVENTS_GUID ON FTV_M2M_EVENTS (GUID)'; + IF (NOT EXISTS (SELECT 1 FROM RDB$INDICES WHERE RDB$INDEX_NAME = 'FTV_M2M_HANDBOOK_INN')) THEN + EXECUTE STATEMENT 'CREATE INDEX FTV_M2M_HANDBOOK_INN ON FTV_M2M_HANDBOOK (INN)'; +END^ + +/* таблицы — до триггеров: DDL блока выполняется в его транзакции */ +COMMIT^ + +CREATE OR ALTER TRIGGER FTV_M2M_BI FOR FTV_M2M ACTIVE BEFORE INSERT POSITION 0 AS +BEGIN + IF (NEW.ID IS NULL OR NEW.ID = 0) THEN NEW.ID = GEN_ID(FTV_M2M_GEN, 1); + NEW.GUID = UPPER(NEW.GUID); +END^ + +CREATE OR ALTER TRIGGER FTV_M2M_LINES_BI FOR FTV_M2M_LINES ACTIVE BEFORE INSERT POSITION 0 AS +BEGIN + IF (NEW.ID IS NULL OR NEW.ID = 0) THEN NEW.ID = GEN_ID(FTV_M2M_LINES_GEN, 1); + NEW.GUID = UPPER(NEW.GUID); +END^ + +CREATE OR ALTER TRIGGER FTV_M2M_EVENTS_BI FOR FTV_M2M_EVENTS ACTIVE BEFORE INSERT POSITION 0 AS +BEGIN + IF (NEW.ID IS NULL OR NEW.ID = 0) THEN NEW.ID = GEN_ID(FTV_M2M_EVENTS_GEN, 1); + NEW.GUID = UPPER(NEW.GUID); +END^ + +CREATE OR ALTER TRIGGER FTV_M2M_HANDBOOK_BI FOR FTV_M2M_HANDBOOK ACTIVE BEFORE INSERT POSITION 0 AS +BEGIN + IF (NEW.ID IS NULL OR NEW.ID = 0) THEN NEW.ID = GEN_ID(FTV_M2M_HANDBOOK_GEN, 1); +END^ + +SET TERM ; ^ + +/* Ошибка обработки: процедуры поднимают её с текстом причины (аналог raiserror MSSQL-версии). */ +CREATE OR ALTER EXCEPTION FTV_M2M_ERROR 'Ошибка обработки M2M'; + +/* Строки настроек без значений: ID у каждого клиента свои, в комментарии — значение у Фонтвьель (MSSQL) для + ориентира. Вставляются только отсутствующие строки — повторный запуск не затирает заполненные значения. */ +SET TERM ^ ; +EXECUTE BLOCK AS +BEGIN + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'WHOS')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('WHOS', NULL, 'OD_DOCS.WHOS — юрлицо-депозитарий (Фонтвьель: 383118)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'OPER_USER')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('OPER_USER', NULL, 'OD_OPERATORS.ID — оператор проводок (Фонтвьель: 84, SYSDBA)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'FILER_CAT')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('FILER_CAT', NULL, 'OD_DOC_CATS.ID категории D_FILER — входящая запись (Фонтвьель: 255)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'D_NUM')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('D_NUM', NULL, 'OD_BALANCES.ID — 98010 НОСТРО депо базовый (Фонтвьель: 313)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'K_NUM')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('K_NUM', NULL, 'OD_BALANCES.ID — 98070 ЦБ на торгах (Фонтвьель: 836)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'MARKET')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('MARKET', NULL, 'OD_FACES.SELF_ID — ПАО Московская Биржа (Фонтвьель: 8106)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'B_TYPE')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('B_TYPE', NULL, 'OD_SYS_TABS DEPO96_DCLA.NUM — «Отчёт депозитария» (Фонтвьель: 31)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'CORR_FACE')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('CORR_FACE', NULL, 'OD_FACES.SELF_ID — НКО АО НРД, корреспондент входящей записи (Фонтвьель: 18174)'); + IF (NOT EXISTS (SELECT 1 FROM FTV_M2M_SETTINGS WHERE NAME = 'FILER_RUBRICA')) THEN + INSERT INTO FTV_M2M_SETTINGS (NAME, VAL, "COMMENT") VALUES ('FILER_RUBRICA', NULL, 'D_FILER.RUBRICA для отчёта НРД (Фонтвьель: 5, «уточнить в депозитарии»)'); +END^ +SET TERM ; ^ + +COMMIT; diff --git a/deploy/depo/fancy-m2m-firebird/10_FTV_M2M_PROCS.sql b/deploy/depo/fancy-m2m-firebird/10_FTV_M2M_PROCS.sql new file mode 100644 index 0000000..0f686f6 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/10_FTV_M2M_PROCS.sql @@ -0,0 +1,624 @@ +/* Bridge&Join — процедуры обработки M2M для Fancy DEPO на Firebird 2.5. + Перенос процедур MSSQL-версии (Фонтвьель, тексты от 22.10.2026) на PSQL. Логика та же; отличия: + - raiserror → FTV_M2M_FAIL: текст причины кладётся в контекст транзакции и поднимается исключение FTV_M2M_ERROR; + FTV_M2M_JOB пишет этот текст в COMMENT (в Firebird 2.5 текст исключения в WHEN не доступен; контекст + возвращает строку без кодировки — приводится к WIN1251, кодировке базы Fancy); + - ошибка записи откатывает только её изменения (WHEN ANY = точка сохранения), в MSSQL-версии изменения + до ошибки оставались; + - числа-привязки Фонтвьель (WHOS, счета, биржа, тип основания, НРД, оператор) — из FTV_M2M_SETTINGS; + - «execute as user = 'SYSDBA'» нет: процедуры работают правами, выданными им самим (GRANT … TO PROCEDURE, + 20_FTV_M2M_GRANTS.sql); логину bj нужно только EXECUTE на FTV_M2M_JOB; + - SELECT … INTO, который в MSSQL молча брал последнюю из нескольких строк, — SELECT FIRST 1; + - в цикле по строкам поручения бумага/счета сбрасываются перед поиском (в MSSQL ненайденное значение + оставалось от предыдущей строки). + Порядок создания: вспомогательные → WIRING → OPERATION → UPDATE_HANDBOOK → EVENTS → CREATE → JOB. */ + +SET TERM ^ ; + +/* Ошибка обработки с текстом причины. */ +CREATE OR ALTER PROCEDURE FTV_M2M_FAIL (MSG VARCHAR(1000)) AS +DECLARE VARIABLE R INTEGER; +BEGIN + R = RDB$SET_CONTEXT('USER_TRANSACTION', 'FTV_M2M_ERR', SUBSTRING(MSG FROM 1 FOR 255)); + EXCEPTION FTV_M2M_ERROR MSG; +END^ + +/* Привязка из FTV_M2M_SETTINGS; не заполнена — ошибка с именем настройки. */ +CREATE OR ALTER PROCEDURE FTV_M2M_GET (NAME VARCHAR(64)) RETURNS (VAL INTEGER) AS +BEGIN + VAL = NULL; + SELECT S.VAL FROM FTV_M2M_SETTINGS S WHERE S.NAME = :NAME INTO :VAL; + IF (VAL IS NULL) THEN + EXECUTE PROCEDURE FTV_M2M_FAIL('Не заполнена настройка FTV_M2M_SETTINGS.' || NAME || ' (привязка к справочнику Fancy)'); +END^ + +/* «дд.мм.гггг чч:мм:сс» (FORMAT(…, 'dd.MM.yyyy HH:mm:ss') MSSQL-версии). */ +CREATE OR ALTER PROCEDURE FTV_M2M_DT (T TIMESTAMP) RETURNS (S VARCHAR(19)) AS +BEGIN + S = NULL; + IF (T IS NOT NULL) THEN + S = LPAD(EXTRACT(DAY FROM T), 2, '0') || '.' || LPAD(EXTRACT(MONTH FROM T), 2, '0') || '.' || EXTRACT(YEAR FROM T) || ' ' || + LPAD(EXTRACT(HOUR FROM T), 2, '0') || ':' || LPAD(EXTRACT(MINUTE FROM T), 2, '0') || ':' || + LPAD(CAST(FLOOR(EXTRACT(SECOND FROM T)) AS INTEGER), 2, '0'); +END^ + + +/* Директива «Обработать» для документа «Зачисление» или «Списание». Значения берутся только из самого + документа; M2M-поручение и трансферные таблицы не используются. */ +CREATE OR ALTER PROCEDURE FTV_M2M_PROCESS_WIRING (OPER_ID INTEGER) AS +DECLARE VARIABLE USER_ID INTEGER; +DECLARE VARIABLE DIRECTION VARCHAR(3); +DECLARE VARIABLE D_CAT INTEGER; +DECLARE VARIABLE SHARE INTEGER; +DECLARE VARIABLE PLACE INTEGER; +DECLARE VARIABLE DEPO INTEGER; +DECLARE VARIABLE AMOUNT NUMERIC(18,7); +DECLARE VARIABLE CMT VARCHAR(255); +DECLARE VARIABLE B_TYPE INTEGER; +DECLARE VARIABLE B_NUM VARCHAR(255); +DECLARE VARIABLE B_DATE TIMESTAMP; +DECLARE VARIABLE WIR_DATE TIMESTAMP; +DECLARE VARIABLE D_NUM INTEGER; +DECLARE VARIABLE K_NUM INTEGER; +DECLARE VARIABLE MARKET INTEGER; +DECLARE VARIABLE OP_NAME VARCHAR(255); +DECLARE VARIABLE TEXT_B_TYPE VARCHAR(255); +DECLARE VARIABLE B_DATE_S VARCHAR(19); +DECLARE VARIABLE WIR_ID INTEGER; +DECLARE VARIABLE WIR_LIST VARCHAR(255); +DECLARE VARIABLE DEB_ID INTEGER; +DECLARE VARIABLE KRD_ID INTEGER; +DECLARE VARIABLE D_REG_1 INTEGER; DECLARE VARIABLE K_REG_1 INTEGER; +DECLARE VARIABLE D_REG_2 INTEGER; DECLARE VARIABLE K_REG_2 INTEGER; +DECLARE VARIABLE D_REG_3 INTEGER; DECLARE VARIABLE K_REG_3 INTEGER; +DECLARE VARIABLE D_REG_4 INTEGER; DECLARE VARIABLE K_REG_4 INTEGER; +DECLARE VARIABLE D_REG_5 INTEGER; DECLARE VARIABLE K_REG_5 INTEGER; +DECLARE VARIABLE D_REG_6 INTEGER; DECLARE VARIABLE K_REG_6 INTEGER; +DECLARE VARIABLE DIR_ID INTEGER; +DECLARE VARIABLE OUT_STATE INTEGER; +DECLARE VARIABLE STEP_ID INTEGER; +BEGIN + EXECUTE PROCEDURE FTV_M2M_GET('OPER_USER') RETURNING_VALUES :USER_ID; + + /* НАПРАВЛЕНИЕ (MSSQL-версия при ненайденном документе молча выходила — здесь ошибка, видно в COMMENT) */ + IF (EXISTS (SELECT 1 FROM U_OP_INV_ZACH WHERE DOC = :OPER_ID)) THEN DIRECTION = 'IN'; + ELSE IF (EXISTS (SELECT 1 FROM U_OP_INV_SPIS WHERE DOC = :OPER_ID)) THEN DIRECTION = 'OUT'; + ELSE EXECUTE PROCEDURE FTV_M2M_FAIL('Не найден документ операции ID = ' || OPER_ID); + + /* ЗНАЧЕНИЯ ПЕРЕМЕННЫХ */ + IF (DIRECTION = 'IN') THEN + BEGIN + SELECT D.D_CAT, H.D_NUM, H.K_NUM, H.B_TYPE, H.B_NUM, H.B_DATE, H.SHARE, H.AMOUNT, H.PLACE, H.DEPO, H.MARKET, H.WIR_DATE + FROM OD_DOCS D LEFT JOIN U_OP_INV_ZACH H ON H.DOC = D.ID + WHERE D.ID = :OPER_ID + INTO :D_CAT, :D_NUM, :K_NUM, :B_TYPE, :B_NUM, :B_DATE, :SHARE, :AMOUNT, :PLACE, :DEPO, :MARKET, :WIR_DATE; + OP_NAME = 'Зачисление'; + SELECT C.SELF_ID, C.FACE, 0, 0, 0, :PLACE FROM OD_CLIENTS C WHERE C.ID = :PLACE + INTO :D_REG_1, :D_REG_2, :D_REG_3, :D_REG_4, :D_REG_5, :D_REG_6; + SELECT C.SELF_ID, :MARKET, 0, :D_REG_1, :PLACE, :DEPO FROM OD_CLIENTS C WHERE C.ID = :DEPO + INTO :K_REG_1, :K_REG_2, :K_REG_3, :K_REG_4, :K_REG_5, :K_REG_6; + END + ELSE + BEGIN + SELECT D.D_CAT, H.K_NUM /* реверс */, H.D_NUM /* реверс */, H.B_TYPE, H.B_NUM, H.B_DATE, H.SHARE, H.AMOUNT, H.PLACE, H.DEPO, H.MARKET, H.WIR_DATE + FROM OD_DOCS D LEFT JOIN U_OP_INV_SPIS H ON H.DOC = D.ID + WHERE D.ID = :OPER_ID + INTO :D_CAT, :D_NUM, :K_NUM, :B_TYPE, :B_NUM, :B_DATE, :SHARE, :AMOUNT, :PLACE, :DEPO, :MARKET, :WIR_DATE; + OP_NAME = 'Списание'; + SELECT C.SELF_ID, C.FACE, 0, 0, 0, :PLACE FROM OD_CLIENTS C WHERE C.ID = :PLACE + INTO :K_REG_1, :K_REG_2, :K_REG_3, :K_REG_4, :K_REG_5, :K_REG_6; + SELECT C.SELF_ID, :MARKET, 0, :K_REG_1, :PLACE, :DEPO FROM OD_CLIENTS C WHERE C.ID = :DEPO + INTO :D_REG_1, :D_REG_2, :D_REG_3, :D_REG_4, :D_REG_5, :D_REG_6; + END + + /* ДОПОЛНИТЕЛЬНЫЕ ПАРАМЕТРЫ: «<тип основания> N<номер> от <дата>» + (в MSSQL-версии FORMATMESSAGE начинал строку с пустого @COMMENT — «(null); …») */ + SELECT FIRST 1 T.NAME FROM OD_SYS_TABS T WHERE T.CODE = 'DEPO96_DCLA' AND T.NUM = :B_TYPE INTO :TEXT_B_TYPE; + EXECUTE PROCEDURE FTV_M2M_DT(:B_DATE) RETURNING_VALUES :B_DATE_S; + CMT = SUBSTRING((COALESCE(TEXT_B_TYPE, '') || ' N' || COALESCE(B_NUM, '') || ' от ' || COALESCE(SUBSTRING(B_DATE_S FROM 1 FOR 10), '')) FROM 1 FOR 255); + + /* ДИРЕКТИВА */ + SELECT FIRST 1 T.ID, T.OUT_STATE FROM OD_STEP_TYPES T WHERE T.SYS_NAME = 'PROCESS' AND T.D_CAT = :D_CAT INTO :DIR_ID, :OUT_STATE; + STEP_ID = GEN_ID(OD_STEPS_ID_GEN, 1); + INSERT INTO OD_STEPS (ID, DOC, S_TYPE, S_DATE, ERR_CODE, OUT_STATE, OPER) + VALUES (:STEP_ID, :OPER_ID, :DIR_ID, CURRENT_TIMESTAMP, 0, :OUT_STATE, :USER_ID); + + /* ПРОВОДКА */ + EXECUTE PROCEDURE OD_PR_INS_WIRS ( + NULL, 4, :WIR_DATE, :OP_NAME, :CMT, :AMOUNT, :AMOUNT, NULL, 0, 0, NULL, :STEP_ID, NULL, :USER_ID, 'F', + :D_NUM, :SHARE, :D_REG_1, :D_REG_2, :D_REG_3, :D_REG_4, :D_REG_5, :D_REG_6, /* дебет */ + :K_NUM, :SHARE, :K_REG_1, :K_REG_2, :K_REG_3, :K_REG_4, :K_REG_5, :K_REG_6) /* кредит */ + RETURNING_VALUES :WIR_ID, :WIR_LIST, :DEB_ID, :KRD_ID; + + /* СОСТОЯНИЕ ДОКУМЕНТА */ + UPDATE OD_DOCS SET STATE = :OUT_STATE WHERE ID = :OPER_ID; +END^ + + +/* Создаёт операцию «Зачисление»/«Списание» по строке M2M-поручения, входящую запись (отчёт НРД) и проводит + операцию. Возвращает OPER_ID. */ +CREATE OR ALTER PROCEDURE FTV_M2M_PROCESS_OPERATION (GUID CHAR(36), REFERENCE VARCHAR(255), OPER_DATE TIMESTAMP, PARAMETERS VARCHAR(4000)) +RETURNS (OPER_ID INTEGER) AS +DECLARE VARIABLE WHOS INTEGER; +DECLARE VARIABLE ACC_D INTEGER; +DECLARE VARIABLE ACC_K INTEGER; +DECLARE VARIABLE MARKET INTEGER; +DECLARE VARIABLE B_TYPE INTEGER; +DECLARE VARIABLE CORR_FACE INTEGER; +DECLARE VARIABLE FILER_CAT INTEGER; +DECLARE VARIABLE RUBRICA INTEGER; +DECLARE VARIABLE CLISER_ID INTEGER; +DECLARE VARIABLE CLISER_NUM VARCHAR(64); +DECLARE VARIABLE CLISER_DATE TIMESTAMP; +DECLARE VARIABLE DIRECTION VARCHAR(64); +DECLARE VARIABLE DD_DATE DATE; +DECLARE VARIABLE DD_NUM VARCHAR(64); +DECLARE VARIABLE SHARE INTEGER; +DECLARE VARIABLE AMOUNT NUMERIC(18,7); +DECLARE VARIABLE CLIENT INTEGER; +DECLARE VARIABLE FACE INTEGER; +DECLARE VARIABLE PLACE INTEGER; +DECLARE VARIABLE D_CAT INTEGER; +DECLARE VARIABLE NUM VARCHAR(255); +DECLARE VARIABLE NEW_DATE TIMESTAMP; +DECLARE VARIABLE FILER_ID INTEGER; +DECLARE VARIABLE FILER_NUM VARCHAR(255); +DECLARE VARIABLE FILER_DATE TIMESTAMP; +DECLARE VARIABLE STEP_ID INTEGER; +DECLARE VARIABLE P VARCHAR(4000); +DECLARE VARIABLE REP_NUM VARCHAR(255); +DECLARE VARIABLE REP_DATE DATE; +DECLARE VARIABLE CMT VARCHAR(4000); +BEGIN + EXECUTE PROCEDURE FTV_M2M_GET('WHOS') RETURNING_VALUES :WHOS; + EXECUTE PROCEDURE FTV_M2M_GET('D_NUM') RETURNING_VALUES :ACC_D; + EXECUTE PROCEDURE FTV_M2M_GET('K_NUM') RETURNING_VALUES :ACC_K; + EXECUTE PROCEDURE FTV_M2M_GET('MARKET') RETURNING_VALUES :MARKET; + EXECUTE PROCEDURE FTV_M2M_GET('B_TYPE') RETURNING_VALUES :B_TYPE; + EXECUTE PROCEDURE FTV_M2M_GET('CORR_FACE') RETURNING_VALUES :CORR_FACE; + EXECUTE PROCEDURE FTV_M2M_GET('FILER_CAT') RETURNING_VALUES :FILER_CAT; + EXECUTE PROCEDURE FTV_M2M_GET('FILER_RUBRICA') RETURNING_VALUES :RUBRICA; + + SELECT FIRST 1 H.DOC, D.NUM, D.D_DATE, + CASE WHEN DC.SYS_NAME = 'I_CLISER_M2M_ZACH' THEN 'IN' WHEN DC.SYS_NAME = 'I_CLISER_M2M_SPIS' THEN 'OUT' END, + CAST(D.D_DATE AS DATE), D.NUM, F.SHARE, F.AMOUNT, F.CLIENT, H.DEPONENT, F.PLACE + FROM D_CLISER_M2M_DOL F + LEFT JOIN OD_DOLS L ON L.ID = F.DOL + LEFT JOIN OD_DOCS D ON D.ID = L.DOC + LEFT JOIN D_CLISER_M2M H ON H.DOC = D.ID + LEFT JOIN OD_DOC_CATS DC ON DC.ID = D.D_CAT + WHERE H.DOC_GUID = :GUID AND F.DOL_REF = :REFERENCE + INTO :CLISER_ID, :CLISER_NUM, :CLISER_DATE, :DIRECTION, :DD_DATE, :DD_NUM, :SHARE, :AMOUNT, :CLIENT, :FACE, :PLACE; + + IF (CLISER_ID IS NULL) THEN + EXECUTE PROCEDURE FTV_M2M_FAIL('Не найдено M2M-поручение по GUID + REFERENCE'); + + /* Направление */ + SELECT FIRST 1 DC.ID FROM OD_DOC_CATS DC + WHERE DC.SYS_NAME = CASE WHEN :DIRECTION = 'IN' THEN 'OP_INV_ZACH' ELSE 'OP_INV_SPIS' END + INTO :D_CAT; + + /* ID и номер операции */ + OPER_ID = GEN_ID(OD_DOC_ID_GEN, 1); + EXECUTE PROCEDURE FU_NEXT_DOC_NUM (:D_CAT, :OPER_DATE, NULL, :OPER_ID) RETURNING_VALUES :NUM, :NEW_DATE; + NUM = NUM || '_' || REFERENCE; + + /* Документ */ + INSERT INTO OD_DOCS (ID, NUM, PARAM, D_CAT, D_DATE, STATE, DIRECTION, WHOS, KVIT) + VALUES (:OPER_ID, :NUM, NULL, :D_CAT, :OPER_DATE, 0, 0, :WHOS, :CLISER_ID); + + IF (DIRECTION = 'IN') THEN + BEGIN + CMT = 'Отчет НКО АО НРД ' || COALESCE(PARAMETERS, '') || '. Перевод M2M (без поручения), GUID ' || GUID || ', референс ' || REFERENCE; + INSERT INTO U_OP_INV_ZACH + (DOC, DD_TYPE, DD_DATE, DD_NUM, SHARE, AMOUNT, BLANKS, PLACE, D_NUM, DEPO, K_NUM, MARKET, + CONDITION, IS_REG, TAX_R, B_TYPE, B_DATE, B_NUM, WIR_DATE, NOTIFY_DATE, REG_DATE, IS_BLOCK, FROM_FACE, REJECT_REASON, "COMMENT") + VALUES + (:OPER_ID, 1 /* клиентское */, :DD_DATE, :DD_NUM, :SHARE, :AMOUNT, NULL, :PLACE, :ACC_D, :CLIENT, :ACC_K, :MARKET, + NULL, NULL, NULL, :B_TYPE, :CLISER_DATE, :CLISER_NUM, :OPER_DATE, :OPER_DATE, :OPER_DATE, 0, :FACE, NULL, :CMT); + END + ELSE IF (DIRECTION = 'OUT') THEN + BEGIN + CMT = 'Отчет НКО АО НРД ' || COALESCE(PARAMETERS, '') || '. Перевод M2M, GUID ' || GUID || ', референс ' || REFERENCE; + INSERT INTO U_OP_INV_SPIS + (DOC, DD_TYPE, DD_DATE, DD_NUM, SHARE, AMOUNT, BLANKS, PLACE, D_NUM, DEPO, K_NUM, MARKET, + OLD_CONDITIONS, IS_REG, TAX_R, B_TYPE, B_DATE, B_NUM, WIR_DATE, NOTIFY_DATE, REG_DATE, IS_BLOCK, FROM_FACE, REJECT_REASON, "COMMENT") + VALUES + (:OPER_ID, 1 /* клиентское */, :DD_DATE, :DD_NUM, :SHARE, :AMOUNT, NULL, :PLACE, :ACC_D, :CLIENT, :ACC_K, :MARKET, + NULL, NULL, NULL, :B_TYPE, :CLISER_DATE, :CLISER_NUM, :OPER_DATE, :OPER_DATE, :OPER_DATE, 0, :FACE, NULL, :CMT); + END + + /* Входящая запись (отчёт НРД). PARAMETERS — «<номер отчёта> от <дд.мм.гггг>»: номер — до первого пробела, + дата — после последнего. */ + FILER_ID = GEN_ID(OD_DOC_ID_GEN, 1); + FILER_DATE = CURRENT_TIMESTAMP; + EXECUTE PROCEDURE FU_NEXT_DOC_NUM ('D_FILER', :FILER_DATE, 1, :FILER_ID) RETURNING_VALUES :FILER_NUM, :NEW_DATE; + INSERT INTO OD_DOCS (ID, NUM, D_CAT, D_DATE, STATE, DIRECTION, WHOS) + VALUES (:FILER_ID, :FILER_NUM, :FILER_CAT, :FILER_DATE, 2, 1, :WHOS); + + P = TRIM(PARAMETERS); + REP_NUM = LEFT(P, POSITION(' ' IN P || ' ') - 1); + REP_DATE = CAST(RIGHT(P, POSITION(' ' IN REVERSE(P)) - 1) AS DATE); + INSERT INTO D_FILER (DOC, PASS_KIND, RUBRICA, "COMMENT", DOC_NUM, DOC_DATE, CORR_FACE, FUND, ACCOUNT, PLACE, ORI_DATE, CHILD_CAT, MESS) + VALUES (:FILER_ID, 8, :RUBRICA, 'Отчет (перевод через MOEX-МОСТ)', :REP_NUM, :REP_DATE, :CORR_FACE, + :FACE, :CLIENT, :PLACE, :FILER_DATE, NULL, 'MS010 / ' || :GUID || ' / ' || :REFERENCE); + + /* Связь входящей записи с операцией */ + STEP_ID = GEN_ID(OD_STEPS_ID_GEN, 1); + INSERT INTO OD_STEPS (ID, DOC, A_DOC, ERR_CODE, S_TYPE, OUT_STATE, S_DATE, OPER) + VALUES (:STEP_ID, :FILER_ID, :OPER_ID, 2004, 0, 0, CURRENT_TIMESTAMP, NULL); + + /* И сразу проводим */ + EXECUTE PROCEDURE FTV_M2M_PROCESS_WIRING (:OPER_ID); +END^ + + +/* Обновление справочника участников сервиса: недостающие юрлица и коды M2M в Fancy, предупреждения о + двойниках по ИНН и расхождении кодов. Возвращает текст отчёта (пишется в COMMENT события HANDBOOK). */ +CREATE OR ALTER PROCEDURE FTV_M2M_UPDATE_HANDBOOK RETURNS (CMT BLOB SUB_TYPE TEXT) AS +DECLARE VARIABLE M2M_CODER INTEGER; +DECLARE VARIABLE CNT INTEGER; +DECLARE VARIABLE FACE_ID INTEGER; +DECLARE VARIABLE HB_ID INTEGER; +DECLARE VARIABLE RW INTEGER = 0; +DECLARE VARIABLE INN VARCHAR(12); +DECLARE VARIABLE CODE VARCHAR(64); +DECLARE VARIABLE CODE2 VARCHAR(64); +DECLARE VARIABLE NAME_SHORT VARCHAR(255); +DECLARE VARIABLE NAME_FULL VARCHAR(255); +DECLARE VARIABLE CRLF CHAR(2); +BEGIN + CRLF = ASCII_CHAR(13) || ASCII_CHAR(10); + SELECT FIRST 1 F.SELF_ID FROM OD_FACES F WHERE F.LAST_FLAG = 1 AND F.MNEM = 'M2M' INTO :M2M_CODER; + IF (M2M_CODER IS NULL) THEN + EXECUTE PROCEDURE FTV_M2M_FAIL('В Fancy нет кодировщика M2M (OD_FACES с MNEM = ''M2M'')'); + + /* 1. Статистика по участникам */ + SELECT COUNT(*) FROM OD_FACE_CODERS C WHERE C.CODER = :M2M_CODER INTO :CNT; + CMT = 'УЧАСТНИКИ СЕРВИСА: в справочнике юрлиц Фэнси - ' || CNT; + SELECT COUNT(*) FROM FTV_M2M_HANDBOOK WHERE ACTIVE = 1 AND PARTICIPANT_CODE IS NOT NULL INTO :CNT; + CMT = CMT || ', по данным НРД - ' || CNT; + + /* 2. Принудительно добавляем отсутствующих юрлиц */ + FOR SELECT HB.ID, HB.PARTICIPANT_CODE, HB.INN, HB.NAME_SHORT, HB.NAME_FULL + FROM FTV_M2M_HANDBOOK HB + WHERE HB.ACTIVE = 1 + AND HB.INN NOT IN (SELECT F.INN FROM OD_FACES F WHERE F.LAST_FLAG = 1 AND F.E_DATE = '9999-01-01' AND F.INN IS NOT NULL) + ORDER BY HB.NAME_SHORT + INTO :HB_ID, :CODE, :INN, :NAME_SHORT, :NAME_FULL DO + BEGIN + RW = RW + 1; + FACE_ID = GEN_ID(OD_FACES_ID_GEN, 1); + INSERT INTO OD_FACES (ID, S_TYPE, INN, NAME) VALUES (:FACE_ID, 1, :INN, :NAME_SHORT); + INSERT INTO OD_U_FACES (FACE, FULL_NAME) VALUES (:FACE_ID, :NAME_FULL); + INSERT INTO OD_FACE_CODERS (CODE, CODER, FACE) VALUES (:CODE, :M2M_CODER, :FACE_ID); + CMT = CMT || CRLF || RW || '. Добавлено юрлицо: ' || COALESCE(CODE, '') || ', ' || INN || ', ' || COALESCE(NAME_SHORT, ''); + END + + /* 3. Недостающие коды участников к существующим юрлицам, с предупреждением о двойниках по ИНН + (в подзапросе ИНН без NULL: иначе NOT IN не находит ни одной строки) */ + FOR SELECT HB.ID, HB.PARTICIPANT_CODE, HB.INN, HB.NAME_SHORT, MIN(F.SELF_ID), COUNT(*) + FROM FTV_M2M_HANDBOOK HB + LEFT JOIN OD_FACES F ON F.INN = HB.INN + LEFT JOIN OD_FACE_CODERS C ON C.CODER = :M2M_CODER AND F.SELF_ID = C.FACE + WHERE HB.ACTIVE = 1 + AND HB.PARTICIPANT_CODE IS NOT NULL + AND F.S_TYPE = 1 + AND F.LAST_FLAG = 1 + AND F.E_DATE = '9999-01-01' + AND C.CODE IS NULL + AND F.INN NOT IN (SELECT F2.INN FROM OD_FACE_CODERS C2 + JOIN OD_FACES F2 ON F2.SELF_ID = C2.FACE AND F2.LAST_FLAG = 1 AND F2.E_DATE = '9999-01-01' + WHERE C2.CODER = :M2M_CODER AND F2.INN IS NOT NULL) + GROUP BY HB.ID, HB.PARTICIPANT_CODE, HB.INN, HB.NAME_SHORT + ORDER BY HB.NAME_SHORT + INTO :HB_ID, :CODE, :INN, :NAME_SHORT, :FACE_ID, :CNT DO + BEGIN + RW = RW + 1; + INSERT INTO OD_FACE_CODERS (CODE, CODER, FACE) VALUES (:CODE, :M2M_CODER, :FACE_ID); + CMT = CMT || CRLF || RW || '. Добавлен код участника ' || CODE || ' к юрлицу: ' || INN || ', ' || COALESCE(NAME_SHORT, ''); + IF (CNT > 1) THEN + CMT = CMT || ' (ПРЕДУПРЕЖДЕНИЕ: в Фэнси найдено несколько юрлиц с ИНН ' || INN || ')'; + END + + IF (RW = 0) THEN + CMT = CMT || ' (при обработке нового справочника НРД никаких изменений не обнаружено)'; + + /* 4. Отличающиеся коды в Fancy и НРД для одного юрлица (по ИНН) или лишние коды в Fancy */ + FOR SELECT F.INN, F.NAME, C.CODE, HB.PARTICIPANT_CODE + FROM OD_FACE_CODERS C + LEFT JOIN OD_FACES F ON F.SELF_ID = C.FACE AND F.LAST_FLAG = 1 AND F.E_DATE = '9999-01-01' + LEFT JOIN FTV_M2M_HANDBOOK HB ON HB.INN = F.INN AND HB.ACTIVE = 1 AND HB.PARTICIPANT_CODE IS NOT NULL + WHERE C.CODER = :M2M_CODER + AND (C.CODE <> HB.PARTICIPANT_CODE OR HB.PARTICIPANT_CODE IS NULL) + INTO :INN, :NAME_SHORT, :CODE, :CODE2 DO + BEGIN + RW = RW + 1; + IF (CODE2 IS NULL) THEN + CMT = CMT || CRLF || 'КРИТИЧЕСКОЕ ПРЕДУПРЕЖДЕНИЕ: для юрлица ' || COALESCE(INN, '?') || ' (' || COALESCE(NAME_SHORT, '') || ') в Фэнси указан код ' || CODE || ', отсутствующий в НРД'; + ELSE + CMT = CMT || CRLF || 'КРИТИЧЕСКОЕ ПРЕДУПРЕЖДЕНИЕ: для юрлица ' || COALESCE(INN, '?') || ' (' || COALESCE(NAME_SHORT, '') || ') в Фэнси указан код ' || CODE || ', отличающийся от кода в НРД ' || CODE2; + END +END^ + + +/* Обработка одного события FTV_M2M_EVENTS. Ссылки — https://lic.zetit.ru/docs/fancy-events */ +CREATE OR ALTER PROCEDURE FTV_M2M_PROCESS_EVENTS (ID INTEGER) AS +DECLARE VARIABLE GUID CHAR(36); +DECLARE VARIABLE REFERENCE VARCHAR(255); +DECLARE VARIABLE EVENT_TYPE VARCHAR(64); +DECLARE VARIABLE EVENT_DATE TIMESTAMP; +DECLARE VARIABLE M2M_REJECT_CODE VARCHAR(1000); +DECLARE VARIABLE PARAMETERS VARCHAR(4000); +DECLARE VARIABLE DIRECTION VARCHAR(64); +DECLARE VARIABLE CMT BLOB SUB_TYPE TEXT; +DECLARE VARIABLE SHARE INTEGER; +DECLARE VARIABLE AMOUNT NUMERIC(18,7); +DECLARE VARIABLE PLACE INTEGER; +DECLARE VARIABLE CLIENT INTEGER; +DECLARE VARIABLE FACE INTEGER; +DECLARE VARIABLE CLISER_ID INTEGER; +DECLARE VARIABLE DOL_ID INTEGER; +DECLARE VARIABLE DD_DATE DATE; +DECLARE VARIABLE DD_NUM VARCHAR(64); +DECLARE VARIABLE OPER_ID INTEGER; +DECLARE VARIABLE ST INTEGER; +DECLARE VARIABLE EV_S VARCHAR(19); +DECLARE VARIABLE NOW_S VARCHAR(19); +BEGIN + SELECT FIRST 1 ME.GUID, ME.REFERENCE, ME.EVENT_TYPE, ME.EVENT_DATE, ME.M2M_REJECT_CODE, ME.PARAMETERS, M.DIRECTION, + H.DOC, F.DOL, CAST(D.D_DATE AS DATE), D.NUM, F.SHARE, F.AMOUNT, F.PLACE, F.CLIENT, H.DEPONENT + FROM FTV_M2M_EVENTS ME + LEFT JOIN FTV_M2M M ON M.GUID = ME.GUID + LEFT JOIN D_CLISER_M2M_DOL F ON F.DOL_REF = ME.REFERENCE + LEFT JOIN D_CLISER_M2M H ON H.DOC_GUID = ME.GUID + LEFT JOIN OD_DOCS D ON D.ID = H.DOC + WHERE ME.ID = :ID + INTO :GUID, :REFERENCE, :EVENT_TYPE, :EVENT_DATE, :M2M_REJECT_CODE, :PARAMETERS, :DIRECTION, + :CLISER_ID, :DOL_ID, :DD_DATE, :DD_NUM, :SHARE, :AMOUNT, :PLACE, :CLIENT, :FACE; + + /* 1. Обновление справочника участников сервиса */ + IF (EVENT_TYPE = 'HANDBOOK') THEN + BEGIN + EXECUTE PROCEDURE FTV_M2M_UPDATE_HANDBOOK RETURNING_VALUES :CMT; + UPDATE FTV_M2M_EVENTS SET "COMMENT" = :CMT WHERE ID = :ID; + EXIT; + END + + /* 1a. BJ_PING — проверочное событие bj (без GUID и REFERENCE): отметить обработанным, документ не трогать */ + IF (EVENT_TYPE = 'BJ_PING') THEN EXIT; + + /* 2. Критические ошибки */ + IF (GUID IS NULL) THEN EXECUTE PROCEDURE FTV_M2M_FAIL('Не указан GUID'); + IF (REFERENCE IS NULL) THEN EXECUTE PROCEDURE FTV_M2M_FAIL('Не указан REFERENCE'); + IF (DOL_ID IS NULL) THEN EXECUTE PROCEDURE FTV_M2M_FAIL('Не найдена строка M2M-поручения по GUID + REFERENCE'); + + /* 3. Признак документа */ + EXECUTE PROCEDURE FTV_M2M_DT(:EVENT_DATE) RETURNING_VALUES :EV_S; + EXECUTE PROCEDURE FTV_M2M_DT(CURRENT_TIMESTAMP) RETURNING_VALUES :NOW_S; + INSERT INTO OD_INVALIDS (DOC, STATUS, "COMMENT", DO_ING) + VALUES (:CLISER_ID, 0, + :EV_S || ' - ' || :EVENT_TYPE || COALESCE(' (референс - ' || :REFERENCE || ')', '') || COALESCE(' (параметры - ' || :PARAMETERS || ')', ''), + 'Время начала обработки: ' || :NOW_S); + + /* 4. Обработка каждого типа события. ID = 0 в UPDATE OD_DOCS — служебное изменение Fancy (триггер оставляет + прежний ID и не проверяет права оператора). */ + IF (EVENT_TYPE = 'BJ_RECEIVED') THEN + UPDATE OD_DOCS SET ID = 0, STATE = 1 WHERE ID = :CLISER_ID; /* START — начало обработки */ + ELSE IF (EVENT_TYPE = 'BJ_SENT') THEN + BEGIN + ST = NULL; + SELECT FIRST 1 S.ID FROM OD_DOC_STATES S WHERE S.SYS_NAME = 'WAIT_RESP_DECIS' INTO :ST; + UPDATE OD_DOCS SET ID = 0, STATE = :ST WHERE ID = :CLISER_ID; /* ожидание ответа Response/Decision */ + END + ELSE IF (EVENT_TYPE IN ('BJ_DECISION_CONFIRM', 'BJ_CP_CONFIRM')) THEN + UPDATE OD_DOCS SET ID = 0, STATE = 8 WHERE ID = :CLISER_ID; /* RECIEVED — принят, ожидает обработки */ + ELSE IF (EVENT_TYPE IN ('BJ_DECISION_REJECT', 'BJ_CP_REJECT')) THEN + UPDATE OD_DOCS SET ID = 0, STATE = 3 WHERE ID = :CLISER_ID; /* REJECT — отмена обработки */ + ELSE IF (EVENT_TYPE = 'BJ_SERVICE_ERROR') THEN + UPDATE OD_DOCS SET ID = 0, STATE = 3 WHERE ID = :CLISER_ID; + ELSE IF (EVENT_TYPE = 'BJ_ORDER_SENT') THEN + BEGIN + ST = NULL; + SELECT FIRST 1 S.ID FROM OD_DOC_STATES S WHERE S.SYS_NAME = 'WAIT_OPER' INTO :ST; + UPDATE OD_DOCS SET ID = 0, STATE = :ST WHERE ID = :CLISER_ID; /* ожидание исполнения операции */ + END + ELSE IF (EVENT_TYPE = 'BJ_ORDER_ACCEPTED') THEN + BEGIN + EXECUTE PROCEDURE FTV_M2M_PROCESS_OPERATION (:GUID, :REFERENCE, :EVENT_DATE, :PARAMETERS) RETURNING_VALUES :OPER_ID; + UPDATE OD_DOCS SET ID = 0, STATE = 2 WHERE ID = :CLISER_ID; /* FINAL — конец обработки */ + END + ELSE IF (EVENT_TYPE = 'BJ_EXECUTED') THEN + EXIT; /* уже исполнено по BJ_ORDER_ACCEPTED */ + ELSE IF (EVENT_TYPE = 'BJ_CANCELLED') THEN + UPDATE OD_DOCS SET ID = 0, STATE = 3 WHERE ID = :CLISER_ID; + ELSE IF (EVENT_TYPE = 'BJ_GATEWAY_REJECT') THEN + UPDATE OD_DOCS SET ID = 0, STATE = 3 WHERE ID = :CLISER_ID; + ELSE IF (EVENT_TYPE IN ('BJ_ORDER_LATE', 'BJ_QUIK_BLOCKED', 'BJ_QUIK_RELEASED', 'BJ_QUIK_SIGNED', 'BJ_QUIK_DEPOSITED')) THEN + EXIT; /* ничего не делать */ + ELSE + EXECUTE PROCEDURE FTV_M2M_FAIL('От сервиса BJ получено неизвестное событие ' || EVENT_TYPE); +END^ + + +/* Создаёт M2M-поручение вместе с подвалом документа по записи FTV_M2M. */ +CREATE OR ALTER PROCEDURE FTV_M2M_PROCESS_CREATE (ID INTEGER) AS +DECLARE VARIABLE WHOS INTEGER; +DECLARE VARIABLE FILER_CAT INTEGER; +DECLARE VARIABLE GUID CHAR(36); +DECLARE VARIABLE DIRECTION VARCHAR(64); +DECLARE VARIABLE CONTRAGENT_M2M_CODE VARCHAR(255); +DECLARE VARIABLE DEPONENT_NAME VARCHAR(255); +DECLARE VARIABLE DEPONENT_DOC VARCHAR(255); +DECLARE VARIABLE REFERENCE VARCHAR(36); +DECLARE VARIABLE ISIN VARCHAR(12); +DECLARE VARIABLE SEC_CODE VARCHAR(255); +DECLARE VARIABLE AMOUNT NUMERIC(18,7); +DECLARE VARIABLE PLACE_NUMBER VARCHAR(255); +DECLARE VARIABLE LINK_NUMBER VARCHAR(128); +DECLARE VARIABLE DEPO_NUMBER VARCHAR(128); +DECLARE VARIABLE D_CAT INTEGER; +DECLARE VARIABLE NUM VARCHAR(255); +DECLARE VARIABLE NEW_DATE TIMESTAMP; +DECLARE VARIABLE D_DATE TIMESTAMP; +DECLARE VARIABLE CONTRAGENT INTEGER; +DECLARE VARIABLE DEPONENT INTEGER; +DECLARE VARIABLE SHARE INTEGER; +DECLARE VARIABLE PLACE INTEGER; +DECLARE VARIABLE DEPO INTEGER; +DECLARE VARIABLE CLISER_ID INTEGER; +DECLARE VARIABLE FILER_ID INTEGER; +DECLARE VARIABLE FILER_NUM VARCHAR(255); +DECLARE VARIABLE FILER_DATE TIMESTAMP; +DECLARE VARIABLE DOL_ID INTEGER; +BEGIN + EXECUTE PROCEDURE FTV_M2M_GET('WHOS') RETURNING_VALUES :WHOS; + + SELECT M.GUID, M.DIRECTION, M.CONTRAGENT_M2M_CODE, M.DEPONENT_NAME, M.DEPONENT_DOC FROM FTV_M2M M WHERE M.ID = :ID + INTO :GUID, :DIRECTION, :CONTRAGENT_M2M_CODE, :DEPONENT_NAME, :DEPONENT_DOC; + + /* 1.1. Неуникальный GUID */ + IF (EXISTS (SELECT 1 FROM D_CLISER_M2M WHERE DOC_GUID = :GUID)) THEN + EXECUTE PROCEDURE FTV_M2M_FAIL('Неуникальный GUID'); + + /* 1.2. Направление перевода */ + IF (DIRECTION = 'IN') THEN + SELECT FIRST 1 C.ID FROM OD_DOC_CATS C WHERE C.SYS_NAME = 'I_CLISER_M2M_ZACH' INTO :D_CAT; + ELSE IF (DIRECTION = 'OUT') THEN + SELECT FIRST 1 C.ID FROM OD_DOC_CATS C WHERE C.SYS_NAME = 'I_CLISER_M2M_SPIS' INTO :D_CAT; + ELSE + EXECUTE PROCEDURE FTV_M2M_FAIL('Ошибочное направление DIRECTION (должно быть IN, OUT)'); + + /* 1.3. Контрагент */ + SELECT FIRST 1 C.FACE FROM OD_FACE_CODERS C + LEFT JOIN OD_FACES F ON F.SELF_ID = C.CODER AND F.LAST_FLAG = 1 + WHERE F.MNEM = 'M2M' AND C.CODE = :CONTRAGENT_M2M_CODE + INTO :CONTRAGENT; + IF (CONTRAGENT IS NULL) THEN + EXECUTE PROCEDURE FTV_M2M_FAIL('Не найден депозитарий-контрагент'); + + /* 1.4. Депонент (как в MSSQL-версии: не найден — поручение создаётся без депонента) */ + SELECT FIRST 1 F.SELF_ID FROM OD_FACES F + WHERE F.LAST_FLAG = 1 + AND REPLACE(F.NAME, ' ', '') = REPLACE(:DEPONENT_NAME, ' ', '') + AND REPLACE(F.DOC_SER || F.DOC_NUM, ' ', '') = REPLACE(:DEPONENT_DOC, ' ', '') + INTO :DEPONENT; + + /* 1.5. Шапка документа */ + CLISER_ID = GEN_ID(OD_DOC_ID_GEN, 1); + D_DATE = CURRENT_TIMESTAMP; + EXECUTE PROCEDURE FU_NEXT_DOC_NUM (:D_CAT, :D_DATE, NULL, :CLISER_ID) RETURNING_VALUES :NUM, :NEW_DATE; + + INSERT INTO OD_DOCS (ID, NUM, PARAM, D_CAT, D_DATE, STATE, DIRECTION, WHOS, KVIT) + VALUES (:CLISER_ID, :NUM, NULL, :D_CAT, :D_DATE, 0, 0, :WHOS, NULL); + INSERT INTO D_CLISER_M2M (DOC, DEPONENT, DOC_GUID, DOC_STATUS, IIS_TYPE, IIS_INN, IIS_NUM, IIS_DATE) + VALUES (:CLISER_ID, :DEPONENT, :GUID, 0, 0, NULL, NULL, NULL); + IF (DIRECTION = 'IN') THEN + INSERT INTO OD_IN_DOCS (DOC, FROM_FACE, PASS_KIND) VALUES (:CLISER_ID, :CONTRAGENT, 8); + ELSE + INSERT INTO OD_OUT_DOCS (DOC, TO_FACE, PASS_KIND) VALUES (:CLISER_ID, :CONTRAGENT, 8); + + /* 1.6. Обогащаем FTV_M2M */ + UPDATE FTV_M2M SET DOC = :CLISER_ID, CONTRAGENT = :CONTRAGENT, DEPONENT = :DEPONENT WHERE GUID = :GUID; + + /* 1.7. Подвал документа */ + FOR SELECT ML.REFERENCE, ML.ISIN, ML.SEC_CODE, ML.AMOUNT, ML.PLACE_NUMBER, ML.LINK_NUMBER, ML.DEPO_NUMBER + FROM FTV_M2M_LINES ML JOIN FTV_M2M M ON M.GUID = ML.GUID + WHERE ML.GUID = :GUID AND ML.STATE = 'TODO' + ORDER BY ML.ID + INTO :REFERENCE, :ISIN, :SEC_CODE, :AMOUNT, :PLACE_NUMBER, :LINK_NUMBER, :DEPO_NUMBER DO + BEGIN + SHARE = NULL; PLACE = NULL; DEPO = NULL; + + /* Бумага */ + SELECT FIRST 1 V.ID FROM OD_VALUES V + LEFT JOIN OD_VALUE_CODERS C ON C.SHARE = V.ID + LEFT JOIN OD_FACES F ON F.SELF_ID = C.CODER AND F.LAST_FLAG = 1 + WHERE V.ISIN = :ISIN AND F.MNEM = 'НДЦ' AND C.CODE = :SEC_CODE + INTO :SHARE; + + /* Счёт места хранения */ + SELECT FIRST 1 C.ID FROM OD_CLIENTS C + LEFT JOIN OD_CLIENTS_REC CR ON CR.CLIENT = C.SELF_ID AND CR.E_DATE = '9999-01-01' + WHERE C.NUMBER LIKE '%' || :PLACE_NUMBER || '%' AND CR.LINK_NUMBER = :LINK_NUMBER + INTO :PLACE; + + /* Счёт клиента */ + SELECT FIRST 1 C.ID FROM OD_CLIENTS C WHERE C.NUMBER = :DEPO_NUMBER INTO :DEPO; + + DOL_ID = GEN_ID(OD_DOL_ID_GEN, 1); + INSERT INTO OD_DOLS (ID, DOC) VALUES (:DOL_ID, :CLISER_ID); + INSERT INTO D_CLISER_M2M_DOL (DOL, SHARE, AMOUNT, DOL_REF, PLACE, CLIENT) VALUES (:DOL_ID, :SHARE, :AMOUNT, :REFERENCE, :PLACE, :DEPO); + + UPDATE FTV_M2M_LINES SET STATE = 'SUCCESS', DOC = :CLISER_ID, DOL = :DOL_ID, SHARE = :SHARE, PLACE = :PLACE, DEPO = :DEPO + WHERE GUID = :GUID AND REFERENCE = :REFERENCE; + END + + /* 1.8. Входящая запись — только для списания (исходящий перевод OUT) */ + IF (DIRECTION = 'OUT') THEN + BEGIN + EXECUTE PROCEDURE FTV_M2M_GET('FILER_CAT') RETURNING_VALUES :FILER_CAT; + FILER_ID = GEN_ID(OD_DOC_ID_GEN, 1); + FILER_DATE = CURRENT_TIMESTAMP; + EXECUTE PROCEDURE FU_NEXT_DOC_NUM ('D_FILER', :FILER_DATE, 1, :FILER_ID) RETURNING_VALUES :FILER_NUM, :NEW_DATE; + INSERT INTO OD_DOCS (ID, NUM, D_CAT, D_DATE, STATE, DIRECTION, WHOS) + VALUES (:FILER_ID, :FILER_NUM, :FILER_CAT, :FILER_DATE, 2, 1, :WHOS); + INSERT INTO D_FILER (DOC, PASS_KIND, RUBRICA, "COMMENT", DOC_NUM, DOC_DATE, CORR_FACE, FUND, ACCOUNT, PLACE, ORI_DATE, CHILD_CAT, MESS) + VALUES (:FILER_ID, 7, 8, 'M2M поручение на списание через MOEX-МОСТ', :NUM, CAST(:D_DATE AS DATE), :DEPONENT, :DEPONENT, + :DEPO, :PLACE, :FILER_DATE, :D_CAT, :GUID); + /* Связываем с M2M-поручением */ + UPDATE OD_DOCS SET ID = 0, KVIT = :FILER_ID WHERE ID = :CLISER_ID; + END +END^ + + +/* Запуск обработки: новые поручения (FTV_M2M) и события (FTV_M2M_EVENTS) со STATE = 'TODO'. Вызывает bj + (в Firebird нет SQL Server Agent). Ошибка одной записи не останавливает остальные. */ +CREATE OR ALTER PROCEDURE FTV_M2M_JOB AS +DECLARE VARIABLE ID INTEGER; +DECLARE VARIABLE ST VARCHAR(64); +DECLARE VARIABLE CMT VARCHAR(1000); +DECLARE VARIABLE R INTEGER; +BEGIN + /* НОВЫЕ ПОРУЧЕНИЯ */ + FOR SELECT M.ID FROM FTV_M2M M WHERE M.STATE = 'TODO' ORDER BY M.TIMENEW, M.ID INTO :ID DO + BEGIN + UPDATE FTV_M2M SET TIMEBEG = CURRENT_TIMESTAMP WHERE ID = :ID; + ST = 'SUCCESS'; CMT = NULL; + R = RDB$SET_CONTEXT('USER_TRANSACTION', 'FTV_M2M_ERR', NULL); + BEGIN + EXECUTE PROCEDURE FTV_M2M_PROCESS_CREATE (:ID); + WHEN ANY DO + BEGIN + ST = 'ERROR'; + CMT = COALESCE(CAST(RDB$GET_CONTEXT('USER_TRANSACTION', 'FTV_M2M_ERR') AS VARCHAR(255) CHARACTER SET WIN1251), 'ошибка Fancy') || ' // FTV_M2M_PROCESS_CREATE // SQLCODE ' || SQLCODE || ', GDSCODE ' || GDSCODE; + END + END + UPDATE FTV_M2M SET STATE = :ST, TIMEEND = CURRENT_TIMESTAMP, "COMMENT" = :CMT WHERE ID = :ID; + END + + /* НОВЫЕ СОБЫТИЯ */ + FOR SELECT E.ID FROM FTV_M2M_EVENTS E WHERE E.STATE = 'TODO' ORDER BY E.TIMENEW, E.ID INTO :ID DO + BEGIN + UPDATE FTV_M2M_EVENTS SET TIMEBEG = CURRENT_TIMESTAMP WHERE ID = :ID; + ST = 'SUCCESS'; CMT = NULL; + R = RDB$SET_CONTEXT('USER_TRANSACTION', 'FTV_M2M_ERR', NULL); + BEGIN + EXECUTE PROCEDURE FTV_M2M_PROCESS_EVENTS (:ID); + WHEN ANY DO + BEGIN + ST = 'ERROR'; + CMT = COALESCE(CAST(RDB$GET_CONTEXT('USER_TRANSACTION', 'FTV_M2M_ERR') AS VARCHAR(255) CHARACTER SET WIN1251), 'ошибка Fancy') || ' // FTV_M2M_PROCESS_EVENTS // SQLCODE ' || SQLCODE || ', GDSCODE ' || GDSCODE; + END + END + /* без ошибки COMMENT не трогаем: в нём отчёт справочника (HANDBOOK) */ + IF (CMT IS NOT NULL) THEN + UPDATE FTV_M2M_EVENTS SET STATE = :ST, TIMEEND = CURRENT_TIMESTAMP, "COMMENT" = :CMT WHERE ID = :ID; + ELSE + UPDATE FTV_M2M_EVENTS SET STATE = :ST, TIMEEND = CURRENT_TIMESTAMP WHERE ID = :ID; + END +END^ + +SET TERM ; ^ + +COMMIT; diff --git a/deploy/depo/fancy-m2m-firebird/20_FTV_M2M_GRANTS.sql b/deploy/depo/fancy-m2m-firebird/20_FTV_M2M_GRANTS.sql new file mode 100644 index 0000000..3a94616 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/20_FTV_M2M_GRANTS.sql @@ -0,0 +1,346 @@ +/* Bridge&Join — права для процедур обработки M2M (Firebird 2.5). + Процедуры работают правами, выданными им самим: логину bj нужно только EXECUTE на FTV_M2M_JOB и доступ к + таблицам обмена FTV_M2M*. Выполнять под SYSDBA или владельцем базы. :BJ_USER — логин bj (подставляет bj). */ + +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_FAIL; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_FAIL; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_GET; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_GET; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_GET; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_DT; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_DT; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_DT; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_PROCESS_WIRING; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_PROCESS_OPERATION; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_UPDATE_HANDBOOK; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_PROCESS_EVENTS; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO PROCEDURE FTV_M2M_PROCESS_CREATE; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_DOCS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_FACES TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_FACE_CODERS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_U_FACES TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_DOLS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_STEPS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_IN_DOCS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_OUT_DOCS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON OD_INVALIDS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON D_CLISER_M2M_DOL TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON D_FILER TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_ZACH TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT, INSERT, UPDATE ON U_OP_INV_SPIS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_CLIENTS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_CLIENTS_REC TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_DOC_CATS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_DOC_STATES TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_VALUES TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_VALUE_CODERS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_SYS_TABS TO PROCEDURE FTV_M2M_JOB; +GRANT SELECT ON OD_STEP_TYPES TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FU_NEXT_DOC_NUM TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE OD_PR_INS_WIRS TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_FAIL TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_GET TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_DT TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_WIRING TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_OPERATION TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_UPDATE_HANDBOOK TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_EVENTS TO PROCEDURE FTV_M2M_JOB; +GRANT EXECUTE ON PROCEDURE FTV_M2M_PROCESS_CREATE TO PROCEDURE FTV_M2M_JOB; + +/* логин bj: запуск обработки и запись в таблицы обмена */ +GRANT EXECUTE ON PROCEDURE FTV_M2M_JOB TO :BJ_USER; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M TO :BJ_USER; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_LINES TO :BJ_USER; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_EVENTS TO :BJ_USER; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_HANDBOOK TO :BJ_USER; +GRANT SELECT, INSERT, UPDATE, DELETE ON FTV_M2M_SETTINGS TO :BJ_USER; +COMMIT; diff --git a/deploy/depo/fancy-m2m-firebird/README.md b/deploy/depo/fancy-m2m-firebird/README.md new file mode 100644 index 0000000..f473a60 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/README.md @@ -0,0 +1,47 @@ +# Обмен M2M с Fancy DEPO на Firebird 2.5 + +Перенос трансферных таблиц и процедур обработки MSSQL-версии (`deploy/depo/fancy-m2m`, Фонтвьель, тексты от +22.10.2026) на Firebird 2.5. Логика процедур та же; отличия перечислены в шапке `10_FTV_M2M_PROCS.sql`. + +| Файл | Что делает | +|---|---| +| `00_FTV_M2M_TABLES.sql` | таблицы `FTV_M2M*`, генераторы и триггеры ID, исключение `FTV_M2M_ERROR`, таблица привязок `FTV_M2M_SETTINGS` | +| `10_FTV_M2M_PROCS.sql` | процедуры: `FTV_M2M_FAIL/GET/DT` (вспомогательные), `PROCESS_WIRING`, `PROCESS_OPERATION`, `UPDATE_HANDBOOK`, `PROCESS_EVENTS`, `PROCESS_CREATE`, `JOB` | +| `20_FTV_M2M_GRANTS.sql` | права процедурам на таблицы Fancy и логину bj (`:BJ_USER`) на `FTV_M2M_JOB` и таблицы обмена | +| `test/` | заглушки таблиц Fancy (по схеме MSSQL), прогон всех веток на встроенном Firebird 2.5.9 | + +Порядок установки: 00 → заполнить `FTV_M2M_SETTINGS` → 10 → 20 (под SYSDBA или владельцем базы). + +## Проверить и уточнить на базе клиента + +Процедуры проверены только на заглушках, собранных по схеме Fancy MSSQL. Fancy на MSSQL — перевод +Firebird-версии (`GEN_ID`, `f_*`, триггер `OD_DOCS_BU v4.59`), поэтому имена таблиц и колонок, скорее всего, +совпадают. Подтвердить на копии базы клиента: + +1. **Генераторы ID**: `OD_DOC_ID_GEN`, `OD_DOL_ID_GEN`, `OD_STEPS_ID_GEN`, `OD_FACES_ID_GEN` — есть ли с такими + именами (`SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS`). +2. **`FU_NEXT_DOC_NUM`**: параметры `(CAT_SYS_NAME, D_DATE, DIRECTION, FOR_DOC)`, возвращает `(NUM, NEW_DATE)`; + выполняемая (`EXECUTE PROCEDURE`), а не селективная. +3. **`OD_PR_INS_WIRS`**: 31 входной параметр в порядке MSSQL-версии, 4 выходных (`NEW_ID, WIR_LIST, DEB_ID, KRD_ID`). +4. **`D_CLISER_M2M.DOC_GUID`**: тип колонки. Процедуры пишут GUID строкой `CHAR(36)` в верхнем регистре; если + в Fancy это `CHAR(16) CHARACTER SET OCTETS` или строка с фигурными скобками — менять сравнение и запись. +5. **Флаги**: `OD_FACES.LAST_FLAG = 1`, `E_DATE = '9999-01-01'`, `OD_CLIENTS_REC.E_DATE = '9999-01-01'` — те же + значения в Firebird-версии (не `'T'`/`'F'`). +6. **Оператор**: под каким логином bj подключается к базе и заведён ли он в `OD_OPERATORS` (`USER_ID` = логин). + `FU_NEXT_DOC_NUM` берёт `WHOS` и префикс номера из `OD_OPERATORS`/`OD_SETS` по текущему пользователю; триггеры + Fancy проверяют права оператора (кроме `UPDATE … ID = 0`). В MSSQL-версии это обходилось `execute as SYSDBA`. +7. **Привязки `FTV_M2M_SETTINGS`** — ID из справочников клиента: `WHOS` (депозитарий), `OPER_USER`, `FILER_CAT` + (категория `D_FILER`), `D_NUM`/`K_NUM` (балансовые счета 98010 и 98070), `MARKET` (Мосбиржа), `B_TYPE` + («Отчёт депозитария» в `DEPO96_DCLA`), `CORR_FACE` (НКО АО НРД), `FILER_RUBRICA`. +8. **Справочники по имени**: категории `I_CLISER_M2M_ZACH/SPIS`, `OP_INV_ZACH/SPIS`; состояния `WAIT_RESP_DECIS`, + `WAIT_OPER`; директива `PROCESS`; кодировщики `OD_FACES.MNEM = 'M2M'` и `'НДЦ'`. Таблицы `D_CLISER_M2M`, + `D_CLISER_M2M_DOL`, `U_OP_INV_ZACH/SPIS` — пользовательские (настройка M2M в Fancy), у клиента их может не быть. +9. **Кодировка базы**: WIN1251 (`RDB$DATABASE.RDB$CHARACTER_SET_NAME`). Текст ошибки из контекста приводится к + WIN1251 — при другой кодировке поменять в `FTV_M2M_JOB`. +10. **Числа состояний** в `PROCESS_EVENTS` (`STATE = 1, 2, 3, 8`) — как у Фонтвьель; сверить с `OD_DOC_STATES`. + +## Открытые вопросы логики (те же, что в MSSQL-версии) + +- `BJ_ORDER_REJECTED` не обрабатывается — уходит в «неизвестное событие» (вопрос программисту от 16.10.2026). +- `BJ_CP_CONFIRM` с направлением OUT перехватывается веткой `BJ_DECISION_CONFIRM` выше. +- Депонент не найден — поручение создаётся без депонента, ошибки нет. diff --git a/deploy/depo/fancy-m2m-firebird/test/run.sh b/deploy/depo/fancy-m2m-firebird/test/run.sh new file mode 100755 index 0000000..0601838 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/test/run.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Прогон процедур обмена M2M на встроенном Firebird 2.5.9 (Classic, без службы и сетевого порта). +# Заглушки Fancy (stub_fancy.sql) — колонки таблиц по схеме Fancy MSSQL и упрощённые FU_NEXT_DOC_NUM / OD_PR_INS_WIRS. +# Использование: deploy/depo/fancy-m2m-firebird/test/run.sh [рабочий каталог, по умолчанию /tmp/bj-fb25] +set -euo pipefail +D=$(cd "$(dirname "$0")/.." && pwd) +W=${1:-/tmp/bj-fb25} +mkdir -p "$W" +if [ ! -x "$W/fb/opt/firebird/bin/isql" ]; then + curl -fsSL -o "$W/fbcs.tar.gz" https://github.com/FirebirdSQL/firebird/releases/download/R2_5_9/FirebirdCS-2.5.9.27139-0.amd64.tar.gz + mkdir -p "$W/dl" "$W/fb" "$W/emb" "$W/lock" + tar -xzf "$W/fbcs.tar.gz" -C "$W/dl" + tar -xzf "$W"/dl/*/buildroot.tar.gz -C "$W/fb" + F="$W/fb/opt/firebird" + ln -sf "$(ls /usr/lib/x86_64-linux-gnu/libncurses.so.6* | head -1)" "$F/lib/libncurses.so.5" + ln -sf "$(ls /usr/lib/x86_64-linux-gnu/libtinfo.so.6* | head -1)" "$F/lib/libtinfo.so.5" + ln -sf "$F/lib/libfbembed.so.2.5" "$W/emb/libfbclient.so.2" +fi +export ISC_USER=SYSDBA ISC_PASSWORD=masterkey # встроенный режим: пароль не проверяется +export FIREBIRD="$W/fb/opt/firebird" FIREBIRD_LOCK="$W/lock" LD_LIBRARY_PATH="$W/emb:$W/fb/opt/firebird/lib" +ISQL="$FIREBIRD/bin/isql" +rm -f "$W/t.fdb" +printf "CREATE DATABASE '%s/t.fdb' DEFAULT CHARACTER SET WIN1251;\nCOMMIT;\n" "$W" > "$W/c.sql" +"$ISQL" -q -i "$W/c.sql" "$W/g.sql" +for f in "$D/test/stub_fancy.sql" "$D/00_FTV_M2M_TABLES.sql" "$D/10_FTV_M2M_PROCS.sql" "$W/g.sql" "$D/test/smoke.sql"; do + echo "== $(basename "$f")" + "$ISQL" -q -ch UTF8 -i "$f" "$W/t.fdb" &1 | sed -E 's/ {3,}/ /g' | { grep -v '^$' || true; } +done diff --git a/deploy/depo/fancy-m2m-firebird/test/smoke.sql b/deploy/depo/fancy-m2m-firebird/test/smoke.sql new file mode 100644 index 0000000..72f3d51 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/test/smoke.sql @@ -0,0 +1,48 @@ +/* Прогон процедур на заглушках Fancy: перевод IN (найден) и с неизвестным контрагентом; события PING, RECEIVED, + SENT, ORDER_ACCEPTED (операция, входящая запись, проводка), неизвестное, HANDBOOK. Привязки — значения Фонтвьель. */ +UPDATE FTV_M2M_SETTINGS SET VAL = CASE NAME WHEN 'WHOS' THEN 383118 WHEN 'OPER_USER' THEN 84 WHEN 'FILER_CAT' THEN 255 WHEN 'D_NUM' THEN 313 + WHEN 'K_NUM' THEN 836 WHEN 'MARKET' THEN 8106 WHEN 'B_TYPE' THEN 31 WHEN 'CORR_FACE' THEN 18174 WHEN 'FILER_RUBRICA' THEN 5 END; +INSERT INTO OD_FACES (ID, SELF_ID, LAST_FLAG, MNEM, NAME, E_DATE, S_TYPE) VALUES (1, 1, 1, 'M2M', 'Кодировщик M2M', '9999-01-01', 0); +INSERT INTO OD_FACES (ID, SELF_ID, LAST_FLAG, MNEM, NAME, E_DATE, S_TYPE) VALUES (2, 2, 1, 'НДЦ', 'Кодировщик НДЦ', '9999-01-01', 0); +INSERT INTO OD_FACES (ID, SELF_ID, LAST_FLAG, NAME, INN, E_DATE, S_TYPE) VALUES (10, 10, 1, 'АО Альфа', '7728168971', '9999-01-01', 1); +INSERT INTO OD_FACES (ID, SELF_ID, LAST_FLAG, NAME, DOC_SER, DOC_NUM, E_DATE, S_TYPE) VALUES (20, 20, 1, 'Лапшина Юлия Юрьевна', '4508', '147055', '9999-01-01', 0); +INSERT INTO OD_FACE_CODERS (CODE, CODER, FACE) VALUES ('MC000050MOST', 1, 10); +INSERT INTO OD_DOC_CATS (ID, SYS_NAME) VALUES (500, 'I_CLISER_M2M_ZACH'); +INSERT INTO OD_DOC_CATS (ID, SYS_NAME) VALUES (501, 'I_CLISER_M2M_SPIS'); +INSERT INTO OD_DOC_CATS (ID, SYS_NAME) VALUES (502, 'OP_INV_ZACH'); +INSERT INTO OD_DOC_CATS (ID, SYS_NAME) VALUES (503, 'OP_INV_SPIS'); +INSERT INTO OD_DOC_STATES (ID, SYS_NAME) VALUES (11, 'WAIT_RESP_DECIS'); +INSERT INTO OD_STEP_TYPES (ID, SYS_NAME, D_CAT, OUT_STATE) VALUES (77, 'PROCESS', 502, 2); +INSERT INTO OD_SYS_TABS (CODE, NUM, NAME) VALUES ('DEPO96_DCLA', 31, 'Отчет депозитария'); +INSERT INTO OD_VALUES (ID, ISIN) VALUES (300, 'RU000A0JVHH1'); +INSERT INTO OD_VALUE_CODERS (SHARE, CODER, CODE) VALUES (300, 2, 'RU000A0JVHH1'); +INSERT INTO OD_CLIENTS (ID, SELF_ID, FACE, NUMBER) VALUES (400, 400, 99, '36MC0413600000F00'); +INSERT INTO OD_CLIENTS_REC (CLIENT, E_DATE, LINK_NUMBER) VALUES (400, '9999-01-01', 'HL171004001C'); +INSERT INTO OD_CLIENTS (ID, SELF_ID, FACE, NUMBER) VALUES (401, 401, 20, 'ВТНКЦ00000060'); +INSERT INTO FTV_M2M_HANDBOOK (INN, PARTICIPANT_CODE, KIND, NAME_SHORT, NAME_FULL) VALUES ('7728168971', 'MC000050MOST', 'depo', 'АО «АЛЬФА-БАНК»', 'АКЦИОНЕРНОЕ ОБЩЕСТВО «АЛЬФА-БАНК»'); +INSERT INTO FTV_M2M_HANDBOOK (INN, PARTICIPANT_CODE, KIND, NAME_SHORT, NAME_FULL) VALUES ('7703807489', 'MC0413600000', 'depo', 'ООО "ИК "Фонтвьель"', 'ООО Инвестиционная Компания Фонтвьель'); +INSERT INTO FTV_M2M (GUID, DIRECTION, CONTRAGENT_M2M_CODE, DEPONENT_NAME, DEPONENT_DOC) VALUES ('bae1fa60-eb0a-4fee-b12c-018d1eafcbd2', 'IN', 'MC000050MOST', 'Лапшина Юлия Юрьевна', '4508 147055'); +INSERT INTO FTV_M2M_LINES (GUID, REFERENCE, ISIN, SEC_CODE, AMOUNT, PLACE_NUMBER, LINK_NUMBER, DEPO_NUMBER) VALUES ('BAE1FA60-EB0A-4FEE-B12C-018D1EAFCBD2', 'M2MREF_1', 'RU000A0JVHH1', 'RU000A0JVHH1', 11, '36MC0413600000F00', 'HL171004001C', 'ВТНКЦ00000060'); +INSERT INTO FTV_M2M (GUID, DIRECTION, CONTRAGENT_M2M_CODE, DEPONENT_NAME, DEPONENT_DOC) VALUES ('00000000-0000-4000-8000-000000000002', 'IN', 'MC9999999999', 'Никто', '0000 000000'); +COMMIT; +EXECUTE PROCEDURE FTV_M2M_JOB; +COMMIT; +INSERT INTO FTV_M2M_EVENTS (GUID, REFERENCE, EVENT_TYPE, EVENT_DATE) VALUES (NULL, NULL, 'BJ_PING', CURRENT_TIMESTAMP); +INSERT INTO FTV_M2M_EVENTS (GUID, REFERENCE, EVENT_TYPE, EVENT_DATE) VALUES ('BAE1FA60-EB0A-4FEE-B12C-018D1EAFCBD2', 'M2MREF_1', 'BJ_RECEIVED', CURRENT_TIMESTAMP); +INSERT INTO FTV_M2M_EVENTS (GUID, REFERENCE, EVENT_TYPE, EVENT_DATE) VALUES ('BAE1FA60-EB0A-4FEE-B12C-018D1EAFCBD2', 'M2MREF_1', 'BJ_SENT', CURRENT_TIMESTAMP); +INSERT INTO FTV_M2M_EVENTS (GUID, REFERENCE, EVENT_TYPE, EVENT_DATE, PARAMETERS) VALUES ('BAE1FA60-EB0A-4FEE-B12C-018D1EAFCBD2', 'M2MREF_1', 'BJ_ORDER_ACCEPTED', '2026-10-22 15:00:00', '1234567890 от 22.10.2026'); +INSERT INTO FTV_M2M_EVENTS (GUID, REFERENCE, EVENT_TYPE, EVENT_DATE) VALUES ('BAE1FA60-EB0A-4FEE-B12C-018D1EAFCBD2', 'M2MREF_1', 'BJ_WHATEVER', CURRENT_TIMESTAMP); +INSERT INTO FTV_M2M_EVENTS (EVENT_TYPE, EVENT_DATE) VALUES ('HANDBOOK', CURRENT_TIMESTAMP); +COMMIT; +EXECUTE PROCEDURE FTV_M2M_JOB; +COMMIT; +SET LIST ON; +SELECT ID, GUID, STATE, DOC, CONTRAGENT, DEPONENT, CAST("COMMENT" AS VARCHAR(300)) C FROM FTV_M2M; +SELECT ID, STATE, DOC, DOL, SHARE, PLACE, DEPO FROM FTV_M2M_LINES; +SELECT ID, EVENT_TYPE, STATE, CAST("COMMENT" AS VARCHAR(600)) C FROM FTV_M2M_EVENTS; +SELECT ID, NUM, D_CAT, STATE, KVIT, WHOS FROM OD_DOCS ORDER BY ID; +SELECT DOC, D_NUM, K_NUM, MARKET, B_TYPE, B_NUM, CAST("COMMENT" AS VARCHAR(300)) C FROM U_OP_INV_ZACH; +SELECT DOC, RUBRICA, DOC_NUM, DOC_DATE, CORR_FACE, MESS FROM D_FILER; +SELECT DOC, CAST("COMMENT" AS VARCHAR(300)) C, CAST(DO_ING AS VARCHAR(100)) D FROM OD_INVALIDS; +SELECT CODE, CODER, FACE FROM OD_FACE_CODERS; +SELECT ID, DOC, A_DOC, S_TYPE, OUT_STATE, OPER FROM OD_STEPS; diff --git a/deploy/depo/fancy-m2m-firebird/test/stub_fancy.sql b/deploy/depo/fancy-m2m-firebird/test/stub_fancy.sql new file mode 100644 index 0000000..e08c085 --- /dev/null +++ b/deploy/depo/fancy-m2m-firebird/test/stub_fancy.sql @@ -0,0 +1,635 @@ +CREATE TABLE D_CLISER_M2M ( + "DOC" INTEGER, + "DEPONENT" INTEGER, + "B_DATE" TIMESTAMP, + "E_DATE" TIMESTAMP, + "DOC_GUID" VARCHAR(36), + "DOC_STATUS" INTEGER, + "IIS_TYPE" INTEGER, + "IIS_INN" VARCHAR(10), + "IIS_NUM" VARCHAR(64), + "IIS_DATE" TIMESTAMP); + +CREATE TABLE D_CLISER_M2M_DOL ( + "DOL" INTEGER, + "SHARE" INTEGER, + "AMOUNT" NUMERIC(18,7), + "CLIENT" INTEGER, + "SETTL" INTEGER, + "SETTL_ACCS" VARCHAR(255), + "PLACES" VARCHAR(255), + "ANSWER_ACC" INTEGER, + "M2M_STATUS" INTEGER, + "M2M_TEXT" VARCHAR(255), + "DEP_STATUS" INTEGER, + "DEP_TEXT" VARCHAR(255), + "DOL_REF" VARCHAR(36), + "G_SGD" INTEGER, + "PLACE" INTEGER); + +CREATE TABLE D_FILER ( + "DOC" INTEGER, + "COMMENT" VARCHAR(255), + "FILE_NAME" VARCHAR(255), + "MESS" BLOB SUB_TYPE TEXT, + "CORR_FACE" INTEGER, + "FAX_DATE" TIMESTAMP, + "ORI_DATE" TIMESTAMP, + "REP_DATE" TIMESTAMP, + "CORR_DATE" TIMESTAMP, + "CORR_NUM" VARCHAR(64), + "RUBRICA" INTEGER, + "DOC_NUM" VARCHAR(64), + "DOC_DATE" TIMESTAMP, + "CHILD_CAT" INTEGER, + "FUND" INTEGER, + "CORR_NAME" VARCHAR(255), + "STORED_IMAGE" BLOB, + "ACCOUNT" INTEGER, + "PLACE" INTEGER, + "FUND_NAME" VARCHAR(255), + "PASS_KIND" INTEGER); + +CREATE TABLE OD_BALANCES ( + "ID" INTEGER, + "ACC_PLAN" INTEGER, + "NAME" VARCHAR(255), + "IS_FICT" CHAR(1), + "IS_DIFF" CHAR(1), + "ACC_TYPE" INTEGER, + "REST_TYPE" INTEGER, + "RET_1" INTEGER, + "RET_2" INTEGER, + "RET_3" INTEGER, + "RET_4" INTEGER, + "RET_5" INTEGER, + "RET_6" INTEGER, + "COMM" BLOB SUB_TYPE TEXT, + "SYS_NAME" VARCHAR(24), + "PART" INTEGER, + "ISM_1" SMALLINT, + "ISM_2" SMALLINT, + "ISM_3" SMALLINT, + "ISM_4" SMALLINT, + "ISM_5" SMALLINT, + "ISM_6" SMALLINT, + "IS_BAL" SMALLINT, + "MAIN_REG" SMALLINT, + "IS_CUR" SMALLINT, + "IS_LF" SMALLINT, + "LEV_" INTEGER, + "OWNER_" INTEGER, + "WALK" INTEGER, + "AMOUNT" INTEGER, + "NUM" INTEGER, + "NUM_S" VARCHAR(255), + "AMOUNT_REG" SMALLINT, + "REVALUE_TYP" SMALLINT, + "REVALUE_ACC" INTEGER, + "REVALUE_ACD" INTEGER, + "PAIR_ACC" INTEGER, + "MASK_NAME" VARCHAR(255), + "MASK_NUM" VARCHAR(25), + "ISG_1" SMALLINT, + "ISG_2" SMALLINT, + "ISG_3" SMALLINT, + "ISG_4" SMALLINT, + "ISG_5" SMALLINT, + "ISG_6" SMALLINT, + "EXP_TYPE" INTEGER, + "NUM_1" INTEGER, + "IS_SYNT" INTEGER, + "NUM_2" INTEGER); + +CREATE TABLE OD_CLIENTS ( + "ID" INTEGER, + "NUMBER" VARCHAR(128), + "STATE" INTEGER, + "D_OPEN" TIMESTAMP, + "D_CLOSE" TIMESTAMP, + "FACE" INTEGER, + "PARENT" INTEGER, + "PLAN_ID" INTEGER, + "RELATION" INTEGER, + "OPER" INTEGER, + "R_DATE" TIMESTAMP, + "SUBTYPE" INTEGER, + "IS_TERM" CHAR(1), + "LEV" INTEGER, + "SELF_ID" INTEGER, + "NAME" VARCHAR(255), + "TYPE_" INTEGER, + "DD_DATE" TIMESTAMP, + "DD_NUM" VARCHAR(64), + "PLACE" INTEGER, + "ISSUER" INTEGER, + "IS_MANAGER" SMALLINT, + "IS_VOICE" SMALLINT, + "IS_PRIV" SMALLINT, + "IS_SOV" SMALLINT, + "BAL_ACC" INTEGER, + "IS_BCLIENT" SMALLINT, + "F_DATE" TIMESTAMP, + "TRANSIT" INTEGER, + "CLI_ORG" INTEGER, + "USER_CODE" VARCHAR(64), + "SEP_SET" INTEGER, + "E_OWNER" INTEGER, + "EDO_TYPE" SMALLINT, + "IS_MAIN" SMALLINT); + +CREATE TABLE OD_CLIENTS_REC ( + "ID" INTEGER, + "CLIENT" INTEGER, + "LINK_NUMBER" VARCHAR(64), + "INCOME_MOD" INTEGER, + "INCOME_ACC" INTEGER, + "INCOME_FACE" INTEGER, + "INCOME_ADR" VARCHAR(255), + "INCOME_REC" VARCHAR(255), + "INCOME_VERBAL" VARCHAR(4000), + "O_MAIL_MOD" INTEGER, + "O_MAIL_ADR" VARCHAR(255), + "I_MAIL_MOD" INTEGER, + "I_MAIL_ALT" INTEGER, + "I_MAIL_ADR" VARCHAR(255), + "B_DATE" TIMESTAMP, + "E_DATE" TIMESTAMP, + "OPER" INTEGER, + "IUD" INTEGER, + "TARIF" VARCHAR(64), + "EXTRA_INT" INTEGER, + "EXTRA_TYPE" INTEGER, + "IS_NZ" SMALLINT, + "Z_DATE" TIMESTAMP, + "Z_AMOUNT" NUMERIC(18,7), + "PORT_NAME" VARCHAR(255)); + +CREATE TABLE OD_DOC_CATS ( + "ID" INTEGER, + "OWNER" INTEGER, + "LEV" INTEGER, + "AMOUNT" INTEGER, + "WALK" INTEGER, + "NAME" VARCHAR(128), + "D_MODE" SMALLINT, + "ADD_TABLE" VARCHAR(64), + "KEY_FIELD" VARCHAR(32), + "INFO_FIELDS" BLOB SUB_TYPE TEXT, + "EDITOR" VARCHAR(64), + "FORM_COMP" VARCHAR(32), + "SYS_NAME" VARCHAR(64), + "PROFILE" INTEGER, + "EDITOR_TYPE" SMALLINT, + "IS_ONCE" SMALLINT, + "FUN_FORM" VARCHAR(255), + "ADD_VIEW" VARCHAR(64), + "B_DATE" TIMESTAMP, + "IS_UNUM" SMALLINT, + "NUM_RULE" SMALLINT, + "FOOTER_VIEW" INTEGER, + "DEL_FUNC" BLOB SUB_TYPE TEXT, + "FOOT_STR" SMALLINT, + "FOOT_TABLE" VARCHAR(64), + "FOOT_FIELD" VARCHAR(64), + "C_MARK" VARCHAR(32), + "C_KIND" SMALLINT, + "UNUM_DIR" SMALLINT, + "FOOTERS" VARCHAR(1024), + "FOOT_COMP" VARCHAR(32), + "FOOT_DEL" SMALLINT, + "MD5_HASH" VARCHAR(32), + "MD5_STAMP" TIMESTAMP, + "IS_TERM" VARCHAR(1), + "IS_AUTO" INTEGER, + "MIN_VERSION" VARCHAR(10)); + +CREATE TABLE OD_DOC_STATES ( + "ID" INTEGER, + "D_CAT" INTEGER, + "IS_IN" CHAR(1), + "IS_OUT" CHAR(1), + "NAME" VARCHAR(128), + "SYS_NAME" VARCHAR(64), + "PROFILE" INTEGER); + +CREATE TABLE OD_DOCS ( + "ID" INTEGER, + "NUM" VARCHAR(64), + "OPER" INTEGER, + "R_DATE" TIMESTAMP, + "D_CAT" INTEGER, + "D_DATE" TIMESTAMP, + "PROC_DATE" TIMESTAMP, + "DIRECTION" INTEGER, + "WHOS" INTEGER, + "PARAM" INTEGER, + "KVIT" INTEGER, + "U_FLAG" INTEGER, + "A_FLAG" INTEGER, + "STATE" INTEGER, + "LAST_STEP" INTEGER, + "ERR_CODE" INTEGER, + "CREATOR" INTEGER, + "SECURITY" VARCHAR(255), + "IMAGEFILE" VARCHAR(1024), + "INTNUM" INTEGER, + "NUMSFX" VARCHAR(255), + "NUM_DATE" VARCHAR(78), + "D_MONTH" INTEGER, + "D_YEAR" INTEGER, + "D_DAY" TIMESTAMP); + +CREATE TABLE OD_DOLS ( + "ID" INTEGER, + "DOC" INTEGER, + "NUM" INTEGER, + "TAG" INTEGER, + "NUM_1" INTEGER, + "NUM_2" INTEGER, + "IS_TERM" CHAR(1), + "FOOTER" INTEGER, + "STATUS" INTEGER); + +CREATE TABLE OD_FACE_CODERS ( + "CODER" INTEGER, + "CODE" VARCHAR(64), + "FACE" INTEGER); + +CREATE TABLE OD_FACES ( + "ID" INTEGER, + "S_TYPE" INTEGER, + "NAME" VARCHAR(255), + "MAIL_ADR" VARCHAR(255), + "HOME_ADR" VARCHAR(255), + "FACT_ADR" VARCHAR(255), + "HOME_KLADR" VARCHAR(255), + "MAIL_KLADR" VARCHAR(255), + "FACT_KLADR" VARCHAR(255), + "EMAIL" VARCHAR(255), + "FAX" VARCHAR(64), + "DATE_DEPTH" TIMESTAMP, + "TELEX" VARCHAR(255), + "INN" VARCHAR(15), + "KPP" VARCHAR(9), + "PHONE" VARCHAR(64), + "DOC_TYPE" INTEGER, + "DOC_SER" VARCHAR(25), + "DOC_NUM" VARCHAR(20), + "DOC_DAT" TIMESTAMP, + "DOC_PLACE" VARCHAR(255), + "DOC_CODE" VARCHAR(128), + "DOC_END" TIMESTAMP, + "DATE_BIRTH" TIMESTAMP, + "SELF_ID" INTEGER, + "B_DATE" TIMESTAMP, + "E_DATE" TIMESTAMP, + "OPER" INTEGER, + "UPTYPE" SMALLINT, + "PROFILE" INTEGER, + "LAST_FLAG" SMALLINT, + "STATE" CHAR(3), + "MNEM" VARCHAR(64), + "REGN" INTEGER, + "BRANCHES" INTEGER, + "NORM_NAME" VARCHAR(255), + "ENG_NAME" VARCHAR(255), + "ENG_MAIL_ADR" VARCHAR(255), + "IMAGEFILE" VARCHAR(255), + "IS_NERES" SMALLINT, + "TAXIS" VARCHAR(64), + "TIN" VARCHAR(24)); + +CREATE TABLE OD_IN_DOCS ( + "DOC" INTEGER, + "FROM_FACE" INTEGER, + "THEIR_DATE" TIMESTAMP, + "I_NUM" VARCHAR(64), + "OUR_O_DOC" INTEGER, + "FILE_NAME" VARCHAR(128), + "THEIR_NUM" VARCHAR(80), + "CODER" INTEGER, + "PASS_KIND" INTEGER); + +CREATE TABLE OD_INVALIDS ( + "DOC" INTEGER, + "DOL" INTEGER, + "STATUS" INTEGER, + "COMMENT" VARCHAR(255), + "DO_ING" VARCHAR(255)); + +CREATE TABLE OD_OBJECTS ( + "ID" INTEGER, + "DMY" CHAR(1)); + +CREATE TABLE OD_OUT_DOCS ( + "DOC" INTEGER, + "TO_FACE" INTEGER, + "O_NUM" VARCHAR(64), + "OUR_I_DOC" INTEGER, + "FILE_NAME" VARCHAR(128), + "PASS_KIND" INTEGER); + +CREATE TABLE OD_SHARES ( + "ID" INTEGER, + "MNEM" VARCHAR(255), + "BIRTHDATE" TIMESTAMP, + "DEATHDATE" TIMESTAMP, + "CLASS" INTEGER, + "MODE" INTEGER, + "ISSUER" INTEGER, + "NOMINAL" DOUBLE PRECISION, + "NOM_VAL" INTEGER, + "NOM_TYPE" SMALLINT, + "ISNUM" CHAR(1), + "NUM_REG" VARCHAR(124), + "ORG_REG" INTEGER, + "COUNT_" NUMERIC(18,0), + "ISSUENUM" INTEGER, + "LINK" INTEGER, + "TYPE_" INTEGER, + "IS_MARGIN" SMALLINT, + "IS_MCS" SMALLINT, + "STATUS" SMALLINT, + "DATE_REG" TIMESTAMP, + "PMFU" SMALLINT, + "SELF_ID" INTEGER, + "B_DATE" TIMESTAMP, + "E_DATE" TIMESTAMP, + "REP_DATE" TIMESTAMP, + "R_DATE" TIMESTAMP, + "R_COMMENT" VARCHAR(255), + "OPER" INTEGER); + +CREATE TABLE OD_STEP_TYPES ( + "ID" INTEGER, + "NAME" VARCHAR(200), + "IN_STATE" INTEGER, + "OUT_STATE" INTEGER, + "COND" BLOB SUB_TYPE TEXT, + "BODY" BLOB SUB_TYPE TEXT, + "D_CAT" INTEGER, + "A_CAT" INTEGER, + "SYS_NAME" VARCHAR(64), + "HINT" VARCHAR(255), + "ROLLBACK_" BLOB SUB_TYPE TEXT, + "ALT_STATE" INTEGER, + "IMPORTANCE" SMALLINT, + "MD5_HASH" VARCHAR(32), + "MD5_STAMP" TIMESTAMP); + +CREATE TABLE OD_STEPS ( + "ID" INTEGER, + "DOC" INTEGER, + "A_DOC" INTEGER, + "S_TYPE" INTEGER, + "S_DATE" TIMESTAMP, + "ERR_CODE" INTEGER, + "NUM" INTEGER, + "OPER" INTEGER, + "OUT_STATE" INTEGER); + +CREATE TABLE OD_SYS_TABS ( + "NUM" INTEGER, + "CODE" VARCHAR(24), + "NAME" VARCHAR(255), + "DOP" VARCHAR(255), + "ALT" VARCHAR(255), + "EXT" VARCHAR(255)); + +CREATE TABLE OD_U_FACES ( + "FACE" INTEGER, + "OKPO" VARCHAR(64), + "OKONX" VARCHAR(64), + "DOL_1" VARCHAR(255), + "DOL_2" VARCHAR(255), + "DOL_OTV" VARCHAR(255), + "FIO_1" VARCHAR(64), + "FIO_2" VARCHAR(64), + "FIO_OTV" VARCHAR(64), + "FIO_BUG" VARCHAR(64), + "TEL_1" VARCHAR(24), + "TEL_2" VARCHAR(24), + "TEL_OTV" VARCHAR(24), + "TEL_BUG" VARCHAR(24), + "OSN_1" VARCHAR(64), + "OSN_2" VARCHAR(64), + "OPF" VARCHAR(10), + "CAPITAL" NUMERIC(18,7), + "REESTR" INTEGER, + "DEPOT" INTEGER, + "DEP_NUM" VARCHAR(20), + "DEP_DAT" TIMESTAMP, + "UPTYPE" SMALLINT, + "FS" INTEGER, + "OGRN" VARCHAR(24), + "OGRN_DATE" TIMESTAMP, + "OGRN_PLACE" VARCHAR(255), + "OKOGU" VARCHAR(24), + "OKATO" VARCHAR(24), + "FULL_NAME" VARCHAR(255), + "ENG_FULL_NAME" VARCHAR(255), + "EXEC_ORGAN" INTEGER, + "NAL_ORGAN" INTEGER, + "ENSURNUM" VARCHAR(10)); + +CREATE TABLE OD_VALUE_CODERS ( + "CODER" INTEGER, + "CODE" VARCHAR(64), + "LOT_SIZE" INTEGER, + "SHARE" INTEGER, + "IND_CODE" VARCHAR(64), + "CODE_NAME" VARCHAR(255)); + +CREATE TABLE OD_VALUES ( + "ID" INTEGER, + "SYSNAME" VARCHAR(64), + "NAME" VARCHAR(255), + "V_TYPE" INTEGER, + "B_DATE" TIMESTAMP, + "ISIN" VARCHAR(12), + "MFU" SMALLINT, + "IS_IN" SMALLINT, + "CFI" CHAR(6), + "BASE_VAL" INTEGER); + +CREATE TABLE OD_WIRING ( + "ID" INTEGER, + "PLAN_ID" INTEGER, + "WIRDATE" TIMESTAMP, + "NAME" VARCHAR(255), + "COMMENT" VARCHAR(255), + "D_REST" INTEGER, + "K_REST" INTEGER, + "EQ_" NUMERIC(18,7), + "O_STEP" INTEGER, + "CHANGED_BY" INTEGER, + "IS_PLAN" CHAR(1), + "BLANKS" BLOB SUB_TYPE TEXT, + "DOL" INTEGER, + "LINK" INTEGER, + "TAG" INTEGER, + "D_SUMMA" NUMERIC(18,7), + "K_SUMMA" NUMERIC(18,7), + "D_AMOUNT" NUMERIC(18,7), + "K_AMOUNT" NUMERIC(18,7)); + +CREATE TABLE OD_OPERATORS ( + "ID" INTEGER, + "USER_ID" VARCHAR(24), + "NAME" VARCHAR(128), + "DEP" INTEGER, + "COMM" BLOB SUB_TYPE TEXT, + "U_FACE" INTEGER, + "PLAN_ID" INTEGER, + "F_FACE" INTEGER, + "IS_ENCRYPT" SMALLINT, + "IS_DISPERS" SMALLINT, + "IS_MONITOR" SMALLINT, + "USER_DOL" VARCHAR(255), + "USER_CODE" VARCHAR(64), + "SMTP_PARAM" VARCHAR(255), + "QUIK_CODE" VARCHAR(255), + "PROXY_PARAM" VARCHAR(255), + "EVENT_MAIL" VARCHAR(255), + "IS_ONE" SMALLINT, + "BLOCK_DATE" TIMESTAMP, + "PASS_DAYS" INTEGER, + "LOGIO_DATE" TIMESTAMP, + "B_DATE" TIMESTAMP, + "E_DATE" TIMESTAMP, + "IS_ROBOT" SMALLINT, + "EMAIL" VARCHAR(255)); + +CREATE TABLE OD_SETS ( + "WHOS" INTEGER, + "PROFIT_TYPE" INTEGER, + "PROFIT_MODE" INTEGER, + "WIRING_MODE" INTEGER, + "IS_RED_SALDO" SMALLINT, + "SAVE_MODE" INTEGER, + "IS_PLACED" SMALLINT, + "TAX_CODE" VARCHAR(9), + "CASHIER" VARCHAR(64), + "REPORTER" VARCHAR(255), + "DOL_REPORTER" VARCHAR(255), + "LABEL_FILENAME" VARCHAR(255), + "TAX_ORG" VARCHAR(255), + "NDS_RATE" NUMERIC(18,7), + "IS_NDS" SMALLINT, + "IS_BOOK" SMALLINT, + "A_MODE" SMALLINT, + "O_MODE" SMALLINT, + "STOP_DATE" TIMESTAMP, + "A_RATER" INTEGER, + "O_RATER" INTEGER, + "IS_RED_STORNO" SMALLINT, + "IS_TEST" SMALLINT); + +CREATE TABLE U_OP_INV_SPIS ( + "DOC" INTEGER, + "DEPO" INTEGER, + "AMOUNT" NUMERIC(18,7), + "BLANKS" VARCHAR(255), + "B_TYPE" INTEGER, + "B_DATE" TIMESTAMP, + "B_NUM" VARCHAR(255), + "DD_DATE" TIMESTAMP, + "DD_NUM" VARCHAR(255), + "MARKET" INTEGER, + "D_NUM" INTEGER, + "K_NUM" INTEGER, + "PLACE" INTEGER, + "SHARE" INTEGER, + "DD_TYPE" INTEGER, + "TAX_R" NUMERIC(18,7), + "IS_98053" SMALLINT, + "IS_REG" SMALLINT, + "IS_BLOCK" SMALLINT, + "COMMENT" VARCHAR(255), + "FROM_FACE" INTEGER, + "WIR_DATE" TIMESTAMP, + "REG_DATE" TIMESTAMP, + "NOTIFY_DATE" TIMESTAMP, + "REJECT_REASON" VARCHAR(255), + "REESTR" INTEGER, + "OLD_CONDITIONS" INTEGER); + +CREATE TABLE U_OP_INV_ZACH ( + "DOC" INTEGER, + "DEPO" INTEGER, + "SHARE" INTEGER, + "AMOUNT" NUMERIC(18,7), + "BLANKS" VARCHAR(255), + "B_TYPE" INTEGER, + "B_DATE" TIMESTAMP, + "B_NUM" VARCHAR(255), + "DD_TYPE" INTEGER, + "DD_DATE" TIMESTAMP, + "DD_NUM" VARCHAR(255), + "MARKET" INTEGER, + "D_NUM" INTEGER, + "K_NUM" INTEGER, + "PLACE" INTEGER, + "TAX_R" NUMERIC(18,7), + "IS_98053" SMALLINT, + "IS_REG" SMALLINT, + "IS_BLOCK" SMALLINT, + "COMMENT" VARCHAR(255), + "FROM_FACE" INTEGER, + "WIR_DATE" TIMESTAMP, + "REG_DATE" TIMESTAMP, + "NOTIFY_DATE" TIMESTAMP, + "REJECT_REASON" VARCHAR(255), + "REESTR" INTEGER, + "CONDITION" INTEGER); + +CREATE GENERATOR OD_DOC_ID_GEN; + +SET GENERATOR OD_DOC_ID_GEN TO 1000; + +CREATE GENERATOR OD_DOL_ID_GEN; + +SET GENERATOR OD_DOL_ID_GEN TO 1000; + +CREATE GENERATOR OD_STEPS_ID_GEN; + +SET GENERATOR OD_STEPS_ID_GEN TO 1000; + +CREATE GENERATOR OD_FACES_ID_GEN; + +SET GENERATOR OD_FACES_ID_GEN TO 1000; + +SET TERM ^ ; +CREATE PROCEDURE FU_NEXT_DOC_NUM (CAT_SYS_NAME VARCHAR(64), D_DATE TIMESTAMP, DIRECTION SMALLINT, FOR_DOC INTEGER) +RETURNS (NUM VARCHAR(255), NEW_DATE TIMESTAMP) AS +BEGIN + NUM = 'N' || COALESCE(FOR_DOC, 0); NEW_DATE = D_DATE; +END^ +CREATE PROCEDURE OD_PR_INS_WIRS (WIR_ID INTEGER, PLAN_ID INTEGER, WIRDATE TIMESTAMP, NAME VARCHAR(255), "COMMENT" VARCHAR(255), + D_SUMMA DOUBLE PRECISION, K_SUMMA DOUBLE PRECISION, EQ_ DOUBLE PRECISION, D_AMOUNT DOUBLE PRECISION, K_AMOUNT DOUBLE PRECISION, + BLANKS VARCHAR(2000), O_STEP INTEGER, DOL INTEGER, CHANGED_BY INTEGER, IS_PLAN CHAR(1), + D_BAL_ACC INTEGER, D_VALUE INTEGER, D_REG_1 INTEGER, D_REG_2 INTEGER, D_REG_3 INTEGER, D_REG_4 INTEGER, D_REG_5 INTEGER, D_REG_6 INTEGER, + K_BAL_ACC INTEGER, K_VALUE INTEGER, K_REG_1 INTEGER, K_REG_2 INTEGER, K_REG_3 INTEGER, K_REG_4 INTEGER, K_REG_5 INTEGER, K_REG_6 INTEGER) +RETURNS (NEW_ID INTEGER, WIR_LIST VARCHAR(255), DEB_ID INTEGER, KRD_ID INTEGER) AS +DECLARE VARIABLE R INTEGER; +BEGIN + NEW_ID = 1; WIR_LIST = ''; DEB_ID = 0; KRD_ID = 0; + R = RDB$SET_CONTEXT('USER_TRANSACTION', 'STUB_WIRS', 'D' || D_BAL_ACC || ' K' || K_BAL_ACC || ' ' || D_SUMMA || ' ' || NAME || ' / ' || "COMMENT"); +END^ +SET TERM ; ^ + +SET TERM ^ ; +/* как Fancy OD_DOCS_BU: ID = 0 в UPDATE — служебное изменение, ID остаётся прежним */ +CREATE TRIGGER OD_DOCS_BU FOR OD_DOCS ACTIVE BEFORE UPDATE AS +BEGIN + IF (NEW.ID = 0 OR NEW.ID IS NULL) THEN NEW.ID = OLD.ID; +END^ +/* версия юрлица: SELF_ID = ID, действующая */ +CREATE TRIGGER OD_FACES_BI FOR OD_FACES ACTIVE BEFORE INSERT AS +BEGIN + IF (NEW.SELF_ID IS NULL) THEN NEW.SELF_ID = NEW.ID; + IF (NEW.LAST_FLAG IS NULL) THEN NEW.LAST_FLAG = 1; + IF (NEW.E_DATE IS NULL) THEN NEW.E_DATE = '9999-01-01'; +END^ +SET TERM ; ^