From 7015fe2cf38b7abccede178429112d567c1a11f8 Mon Sep 17 00:00:00 2001 From: Mikhail Chechnev Date: Fri, 8 Mar 2019 20:42:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2=20=D0=91=D0=94?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B2=20=D1=80=D0=B5=D0=BF=D0=BE?= =?UTF-8?q?=D0=B7=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B9=20P8-ExchangeService?= =?UTF-8?q?Ext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/UDO_PKG_EXS_ATOL.pck | 513 -------- db/UDO_PKG_EXS_INV.pck | 1655 -------------------------- db/UDO_PKG_EXS_TEST.pck | 183 --- db/UDO_P_FISCDOCS_BASE_SEND.prc | 71 -- db/UDO_P_FISCDOCS_GET_STATE_ATOL.prc | 27 - db/UDO_P_FISCDOCS_MAKE_MSG_ATOL.prc | 162 --- 6 files changed, 2611 deletions(-) delete mode 100644 db/UDO_PKG_EXS_ATOL.pck delete mode 100644 db/UDO_PKG_EXS_INV.pck delete mode 100644 db/UDO_PKG_EXS_TEST.pck delete mode 100644 db/UDO_P_FISCDOCS_BASE_SEND.prc delete mode 100644 db/UDO_P_FISCDOCS_GET_STATE_ATOL.prc delete mode 100644 db/UDO_P_FISCDOCS_MAKE_MSG_ATOL.prc diff --git a/db/UDO_PKG_EXS_ATOL.pck b/db/UDO_PKG_EXS_ATOL.pck deleted file mode 100644 index 96fc6bf..0000000 --- a/db/UDO_PKG_EXS_ATOL.pck +++ /dev/null @@ -1,513 +0,0 @@ -create or replace package UDO_PKG_EXS_ATOL as - - /* Константы - тестовое окружение сервера АТОЛ-Онлайн */ - STEST_SRV_ROOT_PATTERN constant varchar2(80) := '%testonline.atol.ru%'; -- Шаблон адреса тестового сервера - STEST_INN constant varchar2(80) := '5544332219'; -- Тестовый ИНН - STEST_ADDR constant varchar2(80) := 'https://v4.online.atol.ru'; -- Тестовый адрес расчётов - - /* Константы - типы функций обработки */ - SFN_TYPE_REG_BILL constant varchar2(20) := 'REG_BILL'; -- Типовая функция регистрации чека - SFN_TYPE_GET_BILL_INF constant varchar2(20) := 'GET_BILL_INF'; -- Типовая функция получения иформации о регистрации чека - - /* Константы - версии ФФД (строковые представления) */ - SFFD105 constant varchar2(20) := '1.05'; -- Версия ФФД 1.05 - SFFD110 constant varchar2(20) := '1.10'; -- Версия ФФД 1.10 - - /* Константы - значения тэга "Номер версии ФФД" (1209) для версий формата */ - NTAG1209_FFD105 constant number(2) := 2; -- Значение тэга 1209 для версии ФФД 1.05 - NTAG1209_FFD110 constant number(2) := 3; -- Значение тэга 1209 для версии ФФД 1.10 - - /* Проверка сервиса на то, что он является тестовым */ - function UTL_EXSSERVICE_IS_TEST - ( - NEXSSERVICE in number -- Регистрационный номер сервиса обмена - ) return boolean; -- Признак тестового сервиса (true - тестовый, false - не тестовый) - - /* Получение рег. номера функции сервиса обмена для регистрации чека по рег. номеру фискального документа */ - function UTL_FISCDOC_GET_EXSFN_REG - ( - NFISCDOC in number -- Рег. номер фискального документа - ) return number; -- Рег. номер функции регистрации чека в сервисе АТОЛ-Онлайн - - /* Получение рег. номера функции сервиса обмена для запроса информации о регистрации чека по рег. номеру фискального документа */ - function UTL_FISCDOC_GET_EXSFN_INF - ( - NFISCDOC in number -- Рег. номер фискального документа - ) return number; -- Рег. номер функции запроса информации о регистрации чека в сервисе АТОЛ-Онлайн - - /* Отработка ответов АТОЛ (v4) на регистрацию чека на приход, расход, возврат (ФФД 1.05) */ - procedure V4_FFD105_PROCESS_REG_BILL_SIR - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Отработка ответов АТОЛ (v4) на запрос сведений о зарегистрированном документе (ФФД 1.05) */ - procedure V4_FFD105_PROCESS_GET_BILL_INF - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Отработка ответов ОФД на запрос чека */ - procedure OFD_PROCESS_GET_BILL_DOC - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - -end; -/ -create or replace package body UDO_PKG_EXS_ATOL as - - /* Константы - состояния документа в АТОЛ */ - SSTATUS_DONE constant varchar2(10) := 'done'; -- Готово - SSTATUS_FAIL constant varchar2(10) := 'fail'; -- Ошибка - SSTATUS_WAIT constant varchar2(10) := 'wait'; -- Ожидание - - /* Шаблон URL для чека ОФД */ - SBILL_OFD_UTL constant varchar2(80) := 'https://ofd.ru/rec/<1041>/<1040>/<1077>?format=pdf'; - - /* Проверка корректности атрибутов позиции очереди */ - procedure UTL_EXSQUEUE_CHECK_ATTRS - ( - REXSQUEUE in EXSQUEUE%rowtype -- Проверяемая запись позиции очереди - ) - is - begin - /* Должна быть организация */ - if (REXSQUEUE.LNK_COMPANY is null) then - P_EXCEPTION(0, 'Для позиции очереди не указана связанная организация.'); - end if; - /* Должна быть связь с документом */ - if (REXSQUEUE.LNK_DOCUMENT is null) then - P_EXCEPTION(0, 'Для позиции очереди не указан связанный документ.'); - end if; - /* Должна быть связь с разделом */ - if (REXSQUEUE.LNK_UNITCODE is null) then - P_EXCEPTION(0, 'Для позиции очереди не указан связанный раздел.'); - end if; - /* Должна быть связь именно с разделом "Фискальные документы" */ - if (REXSQUEUE.LNK_UNITCODE <> 'UDO_FiscalDocuments') then - P_EXCEPTION(0, - 'Связанный раздел "%s", указанный в позиции очереди, не поддерживается.', - REXSQUEUE.LNK_UNITCODE); - end if; - end UTL_EXSQUEUE_CHECK_ATTRS; - - /* Считывание записи фискального документа */ - function UTL_FISCDOC_GET - ( - NFISCDOC in number -- Рег. номер фискального документа - ) return UDO_FISCDOCS%rowtype -- Найденная запись фискального документа - is - RRES UDO_FISCDOCS%rowtype; -- Буфер для результата - begin - /* Считаем запись */ - select T.* into RRES from UDO_FISCDOCS T where T.RN = NFISCDOC; - /* Вернём результат */ - return RRES; - exception - when NO_DATA_FOUND then - PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NFISCDOC, SUNIT_TABLE => 'UDO_FISCDOCS'); - end UTL_FISCDOC_GET; - - /* Получение постфикса сервиса обмена для фискального документа по его принадлежности к организации */ - function UTL_FISCDOC_GET_EXS_POSTFIX - ( - NFISCDOC in number -- Рег. номер фискального документа - ) return varchar2 -- Постфикс сервиса обмена - is - SRES COMPANIES.NAME%type; -- Результат работы - begin - /* Считаем постфик сервиса обмена (это наименование организации фискального документа) */ - select C.NAME - into SRES - from UDO_FISCDOCS FD, - COMPANIES C - where FD.RN = NFISCDOC - and FD.COMPANY = C.RN; - /* Возвращаем результат */ - return SRES; - exception - when others then - P_EXCEPTION(0, - 'Для фискального документа (RN: %s) не определен постфикс сервиса обмена.', - TO_CHAR(NFISCDOC)); - end UTL_FISCDOC_GET_EXS_POSTFIX; - - /* Получение мнемокода сервиса обмена и мнемокода его функции по типу функции обработки и версии ФФД */ - procedure UTL_FISCDOC_GET_EXSFN - ( - NFISCDOC in number, -- Рег. номер фискального документа - SFN_TYPE in varchar2, -- Тип функции обработки (см. константы SFN_TYPE_*) - NEXSSERVICEFN out number -- Рег. номер функции-обработчика - ) - is - SEXSRV EXSSERVICE.CODE%type; -- Мнемокод эталонного сервиса обмена из настроек фискального документа - SEXSRVFN EXSSERVICEFN.CODE%type; -- Мнемокод эталонной функции обмена из настроек фискального документа - begin - begin - /* Находим мнемокод эталонной функции и сервиса из настроек фискального документа */ - select DECODE(SFN_TYPE, SFN_TYPE_REG_BILL, SREG.CODE, SFN_TYPE_GET_BILL_INF, SINF.CODE), - DECODE(SFN_TYPE, SFN_TYPE_REG_BILL, SFNREG.CODE, SFN_TYPE_GET_BILL_INF, SFNINF.CODE) - into SEXSRV, - SEXSRVFN - from UDO_FISCDOCS FD, - UDO_FDKNDVERS TV, - EXSSERVICEFN SFNREG, - EXSSERVICEFN SFNINF, - EXSSERVICE SREG, - EXSSERVICE SINF - where FD.RN = NFISCDOC - and FD.TYPE_VERSION = TV.RN - and TV.FUNCTION_SEND = SFNREG.RN(+) - and SFNREG.PRN = SREG.RN(+) - and TV.FUNCTION_RESP = SFNINF.RN(+) - and SFNINF.PRN = SINF.RN(+); - exception - when others then - SEXSRV := null; - SEXSRVFN := null; - end; - /* Если найдены эталонные сервис обмена и функция - подбираем то что нужно по принадлености фискального документа к организации */ - if ((SEXSRV is not null) and (SEXSRVFN is not null)) then - NEXSSERVICEFN := PKG_EXS.SERVICEFN_FIND_BY_SRVCODE(NFLAG_SMART => 0, - SEXSSERVICE => SEXSRV || '_' || UTL_FISCDOC_GET_EXS_POSTFIX(NFISCDOC => NFISCDOC), - SEXSSERVICEFN => SEXSRVFN); - else - /* Эталоны не найдены - значит невозможен подбор реальной функции */ - P_EXCEPTION(0, - 'Для фискального документа (RN: %s) не определеная типовая функция "%s".', - TO_CHAR(NFISCDOC), - SFN_TYPE); - end if; - end UTL_FISCDOC_GET_EXSFN; - - /* Получение рег. номера функции сервиса обмена для регистрации чека по рег. номеру фискального документа */ - function UTL_FISCDOC_GET_EXSFN_REG - ( - NFISCDOC in number -- Рег. номер фискального документа - ) return number -- Рег. номер функции регистрации чека в сервисе АТОЛ-Онлайн - is - NRES PKG_STD.TREF; -- Буфер для результата - begin - /* Определим мнемокоды сервиса и функции для обработки */ - UTL_FISCDOC_GET_EXSFN(NFISCDOC => NFISCDOC, SFN_TYPE => SFN_TYPE_REG_BILL, NEXSSERVICEFN => NRES); - /* Вернём результат */ - return NRES; - end UTL_FISCDOC_GET_EXSFN_REG; - - /* Получение рег. номера функции сервиса обмена для запроса информации о регистрации чека по рег. номеру фискального документа */ - function UTL_FISCDOC_GET_EXSFN_INF - ( - NFISCDOC in number -- Рег. номер фискального документа - ) return number -- Рег. номер функции запроса информации о регистрации чека в сервисе АТОЛ-Онлайн - is - NRES PKG_STD.TREF; -- Буфер для результата - begin - /* Определим мнемокоды сервиса и функции для обработки */ - UTL_FISCDOC_GET_EXSFN(NFISCDOC => NFISCDOC, SFN_TYPE => SFN_TYPE_GET_BILL_INF, NEXSSERVICEFN => NRES); - /* Вернём результат */ - return NRES; - end UTL_FISCDOC_GET_EXSFN_INF; - - /* Контроль версии ФФД */ - procedure UTL_FISCDOC_CHECK_FFD_VERS - ( - NCOMPANY in number, -- Рег. номер организации - NFISCDOC in number, -- Рег. номер фискального документа - NEXPECTED_VERS in number, -- Ожидаемая версия ФФД (по значению тэга 1209, см. констнаты NTAG1209_FFD*) - SEXPECTED_VERS in varchar2 -- Ожидаемая версия ФФД (строковое представление) - ) - is - begin - /* Считаем тэг 1209 (в нем хранится номер версии ФФД) и сверим значения, фактическое и ожидаемое процедурой */ - if (UDO_F_FISCDOCS_GET_NUMB(NRN => NFISCDOC, NCOMPANY => NCOMPANY, SATTRIBUTE => '1209') != NEXPECTED_VERS) then - P_EXCEPTION(0, - 'Версия формата фискального документа (значение тэга 1209 - %s) не поддерживается. Ожидаемая версия - %s (значение тэга 1209 - %s).', - NVL(TO_CHAR(UDO_F_FISCDOCS_GET_NUMB(NRN => NFISCDOC, NCOMPANY => NCOMPANY, SATTRIBUTE => '1209')), - '<НЕ УКАЗАНО>'), - NVL(SEXPECTED_VERS, '<НЕ УКАЗАНА>'), - NVL(TO_CHAR(NEXPECTED_VERS), '<НЕ УКАЗАНО>')); - end if; - end UTL_FISCDOC_CHECK_FFD_VERS; - - /* Проверка сервиса на то, что он является тестовым */ - function UTL_EXSSERVICE_IS_TEST - ( - NEXSSERVICE in number -- Регистрационный номер сервиса обмена - ) return boolean -- Признак тестового сервиса (true - тестовый, false - не тестовый) - is - REXSSERVICE EXSSERVICE%rowtype; -- Запись сервиса обмена - begin - /* Считаем запись сервиса обмена */ - REXSSERVICE := GET_EXSSERVICE_ID(NFLAG_SMART => 0, NRN => NEXSSERVICE); - /* Проверим его по адресу */ - if (REXSSERVICE.SRV_ROOT like STEST_SRV_ROOT_PATTERN) then - return true; - else - return false; - end if; - end; - - /* Отработка ответов АТОЛ (v4) на регистрацию чека на приход, расход, возврат (ФФД 1.05) */ - procedure V4_FFD105_PROCESS_REG_BILL_SIR - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди - RFISCDOC UDO_FISCDOCS%rowtype; -- Запись фискального документа - CTMP clob; -- Буфер для хранения данных ответа сервера - begin - /* Считаем запись очереди */ - REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE); - /* Проверим что позиция очереди корректна */ - UTL_EXSQUEUE_CHECK_ATTRS(REXSQUEUE => REXSQUEUE); - /* Считаем запись фискального документа */ - RFISCDOC := UTL_FISCDOC_GET(NFISCDOC => REXSQUEUE.LNK_DOCUMENT); - /* Проверим, что он верного формата */ - UTL_FISCDOC_CHECK_FFD_VERS(NCOMPANY => RFISCDOC.COMPANY, - NFISCDOC => RFISCDOC.RN, - NEXPECTED_VERS => NTAG1209_FFD105, - SEXPECTED_VERS => SFFD105); - /* Разбираем ответ */ - CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.RESP, SCHARSET => 'UTF8'); - if (CTMP is null) then - P_EXCEPTION(0, 'Нет ответа от сервера.'); - end if; - /* Выставляем идентификатор АТОЛ в ФД */ - update UDO_FISCDOCS T set T.NUMB_FD = CTMP where T.RN = REXSQUEUE.LNK_DOCUMENT; - /* Всё прошло успешно */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT); - exception - when others then - /* Вернём ошибку */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end V4_FFD105_PROCESS_REG_BILL_SIR; - - /* Отработка ответов АТОЛ (v4) на запрос сведений о зарегистрированном документе (ФФД 1.05) */ - procedure V4_FFD105_PROCESS_GET_BILL_INF - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди - RFISCDOC UDO_FISCDOCS%rowtype; -- Запись фискального документа - RDOC PKG_XPATH.TDOCUMENT; -- Разобранный XML-документ - RROOT_NODE PKG_XPATH.TNODE; -- Корневой тэг XML-документа - SSTATUS PKG_STD.TSTRING; -- Буфер для значения "Статус обработки документа" - STIMESTAMP PKG_STD.TSTRING; -- Буфер для значения "Дата и время документа внешней системы" (строковое представление) - DTIMESTAMP PKG_STD.TLDATE; -- Буфер для значения "Дата и время документа внешней системы" - STAG1012 PKG_STD.TSTRING; -- Буфер для значения "Дата и время документа из ФН" (тэг 1012) - STAG1038 PKG_STD.TSTRING; -- Буфер для значения "Номер смены" (тэг 1038) - STAG1040 PKG_STD.TSTRING; -- Буфер для значения "Фискальный номер документа" (тэг 1040) - STAG1041 PKG_STD.TSTRING; -- Буфер для значения "Номер ФН" (тэг 1041) - STAG1042 PKG_STD.TSTRING; -- Буфер для значения "Номер чека в смене" (тэг 1042) - STAG1077 PKG_STD.TSTRING; -- Буфер для значения "Фискальный признак документа" (тэг 1077) - SERR_CODE PKG_STD.TSTRING; -- Буфер для значения "Код ошибки" - SERR_TEXT PKG_STD.TSTRING; -- Буфер для значения "Текст ошибки" - NNEW_EXSQUEUE PKG_STD.TREF; -- Рег. номер записи очереди обмена (для скачивания готового чека) - begin - /* Считаем запись очереди */ - REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE); - /* Проверим что позиция очереди корректна */ - UTL_EXSQUEUE_CHECK_ATTRS(REXSQUEUE => REXSQUEUE); - /* Считаем запись фискального документа */ - RFISCDOC := UTL_FISCDOC_GET(NFISCDOC => REXSQUEUE.LNK_DOCUMENT); - /* Проверим, что он верного формата */ - UTL_FISCDOC_CHECK_FFD_VERS(NCOMPANY => RFISCDOC.COMPANY, - NFISCDOC => RFISCDOC.RN, - NEXPECTED_VERS => NTAG1209_FFD105, - SEXPECTED_VERS => SFFD105); - /* Разбираем ответ */ - begin - RDOC := PKG_XPATH.PARSE_FROM_BLOB(LBXML => REXSQUEUE.RESP, SCHARSET => 'UTF8'); - exception - when others then - P_EXCEPTION(0, 'Ошибка разбора XML - неожиданный ответ сервера.'); - end; - /* Находим корневой элемент */ - RROOT_NODE := PKG_XPATH.ROOT_NODE(RDOCUMENT => RDOC); - /* Забираем значения документа */ - SSTATUS := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/STATUS')); - STAG1012 := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/TAG1012')); - STAG1038 := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/TAG1038')); - STAG1040 := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/TAG1040')); - STAG1041 := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/TAG1041')); - STAG1042 := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/TAG1042')); - STAG1077 := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, SPATTERN => '/RESP/TAG1077')); - STIMESTAMP := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, - SPATTERN => '/RESP/TIMESTAMP')); - SERR_CODE := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, - SPATTERN => '/RESP/ERROR/CODE')); - SERR_TEXT := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RROOT_NODE, - SPATTERN => '/RESP/ERROR/TEXT')); - /* Освобождаем память */ - PKG_XPATH.FREE(RDOCUMENT => RDOC); - /* Проверим, что указан статус документа */ - if (SSTATUS is null) then - P_EXCEPTION(0, 'Не указан статус обработки документа.'); - end if; - /* Обрабатываем ответ в зависимости от статуса */ - case SSTATUS - /* Обрабатывается */ - when SSTATUS_WAIT then - begin - /* Документ ещё не обработан, ожидаем результатов, поэтому пока ничего не делаем */ - null; - end; - /* Готов */ - when SSTATUS_DONE then - begin - /* Проверим наличие данных в тэгах и дату ответа АТОЛ */ - if (STIMESTAMP is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Дата и время документа внешней системы".', - SSTATUS); - end if; - if (STAG1012 is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Дата и время документа из ФН" (тэг 1012).', - SSTATUS); - end if; - if (STAG1038 is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Номер смены" (тэг 1038).', - SSTATUS); - end if; - if (STAG1040 is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Фискальный номер документа" (тэг 1040).', - SSTATUS); - end if; - if (STAG1041 is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Номер ФН" (тэг 1041).', - SSTATUS); - end if; - if (STAG1042 is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Номер чека в смене" (тэг 1042).', - SSTATUS); - end if; - if (STAG1077 is null) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указано значение "Фискальный признак документа" (тэг 1077).', - SSTATUS); - end if; - /* Проверяем корректность даты подтверждения */ - begin - DTIMESTAMP := TO_DATE(STIMESTAMP, 'dd.mm.yyyy hh24:mi:ss'); - exception - when others then - P_EXCEPTION(0, - 'Значение поля "Дата и время документа внешней системы" (%s) не является датой в формате "ДД.ММ.ГГГГ ЧЧ:МИ:CC"', - STIMESTAMP); - end; - /* Выставляем значение "Дата подтверждения" и "Ссылка на фискальный документ в ОФД" для фискального документа */ - update UDO_FISCDOCS T - set T.CONFIRM_DATE = DTIMESTAMP, - T.DOC_URL = replace(replace(replace(SBILL_OFD_UTL, '<1040>', STAG1040), '<1041>', STAG1041), - '<1077>', - STAG1077) - where T.RN = RFISCDOC.RN; - /* Устанавливаем значения тэгов */ - begin - UDO_P_FISCDOCSPROP_SET_VAL(NPRN => RFISCDOC.RN, - NCOMPANY => RFISCDOC.COMPANY, - SATTRIBUTE => '1012', - DVAL_DATETIME => TO_DATE(STAG1012, 'dd.mm.yyyy hh24:mi:ss')); - UDO_P_FISCDOCSPROP_SET_VAL(NPRN => RFISCDOC.RN, - NCOMPANY => RFISCDOC.COMPANY, - SATTRIBUTE => '1038', - NVAL_NUMB => TO_NUMBER(STAG1038)); - UDO_P_FISCDOCSPROP_SET_VAL(NPRN => RFISCDOC.RN, - NCOMPANY => RFISCDOC.COMPANY, - SATTRIBUTE => '1040', - NVAL_NUMB => TO_NUMBER(STAG1040)); - UDO_P_FISCDOCSPROP_SET_VAL(NPRN => RFISCDOC.RN, - NCOMPANY => RFISCDOC.COMPANY, - SATTRIBUTE => '1041', - SVAL_STR => STAG1041); - UDO_P_FISCDOCSPROP_SET_VAL(NPRN => RFISCDOC.RN, - NCOMPANY => RFISCDOC.COMPANY, - SATTRIBUTE => '1042', - NVAL_NUMB => TO_NUMBER(STAG1042)); - UDO_P_FISCDOCSPROP_SET_VAL(NPRN => RFISCDOC.RN, - NCOMPANY => RFISCDOC.COMPANY, - SATTRIBUTE => '1077', - SVAL_STR => STAG1077); - exception - when others then - P_EXCEPTION(0, - 'Ошибка установки значения атрибута фискального документа: %s', - sqlerrm); - end; - /* Ставим задачу на получение чека от ОФД */ - PKG_EXS.QUEUE_PUT(SEXSSERVICE => 'ОФД_ПолучЧека', - SEXSSERVICEFN => 'ПолучЧека', - BMSG => CLOB2BLOB(LCDATA => STAG1041 || '/' || STAG1040 || '/' || STAG1077, - SCHARSET => 'UTF8'), - NLNK_COMPANY => RFISCDOC.COMPANY, - NLNK_DOCUMENT => RFISCDOC.RN, - SLNK_UNITCODE => 'UDO_FiscalDocuments', - NNEW_EXSQUEUE => NNEW_EXSQUEUE); - end; - /* Ошибка обработки */ - when SSTATUS_FAIL then - begin - /* Проверим, что пришли код и текст ошибки */ - if ((SERR_CODE is null) or (SERR_TEXT is null)) then - P_EXCEPTION(0, - 'Документ в статусе "%s", но не указан код или текст ошибки.', - SSTATUS); - end if; - /* Выставим код и текст в фискальном документе */ - update UDO_FISCDOCS T - set T.SEND_ERROR = SUBSTR(SERR_CODE || ': ' || - REGEXP_REPLACE(replace(SERR_TEXT, CHR(10), ''), '[[:space:]]+', ' '), - 1, - 4000) - where T.RN = RFISCDOC.RN; - end; - /* Неизвестный статус */ - else - P_EXCEPTION(0, 'Cтатус докуента "%s" не поддерживается.', SSTATUS); - end case; - /* Всё прошло успешно */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT); - exception - when others then - /* Вернём ошибку */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end V4_FFD105_PROCESS_GET_BILL_INF; - - /* Отработка ответов ОФД на запрос чека */ - procedure OFD_PROCESS_GET_BILL_DOC - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди - begin - /* Считаем запись очереди */ - REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE); - /* Проверим что позиция очереди корректна */ - UTL_EXSQUEUE_CHECK_ATTRS(REXSQUEUE => REXSQUEUE); - /* Сохраним полученный чек в ФД */ - UDO_P_FISCDOCS_PUT_BILL(NRN => REXSQUEUE.LNK_DOCUMENT, NCOMPANY => REXSQUEUE.LNK_COMPANY, BDATA => REXSQUEUE.RESP); - /* Всё прошло успешно */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT); - exception - when others then - /* Вернём ошибку */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end OFD_PROCESS_GET_BILL_DOC; - -end; -/ diff --git a/db/UDO_PKG_EXS_INV.pck b/db/UDO_PKG_EXS_INV.pck deleted file mode 100644 index 897a830..0000000 --- a/db/UDO_PKG_EXS_INV.pck +++ /dev/null @@ -1,1655 +0,0 @@ -create or replace package UDO_PKG_EXS_INV as - - /* Считывание значения структурного элемента из иерархии адреса географического понятия */ - function UTL_GEOGRAFY_GET_HIER_ITEM - ( - NGEOGRAFY in number, -- Регистрационный номер географического понятия - NGEOGRTYPE in number -- Тип искомого структурного элемента адреса (1 - страна, 2 - регион, 3 - район, 4 - населенный пункт, 5 - улица, 6 - административный округ, 7 - муниципальный округ, 8 - город, 9 - уровень внутригородской территории, 10 - уровень дополнительных территорий, 11 - уровень подчиненных дополнительным территориям объектов) - ) return varchar2; -- Наименование найденного стуктурного элемента адреса - - /* Поиск геопонятия по стуктурным элементам */ - function UTL_GEOGRAFY_FIND_BY_HIER_ITEM - ( - NCOMPANY in number, -- Рег. номер организации - SADDR_COUNTRY in varchar2, -- Страна местонахождения - SADDR_REGION in varchar2, -- Регион местонахождения - SADDR_LOCALITY in varchar2, -- Населённый пункт местонахождения - SADDR_STREET in varchar2 -- Улица местонахождения - ) return number; -- Географическое понятие - - /* Получение данных о местонахождении позиции ведомости инвентаризации */ - function UTL_ELINVOBJECT_DICPLACE_GET - ( - NELINVOBJECT in number, -- Рег. номер записи ведомости инвентаризации - SRESULT_TYPE in varchar2 -- Тип результата (см. констнаты SRESULT_TYPE*) - ) return varchar2; -- Штрих-код ОС - - /* Получение штрих-кода позиции ведомости инвентаризации */ - function UTL_ELINVOBJECT_BARCODE_GET - ( - NELINVOBJECT in number -- Рег. номер записи ведомости инвентаризации - ) return varchar2; -- Штрих-код ОС - - /* Электронная инвентаризация - аутентификация */ - procedure CHECKAUTH - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Электронная инвентаризация - считывание пользователей */ - procedure GETUSERS - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Электронная инвентаризация - считывание типов ведомостей */ - procedure GETSHEETTYPES - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Электронная инвентаризация - считывание заголовков ведомостей инвентаризации */ - procedure GETSHEETS - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Электронная инвентаризация - считывание состава ведомостей инвентаризации */ - procedure GETSHEETITEMS - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Электронная инвентаризация - считывание местонахождений */ - procedure GETSTORAGES - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Электронная инвентаризация - сохранение результатов инвентаризации элемента хранения */ - procedure SAVESHEETITEM - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - -end; -/ -create or replace package body UDO_PKG_EXS_INV as - - /* Константы - пространства имён */ - SNS_TSD constant varchar2(40) := 'tsd'; - SNS_SOAPENV constant varchar2(40) := 'soapenv'; - - /* Константы - тэги */ - STAG_CHECKAUTHRSPNS constant varchar2(40) := 'CheckAuthResponse'; - STAG_GETUSERSRSPNS constant varchar2(40) := 'GetUsersResponse'; - STAG_GETSHEETTYPESRSPNS constant varchar2(40) := 'GetSheetTypesResponse'; - STAG_GETSHEETSRSPNS constant varchar2(40) := 'GetSheetsResponse'; - STAG_GETSTORAGESRSPNS constant varchar2(40) := 'GetStoragesResponse'; - STAG_GETSHEETITEMSRSPNS constant varchar2(40) := 'GetSheetItemsResponse'; - STAG_SAVESHEETITEMRSPNS constant varchar2(40) := 'SaveSheetItemResponse'; - STAG_DEVICEID constant varchar2(40) := 'DeviceID'; - STAG_RESULT constant varchar2(40) := 'Result'; - STAG_ENVELOPE constant varchar2(40) := 'Envelope'; - STAG_HEADER constant varchar2(40) := 'Header'; - STAG_BODY constant varchar2(40) := 'Body'; - STAG_ITEM constant varchar2(40) := 'Item'; - STAG_CODE constant varchar2(40) := 'Code'; - STAG_NAME constant varchar2(40) := 'Name'; - STAG_TYPECODE constant varchar2(40) := 'TypeCode'; - STAG_PREFIX constant varchar2(40) := 'Prefix'; - STAG_NUMBER constant varchar2(40) := 'Number'; - STAG_DATE constant varchar2(40) := 'Date'; - STAG_SHEETCODE constant varchar2(40) := 'SheetCode'; - STAG_MNEMOCODE constant varchar2(40) := 'MnemoCode'; - STAG_LATITUDE constant varchar2(40) := 'Latitude'; - STAG_LONGITUDE constant varchar2(40) := 'Longitude'; - STAG_POSTCODE constant varchar2(40) := 'Postcode'; - STAG_COUNTRY constant varchar2(40) := 'Country'; - STAG_REGION constant varchar2(40) := 'Region'; - STAG_LOCALITY constant varchar2(40) := 'Locality'; - STAG_STREET constant varchar2(40) := 'Street'; - STAG_HOUSENUMBER constant varchar2(40) := 'HouseNumber'; - STAG_STORAGEMNEMOCODE constant varchar2(40) := 'StorageMnemoCode'; - STAG_USERCODE constant varchar2(40) := 'UserCode'; - STAG_ITEMCODE constant varchar2(40) := 'ItemCode'; - STAG_ITEMNAME constant varchar2(40) := 'ItemName'; - STAG_ITEMMNEMOCODE constant varchar2(40) := 'ItemMnemoCode'; - STAG_ITEMNUMBER constant varchar2(40) := 'ItemNumber'; - STAG_QUANTITY constant varchar2(40) := 'Quantity'; - STAG_STORAGEISNEW constant varchar2(40) := 'StorageIsNew'; - STAG_STORAGECODE constant varchar2(40) := 'StorageCode'; - STAG_STORAGENAME constant varchar2(40) := 'StorageName'; - STAG_STORAGEPOSTCODE constant varchar2(40) := 'StoragePostcode'; - STAG_STORAGECOUNTRY constant varchar2(40) := 'StorageCountry'; - STAG_STORAGEREGION constant varchar2(40) := 'StorageRegion'; - STAG_STORAGELOCALITY constant varchar2(40) := 'StorageLocality'; - STAG_STORAGESTREET constant varchar2(40) := 'StorageStreet'; - STAG_STORAGEHOUSENUMBER constant varchar2(40) := 'StorageHouseNumber'; - STAG_STORAGELATITUDE constant varchar2(40) := 'StorageLatitude'; - STAG_STORAGELONGITUDE constant varchar2(40) := 'StorageLongitude'; - STAG_CHECKDATE constant varchar2(40) := 'CheckDate'; - STAG_COMMENT constant varchar2(40) := 'Comment'; - STAG_DISTANCETOSTORAGE constant varchar2(40) := 'DistanceToStorage'; - STAG_FAULT constant varchar2(40) := 'Fault'; - STAG_DETAIL constant varchar2(40) := 'detail'; - STAG_MESSAGE constant varchar2(40) := 'Message'; - STAG_STORAGEMESSAGE constant varchar2(40) := 'StorageMessage'; - STAG_ITEMMESSAGE constant varchar2(40) := 'ItemMessage'; - STAG_ERRORMESSAGE constant varchar2(40) := 'ErrorMessage'; - STAG_ERRORMESSAGE_SSITEM constant varchar2(40) := 'ErrorSaveSheetItemMessage'; - - /* Константы - типы возвращаемых значений */ - SRESULT_TYPE_MNEMO constant varchar2(40):='MNEMO'; -- Мнемокод - SRESULT_TYPE_BARCODE constant varchar2(40):='BARCODE'; -- Штрих-код - - /* Нормализация сообщения об ошибке */ - function UTL_CORRECT_ERR - ( - SERR varchar2 -- Сообщение об ошибке - ) return varchar2 -- Нормализованное сообщение об ошибке - is - STMP PKG_STD.TSTRING; -- Буфер для обработки - SRES PKG_STD.TSTRING; -- Результат работы - NB PKG_STD.TLNUMBER; -- Позиция начала удаляемой подстроки - NE PKG_STD.TLNUMBER; -- Позиция окончания удаляемой подстроки - begin - /* Инициализируем буфер */ - STMP := SERR; - /* Удаляем лишние спецсимволы и техническую информацию из ошибки */ - begin - while (INSTR(STMP, 'ORA') <> 0) - loop - NB := INSTR(STMP, 'ORA'); - NE := INSTR(STMP, ':', NB); - STMP := trim(replace(STMP, trim(SUBSTR(STMP, NB, NE - NB + 1)), '')); - end loop; - SRES := STMP; - exception - when others then - SRES := SERR; - end; - /* Возвращаем резульат */ - return SRES; - end UTL_CORRECT_ERR; - - /* Создание ветки XML */ - function UTL_CREATENODE - ( - XDOC in DBMS_XMLDOM.DOMDOCUMENT, -- Документ - STAG in varchar2, -- Наименование тэга - SNS in varchar2 default null, -- Пространство имён - SVAL in varchar2 default null -- Значение тэга - ) - return DBMS_XMLDOM.DOMNODE -- Ссылка на сформированный тэг документа - is - XEL DBMS_XMLDOM.DOMELEMENT; -- Элемент пространства имён - XNODE DBMS_XMLDOM.DOMNODE; -- Формируемая ветка - XTEXT DBMS_XMLDOM.DOMNODE; -- Текст (значение) формируемой ветки - begin - /* Если задано пространство имён */ - if (SNS is not null) then - /* Создаём элемент с его использованием */ - XEL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG, NS => SNS); - XNODE := DBMS_XMLDOM.MAKENODE(ELEM => XEL); - DBMS_XMLDOM.SETPREFIX(N => XNODE, PREFIX => SNS); - else - /* Или без него */ - XEL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG); - XNODE := DBMS_XMLDOM.MAKENODE(ELEM => XEL); - end if; - /* Значение размещаем в текстовой части ветки */ - if (SVAL is not null) then - XTEXT := DBMS_XMLDOM.APPENDCHILD(N => XNODE, - NEWCHILD => DBMS_XMLDOM.MAKENODE(T => DBMS_XMLDOM.CREATETEXTNODE(DOC => XDOC, - DATA => SVAL))); - end if; - /* Вернем результат */ - return XNODE; - end UTL_CREATENODE; - - /* Считывание значения ветки XML */ - function UTL_GETNODEVAL - ( - XROOTNODE in DBMS_XMLDOM.DOMNODE, -- Корневая ветка для считывания значения - SPATTERN in varchar2 -- Шаблон для считывания данных - ) - return varchar2 -- Считанное значение - is - XNODE DBMS_XMLDOM.DOMNODE; -- Искомая ветка со значением (подходящая под шаблон) - SVAL PKG_STD.TSTRING; -- Результат работы - begin - /* Найдем нужную ветку по шаблону */ - XNODE := DBMS_XSLPROCESSOR.SELECTSINGLENODE(N => XROOTNODE, PATTERN => SPATTERN); - /* Если там нет ничего */ - if (DBMS_XMLDOM.ISNULL(N => XNODE)) then - /* Его и вернём */ - return null; - end if; - /* Что-то есть - читаем данные */ - SVAL := DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(N => XNODE)); - /* Отдаём результат */ - return SVAL; - end UTL_GETNODEVAL; - - /* Создание документа для ответа */ - procedure UTL_CREATERESPONSEDOC - ( - XDOC out DBMS_XMLDOM.DOMDOCUMENT -- Буфер для документа - ) - is - begin - /* Создаём новый документ */ - XDOC := DBMS_XMLDOM.NEWDOMDOCUMENT(); - /* Выставляем параметры заголовка */ - DBMS_XMLDOM.SETVERSION(DOC => XDOC, VERSION => '1.0" encoding="UTF-8'); - /* Выставляем кодировку */ - DBMS_XMLDOM.SETCHARSET(DOC => XDOC, CHARSET => 'UTF-8'); - end UTL_CREATERESPONSEDOC; - - /* Формировние ответа на запрос из XML-документа (обёртывание в конверт подготовленных данных) */ - function UTL_CREATERESPONSE - ( - XDOC in DBMS_XMLDOM.DOMDOCUMENT, -- Документ - XCONTENT in DBMS_XMLDOM.DOMNODE -- Наименование тэга с отправляемым контентом - ) return clob -- Результат работы - is - XMAIN_NODE DBMS_XMLDOM.DOMNODE; -- Корневой элемент документа - XENVELOPE_EL DBMS_XMLDOM.DOMELEMENT; -- Элемент для обёртки ответа - XENVELOPE DBMS_XMLDOM.DOMNODE; -- Обёртка ответа - XHEADER DBMS_XMLDOM.DOMNODE; -- Элемент для заголовока ответа - XBODY DBMS_XMLDOM.DOMNODE; -- Элемент для тела ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Текущий элемент документа - CDATA clob; -- Буфер для результата - begin - /* Подготовим документ */ - XMAIN_NODE := DBMS_XMLDOM.MAKENODE(DOC => XDOC); - /* Обернём его в конверт */ - XENVELOPE_EL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG_ENVELOPE, NS => SNS_SOAPENV); - DBMS_XMLDOM.SETATTRIBUTE(ELEM => XENVELOPE_EL, - name => 'xmlns:soapenv', - NEWVALUE => 'http://schemas.xmlsoap.org/soap/envelope/'); - DBMS_XMLDOM.SETATTRIBUTE(ELEM => XENVELOPE_EL, - name => 'xmlns:tsd', - NEWVALUE => 'http://www.example.org/TSDService/'); - XENVELOPE := DBMS_XMLDOM.MAKENODE(ELEM => XENVELOPE_EL); - DBMS_XMLDOM.SETPREFIX(N => XENVELOPE, PREFIX => SNS_SOAPENV); - XENVELOPE := DBMS_XMLDOM.APPENDCHILD(N => XMAIN_NODE, NEWCHILD => XENVELOPE); - /* Сформируем заголовок */ - XHEADER := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_HEADER, SNS => SNS_SOAPENV); - XHEADER := DBMS_XMLDOM.APPENDCHILD(N => XENVELOPE, NEWCHILD => XHEADER); - /* Сформируем тело */ - XBODY := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_BODY, SNS => SNS_SOAPENV); - XBODY := DBMS_XMLDOM.APPENDCHILD(N => XENVELOPE, NEWCHILD => XBODY); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XBODY, NEWCHILD => XCONTENT); - /* Конвертируем в CLOB */ - DBMS_LOB.CREATETEMPORARY(LOB_LOC => CDATA, CACHE => true, DUR => DBMS_LOB.SESSION); - DBMS_XMLDOM.WRITETOCLOB(DOC => XDOC, CL => CDATA, CHARSET => 'UTF-8'); - DBMS_XMLDOM.FREEDOCUMENT(DOC => XDOC); - /* Вернем результат */ - return CDATA; - end UTL_CREATERESPONSE; - - /* Формирование ответа с ошибкой */ - function UTL_CREATEERRORRESPONSE - ( - SMSG in varchar2 -- Сообщение об ошибке - ) return clob -- Результат работы - is - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XFAULT DBMS_XMLDOM.DOMNODE; -- Корневой узел - XDETAIL DBMS_XMLDOM.DOMNODE; -- Узел для детализации ошибки - XERRMSG DBMS_XMLDOM.DOMNODE; -- Узел с сообщением об ошибке - XMSG DBMS_XMLDOM.DOMNODE; -- Узел текстом сообщения - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для узла - CDATA clob; -- Буфер для результата - begin - /* Создаём документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Собираем ошибку в ответ */ - XFAULT := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_FAULT, SNS => SNS_SOAPENV); - XDETAIL := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_DETAIL); - XERRMSG := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ERRORMESSAGE, SNS => SNS_TSD); - XMSG := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_MESSAGE, SNS => SNS_TSD, SVAL => SMSG); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XERRMSG, NEWCHILD => XMSG); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XDETAIL, NEWCHILD => XERRMSG); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XFAULT, NEWCHILD => XDETAIL); - CDATA := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XFAULT); - /* Возвращаем результат */ - return CDATA; - end UTL_CREATEERRORRESPONSE; - - /* Формирование ответа с ошибкой для процедуры импорта результатов инвентаризации */ - function UTL_CREATEERRORRESPONSE_SSITEM - ( - SMSG_ELINVOBJECT in varchar2, -- Сообщение об ошибке (для инвентарного объекта) - SMSG_DICPLACE in varchar2 -- Сообщение об ошибке (для местонахождения) - ) return clob -- Результат работы - is - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XFAULT DBMS_XMLDOM.DOMNODE; -- Корневой узел - XDETAIL DBMS_XMLDOM.DOMNODE; -- Узел для детализации ошибки - XERRMSG DBMS_XMLDOM.DOMNODE; -- Узел с сообщением об ошибке - XMSG_ELINVOBJECT DBMS_XMLDOM.DOMNODE; -- Узел текстом сообщения (для инвентарного объекта) - XMSG_DICPLACE DBMS_XMLDOM.DOMNODE; -- Узел текстом сообщения (для местонахождения) - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для узла - CDATA clob; -- Буфер для результата - begin - /* Создаём документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Собираем ошибку в ответ */ - XFAULT := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_FAULT, SNS => SNS_SOAPENV); - XDETAIL := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_DETAIL); - XERRMSG := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ERRORMESSAGE_SSITEM, SNS => SNS_TSD); - XMSG_ELINVOBJECT := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ITEMMESSAGE, SNS => SNS_TSD, SVAL => SMSG_ELINVOBJECT); - XMSG_DICPLACE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_STORAGEMESSAGE, SNS => SNS_TSD, SVAL => SMSG_DICPLACE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XERRMSG, NEWCHILD => XMSG_ELINVOBJECT); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XERRMSG, NEWCHILD => XMSG_DICPLACE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XDETAIL, NEWCHILD => XERRMSG); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XFAULT, NEWCHILD => XDETAIL); - CDATA := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XFAULT); - /* Возвращаем результат */ - return CDATA; - end UTL_CREATEERRORRESPONSE_SSITEM; - - /* Считывание значения структурного элемента из иерархии адреса географического понятия */ - function UTL_GEOGRAFY_GET_HIER_ITEM - ( - NGEOGRAFY in number, -- Регистрационный номер географического понятия - NGEOGRTYPE in number -- Тип искомого структурного элемента адреса (1 - страна, 2 - регион, 3 - район, 4 - населенный пункт, 5 - улица, 6 - административный округ, 7 - муниципальный округ, 8 - город, 9 - уровень внутригородской территории, 10 - уровень дополнительных территорий, 11 - уровень подчиненных дополнительным территориям объектов) - ) return varchar2 -- Наименование найденного стуктурного элемента адреса - is - SRES PKG_STD.TSTRING; -- Результат работы - begin - /* Обходим адрес снизу вверх */ - for REC in (select G.GEOGRNAME, - G.GEOGRTYPE - from GEOGRAFY G - connect by prior G.PRN = G.RN - start with G.RN = NGEOGRAFY) - loop - if (REC.GEOGRTYPE = NGEOGRTYPE) then - SRES := REC.GEOGRNAME; - exit; - end if; - end loop; - /* Вернём результат */ - return SRES; - end UTL_GEOGRAFY_GET_HIER_ITEM; - - /* Поиск геопонятия по стуктурным элементам */ - function UTL_GEOGRAFY_FIND_BY_HIER_ITEM - ( - NCOMPANY in number, -- Рег. номер организации - SADDR_COUNTRY in varchar2, -- Страна местонахождения - SADDR_REGION in varchar2, -- Регион местонахождения - SADDR_LOCALITY in varchar2, -- Населённый пункт местонахождения - SADDR_STREET in varchar2 -- Улица местонахождения - ) return number -- Географическое понятие - is - NRES PKG_STD.TREF; -- Рег. номер найденного географического понятия - NVERSION PKG_STD.TREF; -- Рег. номер версии словаря географических понятий - begin - /* Проверим параметры */ - if (NCOMPANY is null) then - return null; - end if; - if ((SADDR_COUNTRY is null) and (SADDR_REGION is null) and (SADDR_LOCALITY is null) and (SADDR_STREET is null)) then - return null; - end if; - /* Определим версию словаря географических понятий */ - FIND_VERSION_BY_COMPANY(NCOMPANY => NCOMPANY, SUNITCODE => 'GEOGRAFY', NVERSION => NVERSION); - /* Подберем географическое понятие - сначала страны */ - for C in (select G.RN - from GEOGRAFY G - where G.VERSION = NVERSION - and ((SADDR_COUNTRY is null) or - ((SADDR_COUNTRY is not null) and (LOWER(G.GEOGRNAME) like LOWER('%' || SADDR_COUNTRY || '%')))) - and G.GEOGRTYPE = 1) - loop - /* Теперь регионы страны */ - for R in (select G.RN - from GEOGRAFY G - where G.VERSION = NVERSION - and ((SADDR_REGION is null) or - ((SADDR_REGION is not null) and (LOWER(G.GEOGRNAME) like LOWER('%' || SADDR_REGION || '%')))) - and G.GEOGRTYPE = 2 - and G.RN in (select GG.RN - from GEOGRAFY GG - where GG.GEOGRTYPE = 2 - connect by prior GG.RN = GG.PRN - start with GG.RN = C.RN)) - loop - /* Спускаемся в населенные пункты */ - for L in (select G.RN - from GEOGRAFY G - where G.VERSION = NVERSION - and ((SADDR_LOCALITY is null) or ((SADDR_LOCALITY is not null) and - (LOWER(G.GEOGRNAME) like LOWER('%' || SADDR_LOCALITY || '%')))) - and G.GEOGRTYPE in (8, 4, 3, 2) - and G.RN in (select GG.RN - from GEOGRAFY GG - where GG.GEOGRTYPE in (8, 4, 3, 2) - connect by prior GG.RN = GG.PRN - start with GG.RN = R.RN) - - ) - loop - /* Теперь - улицы */ - for S in (select G.RN - from GEOGRAFY G - where G.VERSION = NVERSION - and ((SADDR_STREET is null) or - ((SADDR_STREET is not null) and (LOWER(G.GEOGRNAME) like LOWER('%' || SADDR_STREET || '%')))) - and G.GEOGRTYPE = 5 - and G.RN in (select GG.RN - from GEOGRAFY GG - where GG.GEOGRTYPE = 5 - connect by prior GG.RN = GG.PRN - start with GG.RN = L.RN) - - ) - loop - /* Возврат результата */ - return S.RN; - end loop; - end loop; - end loop; - end loop; - /* Вернём пустой результат - сюда приходим только если ничего не нашли */ - return NRES; - end UTL_GEOGRAFY_FIND_BY_HIER_ITEM; - - /* Проверка идентификатора устройства */ - procedure UTL_CHECK_DEVICEID - ( - SDEVICEID in varchar2 -- Идентификатор устройства - ) - is - SLIC_DEVICEIDS LICCTRLSPEC.SERIAL_NO%type; -- Список идентификаторов устройств в лицензии - begin - /* Считаем идентификаторы устройств из лицензии */ - begin - select LS.SERIAL_NO - into SLIC_DEVICEIDS - from LICCTRL L, - LICCTRLSPEC LS - where L.LICENSE_TYPE = 0 - and L.RN = LS.PRN - and LS.APPLICATION = 'Account' - and ROWNUM <= 1; - exception - when NO_DATA_FOUND then - SLIC_DEVICEIDS := null; - end; - /* Если в составе лицензии нет переданного идентификатора */ - if (SLIC_DEVICEIDS like '%' || SDEVICEID || '%') then - /* Скажем об этом */ - P_EXCEPTION(0, - 'Идентификатор устровйства "%s" не определён в лицензии.', - SDEVICEID); - end if; - end UTL_CHECK_DEVICEID; - - /* Получение корневого элемента тела из сообщения очереди обмена */ - procedure UTL_EXSQUEUE_MSG_GET_BODY_ROOT - ( - NEXSQUEUE in number, -- Регистрационный номер обрабатываемой позиции очереди обмена - XNODE_ROOT out DBMS_XMLDOM.DOMNODE -- Корневой элемент первой ветки тела документа - ) - is - REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XMLPARCER DBMS_XMLPARSER.PARSER; -- Парсер - XENVELOPE DBMS_XMLDOM.DOMNODE; -- Конверт - XBODY DBMS_XMLDOM.DOMNODE; -- Тело документа - XNODELIST DBMS_XMLDOM.DOMNODELIST; -- Ветки тела документа - CREQ clob; -- Буфер для запроса - begin - /* Считаем запись очереди */ - REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE); - /* Возьмем текст запроса */ - CREQ := BLOB2CLOB(LBDATA => REXSQUEUE.MSG, SCHARSET => 'UTF8'); - /* Создаем инстанс XML парсера */ - XMLPARCER := DBMS_XMLPARSER.NEWPARSER; - /* Разбираем XML из запроса */ - DBMS_XMLPARSER.PARSECLOB(P => XMLPARCER, DOC => CREQ); - /* Берем XML документ из разобранного */ - XDOC := DBMS_XMLPARSER.GETDOCUMENT(P => XMLPARCER); - /* Считываем корневой элемент */ - XENVELOPE := DBMS_XMLDOM.MAKENODE(ELEM => DBMS_XMLDOM.GETDOCUMENTELEMENT(DOC => XDOC)); - /* Считываем элемент тело */ - XBODY := DBMS_XSLPROCESSOR.SELECTSINGLENODE(N => XENVELOPE, PATTERN => STAG_BODY); - /* Считываем дочерние элементы тела */ - XNODELIST := DBMS_XMLDOM.GETCHILDNODES(N => XBODY); - /* Берем первый дочерний элемент */ - XNODE_ROOT := DBMS_XMLDOM.ITEM(NL => XNODELIST, IDX => 0); - end UTL_EXSQUEUE_MSG_GET_BODY_ROOT; - - /* Получение данных о местонахождении позиции ведомости инвентаризации */ - function UTL_ELINVOBJECT_DICPLACE_GET - ( - NELINVOBJECT in number, -- Рег. номер записи ведомости инвентаризации - SRESULT_TYPE in varchar2 -- Тип результата (см. констнаты SRESULT_TYPE*) - ) return varchar2 -- Штрих-код ОС - is - SRES PKG_STD.TSTRING; -- Результат работы - begin - /* Найдем искомые значения атрибутов местонахождения */ - begin - select DECODE(SRESULT_TYPE, - SRESULT_TYPE_MNEMO, - DECODE(T.INVPACK, null, O.PLACE_MNEMO, OP.PLACE_MNEMO), - SRESULT_TYPE_BARCODE, - DECODE(T.INVPACK, null, O.BARCODE, OP.BARCODE), - null) - into SRES - from ELINVOBJECT T, - INVENTORY I, - DICPLACE O, - DICPLACE OP, - INVPACK P - where T.RN = NELINVOBJECT - and T.INVENTORY = I.RN - and I.OBJECT_PLACE = O.RN(+) - and T.INVPACK = P.RN(+) - and P.OBJECT_PLACE = OP.RN(+); - exception - when NO_DATA_FOUND then - SRES := null; - end; - /* Вернём результат */ - return SRES; - end UTL_ELINVOBJECT_DICPLACE_GET; - - /* Получение штрих-кода позиции ведомости инвентаризации */ - function UTL_ELINVOBJECT_BARCODE_GET - ( - NELINVOBJECT in number -- Рег. номер записи ведомости инвентаризации - ) return varchar2 -- Штрих-код ОС - is - SRES PKG_STD.TSTRING; -- Результат работы - begin - /* Считаем штрих-код позиции ведомости инвентаризации */ - begin - select DECODE(PS.RN, - null, - DECODE(T.INVPACK, null, DECODE(T.INVSUBST, null, I.BARCODE, U.BARCODE), P.BARCODE), - PS.BARCODE) - into SRES - from ELINVOBJECT T, - INVENTORY I, - INVPACK P, - INVPACKPOS PS, - INVSUBST U - where T.RN = NELINVOBJECT - and T.INVENTORY = I.RN - and T.INVPACK = P.RN(+) - and T.INVPACK = PS.PRN(+) - and T.INVSUBST = PS.INVSUBST(+) - and T.INVSUBST = U.RN(+); - exception - when NO_DATA_FOUND then - SRES := null; - end; - /* Вернём результат */ - return SRES; - end UTL_ELINVOBJECT_BARCODE_GET; - - /* Электронная инвентаризация - аутентификация */ - procedure CHECKAUTH - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XCHECKAUTHRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XRESULT DBMS_XMLDOM.DOMNODE; -- Результат аутентификации - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Т.к. пока проверок нет никаких - всегда возвращаем положительный ответ */ - XCHECKAUTHRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_CHECKAUTHRSPNS, SNS => SNS_TSD); - XRESULT := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_RESULT, SNS => SNS_TSD, SVAL => 'true'); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XCHECKAUTHRESPONSE, NEWCHILD => XRESULT); - /* Оборачиваем его в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XCHECKAUTHRESPONSE); - exception - /* Перехватываем возможные ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end CHECKAUTH; - - /* Электронная инвентаризация - считывание пользователей */ - procedure GETUSERS - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XGETUSERSRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XITEM DBMS_XMLDOM.DOMNODE; -- Элемент ответного списка - XCODE DBMS_XMLDOM.DOMNODE; -- Код элемента ответного списка - XNAME DBMS_XMLDOM.DOMNODE; -- Нименование элемента ответного списка - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Создаём пространство имён для ответа */ - XGETUSERSRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_GETUSERSRSPNS, SNS => SNS_TSD); - /* Обходим сотрудников-инвентаризаторов */ - for REC in (select T.RN, - A.AGNABBR - from INVPERSONS T, - AGNLIST A - where T.COMPANY = 136018 - and T.AGNLIST = A.RN) - loop - /* Собираем информацию по сотруднику в ответ */ - XITEM := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ITEM, SNS => SNS_TSD); - XCODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_CODE, SNS => SNS_TSD, SVAL => REC.RN); - XNAME := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_NAME, SNS => SNS_TSD, SVAL => REC.AGNABBR); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XNAME); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XGETUSERSRESPONSE, NEWCHILD => XITEM); - end loop; - /* Оборачиваем ответ в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XGETUSERSRESPONSE); - exception - /* Перехватываем возможные ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end GETUSERS; - - /* Электронная инвентаризация - считывание типов ведомостей */ - procedure GETSHEETTYPES - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XGETSHEETTYPESRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XITEM DBMS_XMLDOM.DOMNODE; -- Элемент ответного списка - XCODE DBMS_XMLDOM.DOMNODE; -- Код элемента ответного списка - XNAME DBMS_XMLDOM.DOMNODE; -- Нименование элемента ответного списка - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Создаём пространство имён для ответа */ - XGETSHEETTYPESRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_GETSHEETTYPESRSPNS, SNS => SNS_TSD); - /* Обходим типы документов связанные с разделом "Электронные инвентаризации" */ - for REC in (select T.RN, - T.DOCCODE - from DOCTYPES T, - COMPVERLIST CV - where T.VERSION = CV.VERSION - and CV.COMPANY = 136018 - and T.RN in (select DOCRN from DOCPARAMS where DOCPARAMS.UNITCODE = 'ElectronicInventories') - order by T.DOCCODE) - loop - /* Собираем информацию по типу документа в ответ */ - XITEM := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ITEM, SNS => SNS_TSD); - XCODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_CODE, SNS => SNS_TSD, SVAL => REC.RN); - XNAME := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_NAME, SNS => SNS_TSD, SVAL => REC.DOCCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XNAME); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XGETSHEETTYPESRESPONSE, NEWCHILD => XITEM); - end loop; - /* Оборачиваем ответ в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XGETSHEETTYPESRESPONSE); - exception - /* Перехватываем возможные ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end GETSHEETTYPES; - - /* Электронная инвентаризация - считывание заголовков ведомостей инвентаризации */ - procedure GETSHEETS - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XGETSHEETSRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XITEM DBMS_XMLDOM.DOMNODE; -- Элемент ответного списка - XCODE DBMS_XMLDOM.DOMNODE; -- Код элемента ответного списка - XNAME DBMS_XMLDOM.DOMNODE; -- Нименование элемента ответного списка - XTYPECODE DBMS_XMLDOM.DOMNODE; -- Тип ведомости элемента ответного списка - XPREFIX DBMS_XMLDOM.DOMNODE; -- Префикс ведомости элемента ответного списка - XNUMBER DBMS_XMLDOM.DOMNODE; -- Номер ведомости элемента ответного списка - XDATE DBMS_XMLDOM.DOMNODE; -- Дата ведомости элемента ответного списка - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - NREQ_TYPECODE PKG_STD.TREF; -- Тип ведомости из запроса (параметр отбора) - SREQ_PREFIX PKG_STD.TSTRING; -- Префикс ведомости из запроса (параметр отбора) - SREQ_NUMBER PKG_STD.TSTRING; -- Номер ведомости из запроса (параметр отбора) - DREQ_DATE PKG_STD.TLDATE; -- Дата ведомости из запроса (параметр отбора) - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Считываем "Тип ведомости" (параметр отбора) */ - NREQ_TYPECODE := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_TYPECODE)); - /* Считываем "Префикс" (параметр отбора) */ - SREQ_PREFIX := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_PREFIX); - /* Считываем "Номер" (параметр отбора) */ - SREQ_NUMBER := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_NUMBER); - /* Считываем "Дату" (параметр отбора) */ - DREQ_DATE := TO_DATE(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DATE), 'YYYY-MM-DD'); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Создаём пространство имён для ответа */ - XGETSHEETSRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_GETSHEETSRSPNS, SNS => SNS_TSD); - /* Обходим записи раздела "Электронные инвентаризации" удовлетворяющие условиям отбора */ - for REC in (select T.RN, - T.DOC_TYPE, - DT.DOCCODE as DOC_TYPE_CODE, - trim(T.DOC_PREF) as DOC_PREF, - trim(T.DOC_NUMB) as DOC_NUMB, - T.DOC_DATE - from ELINVENTORY T, - DOCTYPES DT - where T.COMPANY = 136018 - and T.DOC_TYPE = DT.RN - and (NREQ_TYPECODE is null or (NREQ_TYPECODE is not null and T.DOC_TYPE = NREQ_TYPECODE)) - and (SREQ_PREFIX is null or (SREQ_PREFIX is not null and trim(T.DOC_PREF) = SREQ_PREFIX)) - and (SREQ_NUMBER is null or (SREQ_NUMBER is not null and trim(T.DOC_NUMB) = SREQ_NUMBER)) - and (DREQ_DATE is null or (DREQ_DATE is not null and T.DOC_DATE = DREQ_DATE))) - loop - /* Собираем информацию по ведомости в ответ */ - XITEM := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ITEM, SNS => SNS_TSD); - XCODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_CODE, SNS => SNS_TSD, SVAL => REC.RN); - XNAME := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_NAME, - SNS => SNS_TSD, - SVAL => REC.DOC_TYPE_CODE || ', ' || REC.DOC_PREF || '-' || REC.DOC_NUMB || ', ' || - TO_CHAR(REC.DOC_DATE, 'dd.mm.yyyy')); - XTYPECODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_TYPECODE, SNS => SNS_TSD, SVAL => REC.DOC_TYPE); - XPREFIX := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_PREFIX, SNS => SNS_TSD, SVAL => REC.DOC_PREF); - XNUMBER := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_NUMBER, SNS => SNS_TSD, SVAL => REC.DOC_NUMB); - XDATE := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_DATE, - SNS => SNS_TSD, - SVAL => TO_CHAR(REC.DOC_DATE, 'yyyy-mm-dd')); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XNAME); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XTYPECODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XPREFIX); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XNUMBER); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XDATE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XGETSHEETSRESPONSE, NEWCHILD => XITEM); - end loop; - /* Оборачиваем ответ в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XGETSHEETSRESPONSE); - exception - /* Перехватываем возможные ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end GETSHEETS; - - /* Электронная инвентаризация - считывание состава ведомостей инвентаризации */ - procedure GETSHEETITEMS - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XGETSHEETITEMSRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XITEM DBMS_XMLDOM.DOMNODE; -- Элемент ответного списка - XSTORAGEMNEMOCODE DBMS_XMLDOM.DOMNODE; -- Мнемокод местонахождения для элемента ответного списка - XUSERCODE DBMS_XMLDOM.DOMNODE; -- МОЛ для элемента ответного списка - XITEMCODE DBMS_XMLDOM.DOMNODE; -- Идентификатор ОС для элемента ответного списка - XITEMNAME DBMS_XMLDOM.DOMNODE; -- Наименование ОС для элемента ответного списка - XITEMMNEMOCODE DBMS_XMLDOM.DOMNODE; -- Код ОС для элемента ответного списка - XITEMNUMBER DBMS_XMLDOM.DOMNODE; -- Номер ОС для элемента ответного списка - XQUANTITY DBMS_XMLDOM.DOMNODE; -- Количество ОС для элемента ответного списка - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - NREQ_SHEET_CODE PKG_STD.TREF; -- Ведомость из запроса (параметр отбора) - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Считываем "Регистрационный номер ведомости" (параметр отбора) */ - NREQ_SHEET_CODE := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_SHEETCODE)); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Создаём пространство имён для ответа */ - XGETSHEETITEMSRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_GETSHEETITEMSRSPNS, SNS => SNS_TSD); - /* Обходим типы документов связанные с разделом "Электронные инвентаризации" */ - for REC in (select T.RN NRN, - T.COMPANY NCOMPANY, - T.BARCODE SBARCODE, - T.IS_LOADED NIS_LOADED, - UTL_ELINVOBJECT_DICPLACE_GET(T.RN, SRESULT_TYPE_MNEMO) SSTORAGEMNEMOCODE, - UTL_ELINVOBJECT_DICPLACE_GET(T.RN, SRESULT_TYPE_BARCODE) SOBARCODE, - T.INVPERSONS NINVPERSONS, - UTL_ELINVOBJECT_BARCODE_GET(T.RN) SIBARCODE, - N1.NOMEN_CODE SNOM_CODE, - N1.NOMEN_NAME SNOM_NAME, - I.INV_NUMBER SINV_NUMBER, - '1' SQUANTITY - from ELINVOBJECT T, - INVENTORY I, - DICPLACE O, - DICPLACE OP, - INVPACK P, - INVPACKPOS PS, - INVSUBST U, - DICNOMNS N1 - where T.COMPANY = 136018 - and T.PRN = NREQ_SHEET_CODE - and T.INVENTORY = I.RN - and I.OBJECT_PLACE = O.RN(+) - and T.INVPACK = P.RN(+) - and P.OBJECT_PLACE = OP.RN(+) - and T.INVPACK = PS.PRN(+) - and T.INVSUBST = PS.INVSUBST(+) - and T.INVSUBST = U.RN(+) - and I.NOMENCLATURE = N1.RN) - loop - /* Собираем информацию по элементам ведомости в ответ */ - XITEM := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ITEM, SNS => SNS_TSD); - XSTORAGEMNEMOCODE := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_STORAGEMNEMOCODE, - SNS => SNS_TSD, - SVAL => REC.SSTORAGEMNEMOCODE); - XUSERCODE := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_USERCODE, - SNS => SNS_TSD, - SVAL => trim(REC.NINVPERSONS)); - XITEMCODE := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_ITEMCODE, - SNS => SNS_TSD, - SVAL => trim(REC.SIBARCODE)); - XITEMNAME := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_ITEMNAME, - SNS => SNS_TSD, - SVAL => trim(REC.SNOM_NAME)); - XITEMMNEMOCODE := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_ITEMMNEMOCODE, - SNS => SNS_TSD, - SVAL => trim(REC.SNOM_CODE)); - XITEMNUMBER := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_ITEMNUMBER, - SNS => SNS_TSD, - SVAL => trim(REC.SINV_NUMBER)); - XQUANTITY := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_QUANTITY, SNS => SNS_TSD, SVAL => REC.SQUANTITY); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XSTORAGEMNEMOCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XUSERCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XITEMCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XITEMNAME); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XITEMMNEMOCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XITEMNUMBER); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XQUANTITY); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XGETSHEETITEMSRESPONSE, NEWCHILD => XITEM); - /* Выставим дату выгрузки в терминал для позиции ведомости инвентаризации */ - P_ELINVOBJECT_BASE_UPDATE(NCOMPANY => REC.NCOMPANY, - NRN => REC.NRN, - DUNLOAD_DATE => sysdate, - DINV_DATE => null, - NINVPERSONS => REC.NINVPERSONS, - SBARCODE => REC.SBARCODE, - NIS_LOADED => REC.NIS_LOADED); - end loop; - /* Оборачиваем ответ в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XGETSHEETITEMSRESPONSE); - exception - /* Перехватываем возможные ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end GETSHEETITEMS; - - /* Электронная инвентаризация - считывание местонахождений */ - procedure GETSTORAGES - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XGETSTORAGESRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XITEM DBMS_XMLDOM.DOMNODE; -- Элемент ответного списка - XCODE DBMS_XMLDOM.DOMNODE; -- Код элемента ответного списка - XNAME DBMS_XMLDOM.DOMNODE; -- Нименование элемента ответного списка - XMNEMOCODE DBMS_XMLDOM.DOMNODE; -- Мнемокод местонахождения для элемента ответного списка - XLATITUDE DBMS_XMLDOM.DOMNODE; -- Широта местонахождения для элемента ответного списка - XLONGITUDE DBMS_XMLDOM.DOMNODE; -- Долгота местонахождения для элемента ответного списка - XPOSTCODE DBMS_XMLDOM.DOMNODE; -- Почтовый индекс местонахождения для элемента ответного списка - XCOUNTRY DBMS_XMLDOM.DOMNODE; -- Страна местонахождения для элемента ответного списка - XREGION DBMS_XMLDOM.DOMNODE; -- Регион местонахождения для элемента ответного списка - XLOCALITY DBMS_XMLDOM.DOMNODE; -- Населённый пункт местонахождения для элемента ответного списка - XSTREET DBMS_XMLDOM.DOMNODE; -- Улица местонахождения для элемента ответного списка - XHOUSENUMBER DBMS_XMLDOM.DOMNODE; -- Номер дома местонахождения для элемента ответного списка - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - NREQ_SHEET_CODE PKG_STD.TREF; -- Ведомость из запроса (параметр отбора) - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Считываем "Регистрационный номер ведомости" (параметр отбора) */ - NREQ_SHEET_CODE := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_SHEETCODE)); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Создаём пространство имён для ответа */ - XGETSTORAGESRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_GETSTORAGESRSPNS, SNS => SNS_TSD); - /* Обходим местонахождения */ - for REC in (select T.RN NRN, - T.PLACE_MNEMO SMNEMOCODE, - T.PLACE_NAME SNAME, - UDO_F_GET_DOC_PROP_VAL_STR('LATITUDE', 'ObjPlace', T.RN) SLATITUDE, - UDO_F_GET_DOC_PROP_VAL_STR('LONGITUDE', 'ObjPlace', T.RN) SLONGITUDE, - NVL(T.ADDR_POST, G.POSTAL_CODE) SPOSTCODE, - UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 1) SCOUNTRY, - UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 2) SREGION, - NVL(UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 8), - NVL(UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 4), - NVL(UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 3), UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 2)))) SLOCALITY, - UTL_GEOGRAFY_GET_HIER_ITEM(G.RN, 5) SSTREET, - T.ADDR_HOUSE SHOUSENUMBER, - T.BARCODE SBARCODE - from DICPLACE T, - GEOGRAFY G - where T.COMPANY = 136018 - and T.GEOGRAFY = G.RN(+) - and ((NREQ_SHEET_CODE is null) or - ((NREQ_SHEET_CODE is not null) and - (T.RN in (select DECODE(EO.INVPACK, null, INV.OBJECT_PLACE, P.OBJECT_PLACE) - from ELINVOBJECT EO, - INVENTORY INV, - INVPACK P - where EO.PRN = NREQ_SHEET_CODE - and EO.INVENTORY = INV.RN - and EO.INVPACK = P.RN(+)))))) - loop - /* Собираем информацию по местонахождению в ответ */ - XITEM := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_ITEM, SNS => SNS_TSD); - XCODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_CODE, SNS => SNS_TSD, SVAL => REC.SBARCODE); - XNAME := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_NAME, SNS => SNS_TSD, SVAL => REC.SNAME); - XMNEMOCODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_MNEMOCODE, SNS => SNS_TSD, SVAL => REC.SMNEMOCODE); - XLATITUDE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_LATITUDE, SNS => SNS_TSD, SVAL => REC.SLATITUDE); - XLONGITUDE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_LONGITUDE, SNS => SNS_TSD, SVAL => REC.SLONGITUDE); - XPOSTCODE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_POSTCODE, SNS => SNS_TSD, SVAL => REC.SPOSTCODE); - XCOUNTRY := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_COUNTRY, SNS => SNS_TSD, SVAL => REC.SCOUNTRY); - XREGION := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_REGION, SNS => SNS_TSD, SVAL => REC.SREGION); - XLOCALITY := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_LOCALITY, SNS => SNS_TSD, SVAL => REC.SLOCALITY); - XSTREET := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_STREET, SNS => SNS_TSD, SVAL => REC.SSTREET); - XHOUSENUMBER := UTL_CREATENODE(XDOC => XDOC, - STAG => STAG_HOUSENUMBER, - SNS => SNS_TSD, - SVAL => REC.SHOUSENUMBER); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XNAME); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XMNEMOCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XLATITUDE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XLONGITUDE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XPOSTCODE); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XCOUNTRY); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XREGION); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XLOCALITY); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XSTREET); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM, NEWCHILD => XHOUSENUMBER); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XGETSTORAGESRESPONSE, NEWCHILD => XITEM); - end loop; - /* Оборачиваем ответ в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XGETSTORAGESRESPONSE); - exception - /* Перехватываем возможные ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end GETSTORAGES; - - /* Электронная инвентаризация - сохранение результатов инвентаризации элемента хранения */ - procedure SAVESHEETITEM - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - XSAVESHEETITEMRESPONSE DBMS_XMLDOM.DOMNODE; -- Корневой элемент ответа - XNODE DBMS_XMLDOM.DOMNODE; -- Буфер для ветки ответа - XITEM DBMS_XMLDOM.DOMNODE; -- Элемент ответного списка - XDOC DBMS_XMLDOM.DOMDOCUMENT; -- Документ - XNODE_ROOT DBMS_XMLDOM.DOMNODE; -- Корневой элемент первой ветки тела документа - CRESPONSE clob; -- Буфер для ответа - SREQ_DEVICEID PKG_STD.TSTRING; -- Идентификатор устройства из запроса - NREQ_SHEET_CODE PKG_STD.TREF; -- Ведомость из запроса (параметр сохранения) - NREQ_USER_CODE PKG_STD.TREF; -- Регистрационный номер МОЛ из запроса (параметр сохранения) - SREQ_STORAGE_MNEMOCODE PKG_STD.TSTRING; -- Мнемокод местонахождения из запроса (параметр сохранения) - NREQ_STORAGE_ISNEW PKG_STD.TNUMBER; -- Признак нового местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_CODE PKG_STD.TSTRING; -- Штрих-код местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_NAME PKG_STD.TSTRING; -- Наименование местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_POSTCODE PKG_STD.TSTRING; -- Почтовый индекс местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_COUNTRY PKG_STD.TSTRING; -- Страна местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_REGION PKG_STD.TSTRING; -- Регион местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_LOCALITY PKG_STD.TSTRING; -- Населенный пункт местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_STREET PKG_STD.TSTRING; -- Улица местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_HOUSE PKG_STD.TSTRING; -- Номер дома местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_LATITUDE PKG_STD.TSTRING; -- Широта местонахождения из запроса (параметр сохранения) - SREQ_STORAGE_LONGITUDE PKG_STD.TSTRING; -- Долгота местонахождения из запроса (параметр сохранения) - SREQ_ITEM_CODE PKG_STD.TSTRING; -- Штрих-код ОС из запроса (параметр сохранения) - SREQ_ITEM_NAME PKG_STD.TSTRING; -- Наименование номенклатуры ОС из запроса (параметр сохранения) - SREQ_ITEM_MNEMOCODE PKG_STD.TSTRING; -- Мнемокод номенклатуры ОС из запроса (параметр сохранения) - SREQ_ITEM_NUMBER PKG_STD.TSTRING; -- Инвентарный номер ОС из запроса (параметр сохранения) - NREQ_ITEM_QUANTITY PKG_STD.TQUANT; -- Количество ОС из запроса (параметр сохранения) - DREQ_ITEM_CHECKDATE PKG_STD.TLDATE; -- Дата проведения инвентаризации ОС из запроса (параметр сохранения) - SREQ_ITEM_COMMENT PKG_STD.TLSTRING; -- Комментарий МОЛ ОС из запроса (параметр сохранения) - SREQ_ITEM_LATITUDE PKG_STD.TSTRING; -- Широта ОС из запроса (параметр сохранения) - SREQ_ITEM_LONGITUDE PKG_STD.TSTRING; -- Долгота ОС из запроса (параметр сохранения) - NREQ_ITEM_DISTANCE PKG_STD.TLNUMBER; -- Расстояние до местонахождения ОС из запроса (параметр сохранения) - RELINVENTORY ELINVENTORY%rowtype; -- Запись модифицируемой ведомости инвентаризации - NELINVOBJECT PKG_STD.TREF; -- Рег. номер позиции ведомости инвентаризации - SDICPLACE_BARCODE PKG_STD.TSTRING; -- Штрих-код местонахождения ОС (для позиции ведомости инвентаризации) - SERR_ELINVOBJECT PKG_STD.TSTRING; -- Буфер для ошибки обработки инвентарной карточки - SERR_DICPLACE PKG_STD.TSTRING; -- Буфер для ошибки обработки местонахождения - - /* Поиск географического понятия по параметрам */ - function FIND_GEOGRAFY - ( - NCOMPANY in number, -- Рег. номер организации - SADDR_COUNTRY in varchar2, -- Страна местонахождения - SADDR_REGION in varchar2, -- Регион местонахождения - SADDR_LOCALITY in varchar2, -- Населённый пункт местонахождения - SADDR_STREET in varchar2 -- Улица местонахождения - ) return number -- Географическое понятие - is - begin - return UTL_GEOGRAFY_FIND_BY_HIER_ITEM(NCOMPANY => NCOMPANY, - SADDR_COUNTRY => SADDR_COUNTRY, - SADDR_REGION => SADDR_REGION, - SADDR_LOCALITY => SADDR_LOCALITY, - SADDR_STREET => SADDR_STREET); - end FIND_GEOGRAFY; - - /* Обработка местонахождения - поиск и при необходимости добавление местонахождения ОС */ - procedure PROCESS_DICPLACE - ( - NCOMPANY in number, -- Рег. номер организации - NIS_NEW in number, -- Признак нового метонахождения (0 - старое, 1 - новое) - SMNEMO in varchar2, -- Мнемокод местонахождения - SNAME in varchar2, -- Наименование местонахождения - SBARCODE in varchar2, -- Штарих-код местонахождения - SADDR_POSTCODE in varchar2, -- Почтовый индекс местонахождения - SADDR_COUNTRY in varchar2, -- Страна местонахождения - SADDR_REGION in varchar2, -- Регион местонахождения - SADDR_LOCALITY in varchar2, -- Населённый пункт местонахождения - SADDR_STREET in varchar2, -- Улица местонахождения - SADDR_HOUSE in varchar2, -- Дом местонахождения - SLATITUDE in varchar2, -- Широта местонахождения - SLONGITUDE in varchar2, -- Долгота местонахождения - SDICPLACE_BARCODE out varchar2 -- Штрихкод обработанного мемстонахождения - ) - is - NPROP_LATITUDE PKG_STD.TREF; -- Рег. номер ДС для хранения широты местонахождения - NPROP_LONGITUDE PKG_STD.TREF; -- Рег. номер ДС для хранения долготы местонахождения - NDICPLACE PKG_STD.TREF; -- Рег. номер местонахождения - NDICPLACE_CRN PKG_STD.TREF; -- Рег. номер каталога местонахождения - NTMP PKG_STD.TREF; -- Буфер для рег. номеров - begin - /* Инициализируем ДС для хранения широты */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, SCODE => 'LATITUDE', NRN => NPROP_LATITUDE); - /* Инициализируем ДС для хранения долготы */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, SCODE => 'LONGITUDE', NRN => NPROP_LONGITUDE); - /* Проверяем наличие местонахождения по переданному штрихкоду */ - begin - select T.RN - into NDICPLACE - from DICPLACE T - where T.COMPANY = NCOMPANY - and T.BARCODE = SBARCODE; - exception - when NO_DATA_FOUND then - /* Пробуем найти по мнемокоду */ - begin - select T.RN - into NDICPLACE - from DICPLACE T - where T.COMPANY = NCOMPANY - and T.PLACE_MNEMO = SMNEMO; - exception - when NO_DATA_FOUND then - /* Нашли, но если это новое - добавляем */ - if (NIS_NEW = 1) then - /* Определим каталог размещения */ - FIND_ROOT_CATALOG(NCOMPANY => NCOMPANY, SCODE => 'ObjPlace', NCRN => NDICPLACE_CRN); - /* Добавим запись */ - P_DICPLACE_BASE_INSERT(NCOMPANY => NCOMPANY, - NCRN => NDICPLACE_CRN, - SMNEMO => SMNEMO, - SNAME => SNAME, - SBARCODE => NVL(SBARCODE, GEN_BARCODE_EX()), - DLABEL_DATE => sysdate, - SCAD_NUMB => null, - NGEOGRAFY => null, - SADDR_HOUSE => SADDR_HOUSE, - SADDR_BLOCK => null, - SADDR_BUILDING => null, - SADDR_FLAT => null, - SADDR_POST => SADDR_POSTCODE, - SPLACE_DESCRIPT => SADDR_COUNTRY || '/' || SADDR_REGION || '/' || SADDR_LOCALITY || '/' || - SADDR_STREET, - SAOID => null, - SAOGUID => null, - SHOUSEID => null, - SHOUSEGUID => null, - NRN => NDICPLACE); - else - P_EXCEPTION(0, - 'Местонахождение инвентарных объектов с штрих-кодом "%s" или мнемокодом "%s" не найдено.', - NVL(SBARCODE, '<НЕ УКАЗАН>'), - NVL(SMNEMO, '<НЕ УКАЗАНО>')); - end if; - end; - when TOO_MANY_ROWS then - P_EXCEPTION(0, - 'Местонахождение инвентарных объектов с штрих-кодом "%s" определено неоднозначно.', - SBARCODE); - end; - /* Проверим что нашли местонахождение */ - if (NDICPLACE is null) then - P_EXCEPTION(0, - 'Не удалось определить фактическое местонахождение по штрихкоду "%s" и мнемокоду "%s".', - NVL(SBARCODE, '<НЕ УКАЗАН>'), - NVL(SMNEMO, '<НЕ УКАЗАН>')); - end if; - /* Актуализируем его */ - for C in (select T.* from DICPLACE T where T.RN = NDICPLACE) - loop - /* Подберем дату штрих-кода */ - if (NVL(SBARCODE, C.BARCODE) is not null) then - if (SBARCODE = C.BARCODE) then - C.LABEL_DATE := NVL(C.LABEL_DATE, sysdate); - else - C.LABEL_DATE := sysdate; - end if; - else - C.LABEL_DATE := null; - end if; - /* Актуализируем запись */ - P_DICPLACE_BASE_UPDATE(NCOMPANY => C.COMPANY, - NRN => C.RN, - SMNEMO => NVL(SMNEMO, C.PLACE_MNEMO), - SNAME => NVL(SNAME, C.PLACE_NAME), - SBARCODE => NVL(SBARCODE, C.BARCODE), - DLABEL_DATE => C.LABEL_DATE, - SCAD_NUMB => C.CAD_NUMB, - NGEOGRAFY => NVL(FIND_GEOGRAFY(NCOMPANY => C.COMPANY, - SADDR_COUNTRY => SADDR_COUNTRY, - SADDR_REGION => SADDR_REGION, - SADDR_LOCALITY => SADDR_LOCALITY, - SADDR_STREET => SADDR_STREET), - C.GEOGRAFY), - SADDR_HOUSE => SADDR_HOUSE, - SADDR_BLOCK => C.ADDR_BLOCK, - SADDR_BUILDING => C.ADDR_BUILDING, - SADDR_FLAT => C.ADDR_FLAT, - SADDR_POST => SADDR_POSTCODE, - SPLACE_DESCRIPT => C.PLACE_DESCRIPT, - SAOID => null, - SAOGUID => null, - SHOUSEID => null, - SHOUSEGUID => null); - /* Выставим ДС с широтой */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ObjPlace', - NPROPERTY => NPROP_LATITUDE, - SSTR_VALUE => SLATITUDE, - NNUM_VALUE => null, - DDATE_VALUE => null, - NRN => NTMP); - /* Выставим ДС с долготой */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ObjPlace', - NPROPERTY => NPROP_LONGITUDE, - SSTR_VALUE => SLONGITUDE, - NNUM_VALUE => null, - DDATE_VALUE => null, - NRN => NTMP); - end loop; - /* Аккуратно считываем штрих-код местонахождения */ - begin - select T.BARCODE into SDICPLACE_BARCODE from DICPLACE T where T.RN = NDICPLACE; - exception - when NO_DATA_FOUND then - PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NDICPLACE, SUNIT_TABLE => 'DICPLACE'); - end; - end PROCESS_DICPLACE; - - /* Обрабатываем ОС - поиск и при необходимости добавление позиции ведомости инвентаризации с импортируемым ОС */ - procedure PROCESS_INVENTORY - ( - RELINVENTORY in ELINVENTORY%rowtype, -- Запись обрабатываемой ведомости - SBARCODE in varchar2, -- Штрих-код ОС - SINV_NUMBER in varchar2, -- Инвентарный номер ОС - NELINVOBJECT out number -- Рег. номер позиции ведомости инвентаризации - ) - is - NINVENTORY PKG_STD.TREF; -- Рег. номер ОС (карточки "Инвентарной картотеки") - begin - /* Ищем позицию ведомости по штрих-коду ОС */ - begin - select T.RN - into NELINVOBJECT - from ELINVOBJECT T - where T.COMPANY = RELINVENTORY.COMPANY - and T.PRN = RELINVENTORY.RN - and UTL_ELINVOBJECT_BARCODE_GET(T.RN) = SBARCODE; - exception - when NO_DATA_FOUND then - /* Не нашли позицию ведомости инвентаризации */ - begin - /* Ищем рег. номер ИК по штрих-коду */ - select T.RN - into NINVENTORY - from INVENTORY T - where T.BARCODE = SBARCODE - and T.COMPANY = RELINVENTORY.COMPANY; - /* Добавляем её в ведомость инвентаризации */ - P_ELINVOBJECT_BASE_INSERT(NCOMPANY => RELINVENTORY.COMPANY, - NPRN => RELINVENTORY.RN, - NINVENTORY => NINVENTORY, - NINVSUBST => null, - NINVPACK => null, - DUNLOAD_DATE => null, - DINV_DATE => null, - NINVPERSONS => null, - SBARCODE => null, - NIS_LOADED => 1, - NRN => NELINVOBJECT); - exception - when NO_DATA_FOUND then - begin - /* Ищем рег. номер ИК по инвентарному номеру */ - select T.RN - into NINVENTORY - from INVENTORY T - where trim(T.INV_NUMBER) = trim(SINV_NUMBER) - and T.COMPANY = RELINVENTORY.COMPANY; - /* Добавляем её в ведомость инвентаризации */ - P_ELINVOBJECT_BASE_INSERT(NCOMPANY => RELINVENTORY.COMPANY, - NPRN => RELINVENTORY.RN, - NINVENTORY => NINVENTORY, - NINVSUBST => null, - NINVPACK => null, - DUNLOAD_DATE => null, - DINV_DATE => null, - NINVPERSONS => null, - SBARCODE => null, - NIS_LOADED => 1, - NRN => NELINVOBJECT); - exception - when NO_DATA_FOUND then - P_EXCEPTION(0, - 'Инвентарная карточка с штрих-кодом "%s" не найдена.', - SBARCODE); - end; - end; - end; - end PROCESS_INVENTORY; - - /* Обрабатываем элемент ведомости */ - procedure PROCESS_ELINVOBJECT - ( - RELINVENTORY in ELINVENTORY%rowtype, -- Запись обрабатываемой ведомости - NELINVOBJECT in number, -- Рег. номер элемента ведомости инвентаризации - NINVPERSONS in number, -- Рег. номер инвентаризирующего лица - DINV_DATE in date, -- Дата проведения инвентаризации - SBARCODE in varchar2, -- Штрих-код местонахождения - SITEM_COMMENT in varchar2, -- Комментарий инвентаризирующего лица - NITEM_DISTANCE in number, -- Расстояние ОС до местонахождения - SITEM_LATITUDE in varchar2, -- Широта ОС - SITEM_LONGITUDE in varchar2, -- Долгота ОС - NITEM_QUANTITY in number -- Количество ОС - ) - is - NPROP_COMMENT PKG_STD.TREF; -- Рег. номер ДС для хранения комментария - NPROP_DISTANCE PKG_STD.TREF; -- Рег. номер ДС для хранения расстояния до местонахождения (метров) - NPROP_LATITUDE PKG_STD.TREF; -- Рег. номер ДС для хранения широты - NPROP_LONGITUDE PKG_STD.TREF; -- Рег. номер ДС для хранения долготы - NPROP_QUANTITY PKG_STD.TREF; -- Рег. номер ДС для хранения количества - NTMP PKG_STD.TREF; -- Буфер для рег. номеров - begin - /* Инициализируем ДС для хранения примечания */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, - NCOMPANY => RELINVENTORY.COMPANY, - SCODE => 'COMMENT', - NRN => NPROP_COMMENT); - /* Инициализируем ДС для хранения расстояния до местонахождения */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, - NCOMPANY => RELINVENTORY.COMPANY, - SCODE => 'DISTANCE', - NRN => NPROP_DISTANCE); - /* Инициализируем ДС для хранения широты */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, - NCOMPANY => RELINVENTORY.COMPANY, - SCODE => 'LATITUDE', - NRN => NPROP_LATITUDE); - /* Инициализируем ДС для хранения долготы */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, - NCOMPANY => RELINVENTORY.COMPANY, - SCODE => 'LONGITUDE', - NRN => NPROP_LONGITUDE); - /* Инициализируем ДС для хранения количества */ - FIND_DOCS_PROPS_CODE(NFLAG_SMART => 0, - NCOMPANY => RELINVENTORY.COMPANY, - SCODE => 'QUANTITY', - NRN => NPROP_QUANTITY); - /* Обратимся к обрабатываемой позиции ведомости инвентаризации */ - for C in (select T.* from ELINVOBJECT T where T.RN = NELINVOBJECT) - loop - /* Обновим позицию ведомости инвентаризации */ - P_ELINVOBJECT_BASE_UPDATE(NCOMPANY => C.COMPANY, - NRN => C.RN, - DUNLOAD_DATE => C.UNLOAD_DATE, - DINV_DATE => DINV_DATE, - NINVPERSONS => NINVPERSONS, - SBARCODE => SBARCODE, - NIS_LOADED => C.IS_LOADED); - /* Выставим ДС с примечанием */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ElectronicInventoriesObjects', - NPROPERTY => NPROP_COMMENT, - SSTR_VALUE => SITEM_COMMENT, - NNUM_VALUE => null, - DDATE_VALUE => null, - NRN => NTMP); - /* Выставим ДС с дистанцией */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ElectronicInventoriesObjects', - NPROPERTY => NPROP_DISTANCE, - SSTR_VALUE => null, - NNUM_VALUE => NITEM_DISTANCE, - DDATE_VALUE => null, - NRN => NTMP); - /* Выставим ДС с широтой */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ElectronicInventoriesObjects', - NPROPERTY => NPROP_LATITUDE, - SSTR_VALUE => SITEM_LATITUDE, - NNUM_VALUE => null, - DDATE_VALUE => null, - NRN => NTMP); - /* Выставим ДС с долготой */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ElectronicInventoriesObjects', - NPROPERTY => NPROP_LONGITUDE, - SSTR_VALUE => SITEM_LONGITUDE, - NNUM_VALUE => null, - DDATE_VALUE => null, - NRN => NTMP); - /* Выставим ДС с количеством */ - P_DOCS_PROPS_VALS_BASE_MODIFY(NDOCUMENT => C.RN, - SUNITCODE => 'ElectronicInventoriesObjects', - NPROPERTY => NPROP_QUANTITY, - SSTR_VALUE => null, - NNUM_VALUE => NITEM_QUANTITY, - DDATE_VALUE => null, - NRN => NTMP); - end loop; - end PROCESS_ELINVOBJECT; - - begin - begin - /* Считываем корневой элемент тела посылки */ - UTL_EXSQUEUE_MSG_GET_BODY_ROOT(NEXSQUEUE => NEXSQUEUE, XNODE_ROOT => XNODE_ROOT); - /* Считываем идентификатор устройства */ - SREQ_DEVICEID := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DEVICEID); - /* Считываем "Регистрационный номер ведомости" (параметр сохранения) */ - NREQ_SHEET_CODE := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_SHEETCODE)); - /* Считываем "Регистрационный номер МОЛ" (параметр сохранения) */ - NREQ_USER_CODE := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_USERCODE)); - /* Считываем "Мнемокод местонахождения" (параметр сохранения) */ - SREQ_STORAGE_MNEMOCODE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGEMNEMOCODE); - /* Считываем "Признак нового местонахождения" (параметр сохранения) */ - NREQ_STORAGE_ISNEW := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGEISNEW)); - /* Считываем "Штрих-код местонахождения" (параметр сохранения) */ - SREQ_STORAGE_CODE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGECODE); - /* Считываем "Наименование местонахождения" (параметр сохранения) */ - SREQ_STORAGE_NAME := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGENAME); - /* Считываем "Почтовый индекс местонахождения" (параметр сохранения) */ - SREQ_STORAGE_POSTCODE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGEPOSTCODE); - /* Считываем "Страна местонахождения" (параметр сохранения) */ - SREQ_STORAGE_COUNTRY := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGECOUNTRY); - /* Считываем "Регион местонахождения" (параметр сохранения) */ - SREQ_STORAGE_REGION := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGEREGION); - /* Считываем "Населенный пункт местонахождения" (параметр сохранения) */ - SREQ_STORAGE_LOCALITY := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGELOCALITY); - /* Считываем "Улица местонахождения" (параметр сохранения) */ - SREQ_STORAGE_STREET := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGESTREET); - /* Считываем "Номер дома местонахождения" (параметр сохранения) */ - SREQ_STORAGE_HOUSE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGEHOUSENUMBER); - /* Считываем "Широта местонахождения" (параметр сохранения) */ - SREQ_STORAGE_LATITUDE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGELATITUDE); - /* Считываем "Долгота местонахождения" (параметр сохранения) */ - SREQ_STORAGE_LONGITUDE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_STORAGELONGITUDE); - /* Считываем "Штрих-код ОС" (параметр сохранения) */ - SREQ_ITEM_CODE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_ITEMCODE); - /* Считываем "Наименование номенклатуры ОС" (параметр сохранения) */ - SREQ_ITEM_NAME := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_ITEMNAME); - /* Считываем "Мнемокод номенклатуры ОС" (параметр сохранения) */ - SREQ_ITEM_MNEMOCODE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_ITEMMNEMOCODE); - /* Считываем "Инвентарный номер ОС" (параметр сохранения) */ - SREQ_ITEM_NUMBER := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_ITEMNUMBER); - /* Считываем "Количество ОС" (параметр сохранения) */ - NREQ_ITEM_QUANTITY := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_QUANTITY)); - /* Считываем "Дата проведения инвентаризации ОС" (параметр сохранения) */ - DREQ_ITEM_CHECKDATE := TO_DATE(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_CHECKDATE), - 'YYYY-MM-DD"T"HH24:MI:SS'); - /* Считываем "Комментарий МОЛ ОС" (параметр сохранения) */ - SREQ_ITEM_COMMENT := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_COMMENT); - /* Считываем "Широта ОС" (параметр сохранения) */ - SREQ_ITEM_LATITUDE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_LATITUDE); - /* Считываем "Долгота ОС" (параметр сохранения) */ - SREQ_ITEM_LONGITUDE := UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_LONGITUDE); - /* Считываем "Расстояние до местонахождения ОС" (параметр сохранения) */ - NREQ_ITEM_DISTANCE := TO_NUMBER(UTL_GETNODEVAL(XROOTNODE => XNODE_ROOT, SPATTERN => STAG_DISTANCETOSTORAGE)); - /* Контроль индетификатора устройства по лицензии */ - UTL_CHECK_DEVICEID(SDEVICEID => SREQ_DEVICEID); - /* Подготавливаем документ для ответа */ - UTL_CREATERESPONSEDOC(XDOC => XDOC); - /* Работаем только если указан регистрационный номер ведомости */ - if (NREQ_SHEET_CODE is not null) then - /* Считаем запись ведомости инвентаризации */ - begin - select T.* into RELINVENTORY from ELINVENTORY T where T.RN = NREQ_SHEET_CODE; - exception - when NO_DATA_FOUND then - PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NREQ_SHEET_CODE, SUNIT_TABLE => 'ELINVENTORY'); - end; - /* Обрабатываем местонахождение */ - begin - PROCESS_DICPLACE(NCOMPANY => RELINVENTORY.COMPANY, - NIS_NEW => NREQ_STORAGE_ISNEW, - SMNEMO => SREQ_STORAGE_MNEMOCODE, - SNAME => SREQ_STORAGE_NAME, - SBARCODE => SREQ_STORAGE_CODE, - SADDR_POSTCODE => SREQ_STORAGE_POSTCODE, - SADDR_COUNTRY => SREQ_STORAGE_COUNTRY, - SADDR_REGION => SREQ_STORAGE_REGION, - SADDR_LOCALITY => SREQ_STORAGE_LOCALITY, - SADDR_STREET => SREQ_STORAGE_STREET, - SADDR_HOUSE => SREQ_STORAGE_HOUSE, - SLATITUDE => SREQ_STORAGE_LATITUDE, - SLONGITUDE => SREQ_STORAGE_LONGITUDE, - SDICPLACE_BARCODE => SDICPLACE_BARCODE); - exception - when others then - SERR_DICPLACE := sqlerrm; - end; - /* Если метонахождение обработано успешно */ - if (SERR_DICPLACE is null) then - begin - /* Обрабатываем ОС */ - PROCESS_INVENTORY(RELINVENTORY => RELINVENTORY, - SBARCODE => SREQ_ITEM_CODE, - SINV_NUMBER => SREQ_ITEM_NUMBER, - NELINVOBJECT => NELINVOBJECT); - /* Обрабатываем элемент ведомости */ - PROCESS_ELINVOBJECT(RELINVENTORY => RELINVENTORY, - NELINVOBJECT => NELINVOBJECT, - NINVPERSONS => NREQ_USER_CODE, - DINV_DATE => DREQ_ITEM_CHECKDATE, - SBARCODE => SDICPLACE_BARCODE, - SITEM_COMMENT => SREQ_ITEM_COMMENT, - NITEM_DISTANCE => NREQ_ITEM_DISTANCE, - SITEM_LATITUDE => SREQ_ITEM_LATITUDE, - SITEM_LONGITUDE => SREQ_ITEM_LONGITUDE, - NITEM_QUANTITY => NREQ_ITEM_QUANTITY); - exception - when others then - SERR_ELINVOBJECT := sqlerrm; - end; - else - SERR_ELINVOBJECT := 'Возникли ошибки при обработке места хранения'; - end if; - else - P_EXCEPTION(0, 'В запросе не указан идентификатор ведомости.'); - end if; - /* Если ошибок нет - возвращаем положительный ответ */ - if ((SERR_ELINVOBJECT is null) and (SERR_DICPLACE is null)) then - /* Создаём пространство имён для ответа */ - XSAVESHEETITEMRESPONSE := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_SAVESHEETITEMRSPNS, SNS => SNS_TSD); - /* Формируем результат */ - XITEM := UTL_CREATENODE(XDOC => XDOC, STAG => STAG_RESULT, SNS => SNS_TSD, SVAL => 'true'); - XNODE := DBMS_XMLDOM.APPENDCHILD(N => XSAVESHEETITEMRESPONSE, NEWCHILD => XITEM); - /* Оборачиваем ответ в конверт */ - CRESPONSE := UTL_CREATERESPONSE(XDOC => XDOC, XCONTENT => XSAVESHEETITEMRESPONSE); - else - /* Были ошибки - вернём их */ - CRESPONSE := UTL_CREATEERRORRESPONSE_SSITEM(SMSG_ELINVOBJECT => UTL_CORRECT_ERR(SERR => SERR_ELINVOBJECT), - SMSG_DICPLACE => UTL_CORRECT_ERR(SERR => SERR_DICPLACE)); - end if; - exception - /* Перехватываем возможные необработанные ранее ошибки */ - when others then - CRESPONSE := UTL_CREATEERRORRESPONSE(SMSG => UTL_CORRECT_ERR(SERR => sqlerrm)); - end; - /* Возвращаем ответ */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => CRESPONSE, SCHARSET => 'UTF8')); - exception - when others then - /* Вернём ошибку - это фатальная */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end SAVESHEETITEM; - -end; -/ diff --git a/db/UDO_PKG_EXS_TEST.pck b/db/UDO_PKG_EXS_TEST.pck deleted file mode 100644 index 8c3cba3..0000000 --- a/db/UDO_PKG_EXS_TEST.pck +++ /dev/null @@ -1,183 +0,0 @@ -create or replace package UDO_PKG_EXS_TEST as - - /* Обработка запроса на создание сессии */ - procedure UTL_LOGIN - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - - /* Запросить контрагента */ - procedure AGENT_GET_INFO - ( - NCOMPANY in number, -- Рег. номер организации - NREMOTE_AGENT in number -- Рег. номер контрагента в удалённой БД - ); - - /* Обработка ответа с информацией о контрагенте от тестового стенда */ - procedure AGENT_PROCESS_INFO - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ); - -end; -/ -create or replace package body UDO_PKG_EXS_TEST as - - /* Обработка запроса на создание сессии */ - procedure UTL_LOGIN - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди - CTMP clob; -- Буфер для конвертации - RCTMP sys_refcursor; -- Буфер для измененной позиции очереди - SUSER PKG_STD.TSTRING; -- Имя пользователя - SPASS PKG_STD.TSTRING; -- Пароль пользователя - SCOMPANY PKG_STD.TSTRING; -- Наименование организации - SCONNECT PKG_STD.TSTRING; -- Идентификатор сесии - begin - /* Считаем запись очереди */ - REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE); - /* Забираем данные сообщения и конвертируем в кодировку БД */ - CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.MSG, SCHARSET => 'UTF8'); - /* Кладём конвертированное обратно (просто для удобства мониторинга) */ - PKG_EXS.QUEUE_MSG_SET(NEXSQUEUE => REXSQUEUE.RN, BMSG => CLOB2BLOB(LCDATA => CTMP), RCQUEUE => RCTMP); - /* Извлекаем логин и пароль */ - if (CTMP is not null) then - select EXTRACTVALUE(XMLTYPE(CTMP), '/auth/user') SUSER, - EXTRACTVALUE(XMLTYPE(CTMP), '/auth/pass') SPASS, - EXTRACTVALUE(XMLTYPE(CTMP), '/auth/company') SCOMP - into SUSER, - SPASS, - SCOMPANY - from DUAL; - else - P_EXCEPTION(0, 'Не указаны данные для аутентификации.'); - end if; - /* Если и логин и пароль и организация есть */ - if ((SUSER is not null) and (SPASS is not null) and (SCOMPANY is not null)) then - /* Формируем идентификатор сесии */ - SCONNECT := SYS_GUID(); - /* Создаём сессию */ - PKG_SESSION.LOGON_WEB(SCONNECT => SCONNECT, - SUTILIZER => SUSER, - SPASSWORD => SPASS, - SIMPLEMENTATION => 'Other', - SAPPLICATION => 'Other', - SCOMPANY => SCOMPANY); - /* Выставляем результат обработки */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, - SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK, - BRESP => CLOB2BLOB(LCDATA => SCONNECT, SCHARSET => 'UTF8')); - else - P_EXCEPTION(0, - 'Не указано имя пользователя, пароль или организация.'); - end if; - exception - when others then - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end UTL_LOGIN; - - /* Запросить контрагента на удалённом сервере */ - procedure AGENT_GET_INFO - ( - NCOMPANY in number, -- Рег. номер организации - NREMOTE_AGENT in number -- Рег. номер контрагента в удалённой БД - ) - is - RCTMP sys_refcursor; -- Буфер для измененной позиции очереди - begin - /* Поместим задание в очередь */ - PKG_EXS.QUEUE_PUT(SEXSSERVICE => 'ТестовыйСтенд', - SEXSSERVICEFN => 'ПолучениеКонтрагента', - BMSG => CLOB2BLOB(LCDATA => '{"SACTION":"GET_AGENT","NAGENT":' || TO_CHAR(NREMOTE_AGENT) || - ',"NCOMPANY":' || TO_CHAR(NCOMPANY) || '}'), - RCQUEUE => RCTMP); - end AGENT_GET_INFO; - - /* Обработка ответа с информацией о контрагенте от тестового стенда */ - procedure AGENT_PROCESS_INFO - ( - NIDENT in number, -- Идентификатор процесса - NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена - ) - is - REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди - CMSG clob; -- Буфер для запроса - CRESP clob; -- Буфер для ответа - RCTMP sys_refcursor; -- Буфер для измененной позиции очереди - NCOMPANY PKG_STD.TREF; -- Рег. номер организации - NCRN PKG_STD.TREF; -- Рег. номер каталога - SAGNABBR AGNLIST.AGNABBR%type; -- Мнемокод контрагента - SAGNNAME AGNLIST.AGNNAME%type; -- Наименование контрагента - NAGENT AGNLIST.RN%type; -- Рег. номер добавленного контрагента - begin - /* Считаем запись очереди */ - REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE); - /* Считаем запрос серверу */ - CMSG := BLOB2CLOB(LBDATA => REXSQUEUE.MSG); - /* Считаем ответ сервера и конвертируем в кодировку БД */ - CRESP := BLOB2CLOB(LBDATA => REXSQUEUE.RESP, SCHARSET => 'UTF8'); - /* Кладём конвертированное обратно (просто для удобства мониторинга) */ - PKG_EXS.QUEUE_RESP_SET(NEXSQUEUE => REXSQUEUE.RN, - BRESP => CLOB2BLOB(LCDATA => CRESP), - NIS_ORIGINAL => PKG_EXS.NIS_ORIGINAL_NO, - RCQUEUE => RCTMP); - /* Заберем организацию из исходящего сообщения */ - begin - select EXTRACTVALUE(XMLTYPE(CMSG), '/MSG/NCOMPANY') NCOMPANY into NCOMPANY from DUAL; - exception - when others then - P_EXCEPTION(0, 'Не удалось определить организацию'); - end; - if (NCOMPANY is null) then - P_EXCEPTION(0, 'В исходящем сообщении не указана организация'); - end if; - /* Разбираем ответ сервера */ - if (CRESP is not null) then - begin - select EXTRACTVALUE(XMLTYPE(CRESP), '/AGENT/SAGNABBR') SAGNABBR, - EXTRACTVALUE(XMLTYPE(CRESP), '/AGENT/SAGNNAME') SAGNNAME - into SAGNABBR, - SAGNNAME - from DUAL; - exception - when others then - P_EXCEPTION(0, 'Неожиданный ответ сервера.'); - end; - else - P_EXCEPTION(0, 'Не указаны данные для добавления контрагента.'); - end if; - if (SAGNABBR is null) then - P_EXCEPTION(0, 'В ответе сервера не указан мнемокод контрагента.'); - end if; - if (SAGNNAME is null) then - P_EXCEPTION(0, - 'В ответе сервера не указано наименование контрагента.'); - end if; - /* Найдём каталог */ - FIND_ACATALOG_NAME(NFLAG_SMART => 0, - NCOMPANY => NCOMPANY, - NVERSION => null, - SUNITCODE => 'AGNLIST', - SNAME => 'ExchangeService', - NRN => NCRN); - /* Регистрируем контрагента */ - P_AGNLIST_BASE_INSERT(NCOMPANY => NCOMPANY, - NCRN => NCRN, - SAGNABBR => SUBSTR(NIDENT || SAGNABBR, 1, 20), - SAGNNAME => SAGNNAME || ' ' || NIDENT, - NRN => NAGENT); - /* Фиксируем испех исполнения */ - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_OK); - exception - when others then - PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); - end AGENT_PROCESS_INFO; - -end; -/ diff --git a/db/UDO_P_FISCDOCS_BASE_SEND.prc b/db/UDO_P_FISCDOCS_BASE_SEND.prc deleted file mode 100644 index 76bc894..0000000 --- a/db/UDO_P_FISCDOCS_BASE_SEND.prc +++ /dev/null @@ -1,71 +0,0 @@ -create or replace procedure UDO_P_FISCDOCS_BASE_SEND -( - NRN in number, -- Регистрационный номер - NCOMPANY in number -- Организация -) -as - NEXSQUEUE PKG_STD.TREF; -- Регистрационный номер записи очереди обмена - SPRC_NAME varchar2(60); -- Наименование процедуры проверки значений - PRMS PKG_CONTPRMLOC.TCONTAINER; -- Контейнер для параметров процедуры обработки -begin - /* Проверка заполнения обязательных атрибутов */ - UDO_P_FISCDOCSPROP_CHECK_REQ(NCOMPANY => NCOMPANY, NPRN => NRN); - - /* Определение процедуры проверки значений */ - for REC in (select V.PKG_CHECK, - V.PRC_CHECK - from UDO_FISCDOCS T, - UDO_FDKNDVERS V - where T.RN = NRN - and T.COMPANY = NCOMPANY - and T.TYPE_VERSION = V.RN) - loop - /* Наименование процедуры */ - SPRC_NAME := NULLIF(REC.PKG_CHECK || '.', '.') || REC.PRC_CHECK; - end loop; - - /* Если есть заполнена процедура проверки */ - if (SPRC_NAME is not null) then - /* Установка значений фиксированных входных параметров */ - PKG_CONTPRMLOC.APPENDN(RCONTAINER => PRMS, SNAME => 'NRN', NVALUE => NRN, NIN_OUT => PKG_STD.IPARAM_TYPE_IN); - PKG_CONTPRMLOC.APPENDN(RCONTAINER => PRMS, - SNAME => 'NCOMPANY', - NVALUE => NCOMPANY, - NIN_OUT => PKG_STD.IPARAM_TYPE_IN); - /* Выполнение процедуры */ - begin - PKG_SQL_CALL.EXECUTE_STORED(SSTORED_NAME => SPRC_NAME, RPARAM_CONTAINER => PRMS); - exception - when others then - P_EXCEPTION(0, - 'Ошибка выполнения процедуры "%s".' || CR || 'Текст ошибки: %s', - SPRC_NAME, - sqlerrm); - end; - end if; - - /* Формирование и отправка сообщения для АТОЛ-Онлайн */ - UDO_P_FISCDOCS_MAKE_MSG_ATOL(NCOMPANY => NCOMPANY, NFISCDOC => NRN, NEXSQUEUE => NEXSQUEUE); - - /* Создание связи между чеком и очередью обмена */ - PKG_DOCLINKS.LINK(NFLAG_SMART => 0, - NCOMPANY => NCOMPANY, - SIN_UNITCODE => 'UDO_FiscalDocuments', - NIN_DOCUMENT => NRN, - SOUT_UNITCODE => 'EXSQueue', - NOUT_DOCUMENT => NEXSQUEUE); - - /* Изменение статуса */ - UDO_P_FISCDOCS_BASE_SET_STATUS(NRN => NRN, NCOMPANY => NCOMPANY, NSTATUS => 1); - - /* Установка даты и времени отправки */ - update UDO_FISCDOCS - set SEND_TIME = sysdate - where RN = NRN - and COMPANY = NCOMPANY; - - if (sql%notfound) then - PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'UDO_FiscalDocuments'); - end if; -end; -/ diff --git a/db/UDO_P_FISCDOCS_GET_STATE_ATOL.prc b/db/UDO_P_FISCDOCS_GET_STATE_ATOL.prc deleted file mode 100644 index bfa0fb2..0000000 --- a/db/UDO_P_FISCDOCS_GET_STATE_ATOL.prc +++ /dev/null @@ -1,27 +0,0 @@ -create or replace procedure UDO_P_FISCDOCS_GET_STATE_ATOL -as - NEXSQUEUE PKG_STD.TREF; -- Регистрационный номер добавленной позиции очереди обмена -begin - /* Обходим фискальные документы, успешно отправленные в АТОЛ, но по которым ещё нет проставленного статуса */ - for C in (select T.COMPANY, - T.RN, - Q.RESP BUUID - from UDO_FISCDOCS T, - EXSQUEUE Q - where ((T.SEND_ERROR is null) and (T.CONFIRM_DATE is null)) - and Q.LNK_COMPANY = T.COMPANY - and Q.LNK_UNITCODE = 'UDO_FiscalDocuments' - and Q.LNK_DOCUMENT = T.RN - and Q.EXEC_STATE = PKG_EXS.NQUEUE_EXEC_STATE_OK - and Q.EXSSERVICEFN = UDO_PKG_EXS_ATOL.UTL_FISCDOC_GET_EXSFN_REG(T.RN)) - loop - /* Ставим запрос на получение статуса документа в очередь */ - PKG_EXS.QUEUE_PUT(NEXSSERVICEFN => UDO_PKG_EXS_ATOL.UTL_FISCDOC_GET_EXSFN_INF(NFISCDOC => C.RN), - BMSG => C.BUUID, - NLNK_COMPANY => C.COMPANY, - NLNK_DOCUMENT => C.RN, - SLNK_UNITCODE => 'UDO_FiscalDocuments', - NNEW_EXSQUEUE => NEXSQUEUE); - end loop; -end; -/ diff --git a/db/UDO_P_FISCDOCS_MAKE_MSG_ATOL.prc b/db/UDO_P_FISCDOCS_MAKE_MSG_ATOL.prc deleted file mode 100644 index 70f5c7b..0000000 --- a/db/UDO_P_FISCDOCS_MAKE_MSG_ATOL.prc +++ /dev/null @@ -1,162 +0,0 @@ -create or replace procedure UDO_P_FISCDOCS_MAKE_MSG_ATOL -( - NCOMPANY in number, -- Организация - NFISCDOC in number, -- Регистрационный номер фискального документа - NEXSQUEUE out number -- Регистрационный номер добавленной позиции очереди обмена -) -as - /* Локальные переменные */ - CDATA clob; -- Буфер для XML-посылки - NTMP_RN PKG_STD.TREF; -- Буфер для вычислений - REXSSERVICEFN EXSSERVICEFN%rowtype; -- Запись функции сервиса интеграции - BTEST_SRV boolean := false; -- Признак тестового сервиса - - /* Добавление пустой открытой ветки */ - procedure NODE - ( - SNAME varchar2 -- Имя ветки - ) - as - begin - /* Открываем ветку */ - PKG_XMLFAST.DOWN(SNAME => SNAME); - /* Добавляем её */ - PKG_XMLFAST.NODE; - end NODE; - - /* Добавление ветки со значением (строка) */ - procedure NODE - ( - SNAME varchar2, -- Имя ветки - SVALUE varchar2 -- Значение ветки (строка) - ) - as - begin - /* Открываем ветку */ - PKG_XMLFAST.DOWN(SNAME => SNAME); - /* Добавляем её */ - PKG_XMLFAST.NODE; - /* Выставляем значение */ - PKG_XMLFAST.VALUE(SVALUE => SVALUE); - /* Закрываем ветку */ - PKG_XMLFAST.UP; - end NODE; - - /* Добавление ветки со значением (число) */ - procedure NODE - ( - SNAME varchar2, -- Имя ветки - NVALUE number -- Значение ветки (число) - ) - as - begin - /* Открываем ветку */ - PKG_XMLFAST.DOWN(SNAME => SNAME); - /* Добавляем её */ - PKG_XMLFAST.NODE; - /* Выставляем значение */ - PKG_XMLFAST.VALUE(NVALUE => NVALUE); - /* Закрываем ветку */ - PKG_XMLFAST.UP; - end NODE; - - /* Добавление ветки со значением (дата) */ - procedure NODE - ( - SNAME varchar2, -- Имя ветки - DVALUE date -- Значение ветки (дата) - ) - as - begin - /* Открываем ветку */ - PKG_XMLFAST.DOWN(SNAME => SNAME); - /* Добавляем её */ - PKG_XMLFAST.NODE; - /* Выставляем значение */ - PKG_XMLFAST.VALUE(DVALUE => DVALUE); - /* Закрываем ветку */ - PKG_XMLFAST.UP; - end NODE; - -begin - /* Проверим наличие документа */ - UDO_P_FISCDOCS_EXISTS(NRN => NFISCDOC, NCOMPANY => NCOMPANY, NCRN => NTMP_RN, NJUR_PERS => NTMP_RN); - /* Определим сервис интеграции и его функцию, через которые будем отправлять сообщение */ - REXSSERVICEFN := GET_EXSSERVICEFN_ID(NFLAG_SMART => 0, - NRN => UDO_PKG_EXS_ATOL.UTL_FISCDOC_GET_EXSFN_REG(NFISCDOC => NFISCDOC)); - /* Выставим флаг тестового сервиса */ - BTEST_SRV := UDO_PKG_EXS_ATOL.UTL_EXSSERVICE_IS_TEST(NEXSSERVICE => REXSSERVICEFN.PRN); - /* Инициализируем сборку документа для отправки */ - PKG_XMLFAST.PROLOGUE(NENCODING => PKG_XMLFAST.ENCODING_UTF8_, - NSTANDALONE => PKG_XMLFAST.STANDALONE_YES_, - BALINE => true); - /* Открываем корень XML документа */ - NODE(SNAME => 'FISCDOC'); - /* Курсорный цикл для доступа к данным фискального документа */ - for D in (select T.* - from UDO_FISCDOCS T - where T.RN = NFISCDOC - and T.COMPANY = NCOMPANY) - loop - /* Данные заголовка фискального документа */ - NODE(SNAME => 'NRN', NVALUE => D.RN); - NODE(SNAME => 'DDOC_DATE', DVALUE => D.DOC_DATE); - NODE(SNAME => 'SDDOC_DATE', SVALUE => TO_CHAR(D.DOC_DATE, 'dd.mm.yyyy hh24:mi:ss')); - /* Список свойств фискального документа */ - NODE('FISCDOC_PROPS'); - for SP in (select A.CODE SCODE, - A.NAME SNAME, - UDO_GET_FISCDOCSPROP_VALUE(T.RN) SVALUE, - T.VAL_STR SVAL_STR, - T.VAL_NUMB NVAL_NUMB, - T.VAL_DATE DVAL_DATE, - T.VAL_DATETIME DVAL_DATETIME - from UDO_FISCDOCSPROP T, - UDO_FDKNDATT P, - UDO_FISCDOCATT A - where T.PRN = D.RN - and T.PROP = P.RN - and P.ATTRIBUTE = A.RN) - loop - /* Свойство фискального документа */ - NODE(SNAME => 'FISCDOC_PROP'); - /* Для некоторых тэгов необходим тестовый набор данных, если это тестовый сервис */ - if (BTEST_SRV) then - /* Подставим тестовый ИНН */ - if (SP.SCODE = '1018') then - SP.SVALUE := UDO_PKG_EXS_ATOL.STEST_INN; - SP.SVAL_STR := UDO_PKG_EXS_ATOL.STEST_INN; - end if; - /* Подставим тестовый адрес расчётов */ - if (SP.SCODE = '1187') then - SP.SVALUE := UDO_PKG_EXS_ATOL.STEST_ADDR; - SP.SVAL_STR := UDO_PKG_EXS_ATOL.STEST_ADDR; - end if; - end if; - /* Данные свойства фискального документа */ - NODE(SNAME => 'SCODE', SVALUE => SP.SCODE); - NODE(SNAME => 'SNAME', SVALUE => SP.SNAME); - NODE(SNAME => 'VALUE', SVALUE => SP.SVALUE); - NODE(SNAME => 'SVALUE', SVALUE => SP.SVAL_STR); - NODE(SNAME => 'NVALUE', NVALUE => SP.NVAL_NUMB); - NODE(SNAME => 'DVALUE', DVALUE => SP.DVAL_DATE); - NODE(SNAME => 'DTVALUE', DVALUE => SP.DVAL_DATETIME); - /* Закрываем свойство фискального документа */ - PKG_XMLFAST.UP; - end loop; - /* Закрываем список свойств фискального документа */ - PKG_XMLFAST.UP; - end loop; - /* Закрываем корневой тэг XML-документа */ - PKG_XMLFAST.UP; - /* Финализируем сборку XML-документа */ - PKG_XMLFAST.EPILOGUE(LDATA => CDATA); - /* Отправляем сформированный документ */ - PKG_EXS.QUEUE_PUT(NEXSSERVICEFN => REXSSERVICEFN.RN, - BMSG => CLOB2BLOB(LCDATA => CDATA, SCHARSET => 'UTF8'), - NLNK_COMPANY => NCOMPANY, - NLNK_DOCUMENT => NFISCDOC, - SLNK_UNITCODE => 'UDO_FiscalDocuments', - NNEW_EXSQUEUE => NEXSQUEUE); -end; -/