AnyStat на примере 4512-У
AnyStat – Универсальный механизм сбора и учета информации о направленных/принятых файлах и квитанциях модулем statmonitordb ПП “УФО Checker” для дальнейшего ее отображения в ПМ “Монитор Отчетности”. Описание данного механизма содержится в документации к модулю statmonitordb.
Для работы данного механизма потребуются дополнительные таблицы в БД. Исходные данные уже содержат информацию по сбору информации, касающейся отчетности 3412-У. Далее рассмотрим стратегию сбора этих данных более подробно.
Для хранения информации используются две таблицы
Основная таблица для хранения информации STAT_4512
| S4512_ID | идентификатор записи | 
| S4512_DATE | дата | 
| S4512_TYPE | тип сообщения (ЭСВТ/ЭСКР) | 
| S4512_FILE | имя файла | 
| S4512_PASSPORT | номер паспорта | 
| S4512_CONDATE | дата контракта | 
| S4512_FNS | флаг квитанции ФНС (0 – квитанции нет, 1 – положительная, 2 – отрицательная) | 
| S4512_FTS | флаг квитанции ФТС | 
| S4512_STATE | общий статус для записи | 
| S4512_XML | поле для сохранения xml файла | 
Вторичная таблица. Файлы, связанные с основным (файлы ЭККР/ЭКВТ, квитанции) STAT_4512_FILES
| S4512F_ID | идентификатор | 
| S4512F_SRC | ссылка на первичный файл в (S4512_ID в STAT_4512) | 
| S4512F_DATE | дата файла | 
| S4512F_FILENAME | имя файла | 
| S4512F_STATE | статус файла | 
| S4512F_COMMENT | комментарий (если были ошибки) | 
| S4512F_XML | для хранения xml квитанции | 
В рамках Указания ходят следующие типы файлов:
- первичные ЭКВТ/ЭСКР (PS*.xml)
 - вложения к первичным ЭСКР/ЭККР (DC.)
 - Квитанции ФТС
 - Квитанции ФНС
 
Касаемо квитанций. Префиксы файлов по типам и результату:
| Тип | Рез. | ФТС | ФНС | 
| PS | + | FS | NS | 
| – | ES | нет | |
| DC | + | FC | NC | 
| – | EC | нет | 
Класс отчетности определим как “4512” и вызываться в последствии будет с помощью run0_statutils= -ANYSTAT_4512
На первом этапе необходимо классифицировать файл (понять тип файла). Это описано в таблице STAT_CLASS, в строках с указанным CS_CLASS=4512
ЭСВТ:
| SC_QUERY – правила классификации | FILE:IN:1,2,3,4,9:%N22&1% – 22 символ имени файла 1,2,3,4,9 FILE:=:PS:%N1&2% – и первые два символа имени файла PS  | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451202 | 
| SC_CHECK – проверка перед обработкой | 451200:>:0:Файл уже присутствует в БД:select count(*) from stat_4512 where S4512_FILE=:FNAME в соответствии с записью 451200 в STAT_WORK извлекаются данные, sql выбирает количество записей с таким же именем файла, и если записи есть, файл отбраковывается как повторный  | 
ЭСКР:
| SC_QUERY – правила классификации | FILE:IN:5,6:%N22&1% – 22 символ имени файла 5,6 FILE:=:PS:%N1&2% – и первые два символа имени файла PS  | 
| SC_LINK – ссылка на STAT_WORK | 451203 | 
| SC_CHECK – проверка перед обработкой | 451200:>:0:Файл уже присутствует в БД:select count(*) from stat_4512 where S4512_FILE=:FNAME проверка уникальности файла аналогична ЭСВТ  | 
ЭСКР/ЭККР:
| SC_QUERY – правила классификации | FILE:=:DC:%N1&2% – первые два символа имени файла DC | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451204 | 
| SC_CHECK – проверка перед обработкой | проверка уникальности имени файла в таблице вторичных файлов и проверка наличия первичного файла 451200:>:0:Файл уже присутствует в БД:select count() from stat_4512_files where S4512F_FILENAME=:FNAME 451200:=:0:Отсутствует первичный файл:select count() from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’)  | 
Положительные квитанции ФТС ЭСВТ/ЭСКР:
| SC_QUERY – правила классификации | FILE:=:FS:%N1&2% – первые два символа именги файла FS | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451205 | 
| SC_CHECK – проверка перед обработкой | проверка уникальности имени файла в таблице вторичных файлов и проверка наличия первичного файла 451200:>:0:Файл уже присутствует в БД:select count() from stat_4512_files where S4512F_FILENAME=:FNAME 451200:=:0:Отсутствует первичный файл:select count() from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’)  | 
Положительные квитанции ФНС/ФТС ЭКВТ/ЭККР
| SC_QUERY – правила классификации | FILE:IN:NC,FC:%N1&2% – первые два символа именги файла FS | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451207 | 
| SC_CHECK – проверка перед обработкой | проверка уникальности имени файла в таблице вторичных файлов и проверка наличия первичного файла 451200:>:0:Файл уже присутствует в БД:select count() from stat_4512_files where S4512F_FILENAME=:FNAME 451200:=:0:Отсутствует первичный файл:select count() from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’)  | 
Положительные квитанции ФНС ЭСВТ/ЭСКР
| SC_QUERY – правила классификации | FILE:=:NS:%N1&2% | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451208 | 
| SC_CHECK – проверка перед обработкой | 451200:>:0:Файл уже присутствует в БД:select count() from stat_4512_files where S4512F_FILENAME=:FNAME 451200:=:0:Отсутствует первичный файл:select count() from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’) | 
Отрицательные квитанции ФТС ЭСВТ/ЭСКР
| SC_QUERY – правила классификации | FILE:=:ES:%N1&2% | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451206 | 
| SC_CHECK – проверка перед обработкой | 451200:>:0:Файл уже присутствует в БД:select count() from stat_4512_files where S4512F_FILENAME=:FNAME 451200:=:0:Отсутствует первичный файл:select count() from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’) | 
Отрицательные квитанции ЭСКР/ЭККР
| SC_QUERY – правила классификации | FILE:=:EC:%N1&2% | 
| SC_LINK – ссылка на запись в таблице STAT_WORK | 451209 | 
| SC_CHECK – проверка перед обработкой | 451200:>:0:Файл уже присутствует в БД:select count() from stat_4512_files where S4512F_FILENAME=:FNAME 451200:=:0:Отсутствует первичный файл:select count() from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’) | 
При проверках перед обработкой (SC_CHECK) используется запись из STAT_WORK с идентификатором 451200
Из записи требуется только поле SW_QUERY:
FNAME:FILE:%N%.%E% – Полное имя файла
FNAME2:FILE:%N3&32% – имя файла без первых двух символов
Далее можно обработать файл, в соответствии со стратегией сбора и добавления информации из STAT_WORK, используя записи с SW_ID совпадающим с полученным на этапе классификации SC_LINK
ЭСВТ (SW_ID=451202)
| SW_QUERY – извлечение данных | FILENAME:XPATH://TRANSPORT/THEADER/@file – извлекаем в переменную FILENAME имя файла в соответствии с XPath (извлекаем значение параметра file тэга THEADER, находящегося внутри TRANSPORT) PASSPORT:XPATH://TRANSPORT/THEADER/Pasport/text() – извлекаем в переменную PASSPORT номер паспорта в соответствии с XPath (извлекаем текст внутри тэга Pasport, находящегося внутри тэга THEADER, находящегося внутри TRANSPORT) CONDATE:XPATH://TRANSPORT/THEADER/Date/text() – извлекаем в переменную CONDATE дату контракта в соответствии с XPath (извлекаем текст внутри тэга Date, находящегося внутри тэга THEADER, находящегося внутри TRANSPORT) XML:XPATH://* – В переменную XML сохраним весь xml документ с корня  | 
| SW_SQL – sql инструкции добавления данных в таблицы | INSERT INTO STAT_4512 ( S4512_DATE, S4512_TYPE, S4512_FILE, S4512_PASSPORT, S4512_CONDATE, S4512_FNS, S4512_FTS, S4512_STATE,S4512_XML) VALUES (current_timestamp,’ЭСВТ’,:FILENAME,:PASSPORT,:CONDATE,0,0,0,:XML) | 
ЭСКР (SW_ID=451203)
| SW_QUERY – извлечение данных | FILENAME:XPATH://TRANSPORT/THEADER/@file – извлекаем в переменную FILENAME имя файла в соответствии с XPath (извлекаем значение параметра file тэга THEADER, находящегося внутри TRANSPORT) PASSPORT:XPATH://TRANSPORT/THEADER/Pasport/text() – извлекаем в переменную PASSPORT номер паспорта в соответствии с XPath (извлекаем текст внутри тэга Pasport, находящегося внутри тэга THEADER, находящегося внутри TRANSPORT) CONDATE:XPATH://TRANSPORT/THEADER/Date/text() – извлекаем в переменную CONDATE дату контракта в соответствии с XPath (извлекаем текст внутри тэга Date, находящегося внутри тэга THEADER, находящегося внутри TRANSPORT) XML:XPATH://* – В переменную XML сохраним весь xml документ с корня  | 
| SW_SQL – sql инструкции добавления данных в таблицы | INSERT INTO STAT_4512 ( S4512_DATE, S4512_TYPE, S4512_FILE, S4512_PASSPORT, S4512_CONDATE, S4512_FNS, S4512_FTS, S4512_STATE,S4512_XML) VALUES (current_timestamp,’ЭСКР’,:FILENAME,:PASSPORT,:CONDATE,0,0,0,:XML) | 
ЭСКР/ЭККР (SW_ID=451204)
| SW_QUERY – извлечение данных | FNAME:FILE:%N%.%E% – Полное имя файла FNAME2:FILE:%N3&32% – имя файла без первых двух символов  | 
| SW_SQL – sql инструкции добавления данных в таблицы | Первой инструкцией ищем идентификатор первичного файла (результат будет помещен в переменную Q_1_1) и затем добавляем извлеченную информацию в таблицу STAT_4512_FILES select S4512_ID from STAT_4512 where upper(S4512_FILE)=upper(‘PS%FNAME2%.XML’) INSERT INTO STAT_4512_FILES (S4512F_SRC, S4512F_DATE, S4512F_FILENAME, S4512F_STATE) VALUES (:Q_1_1, current_timestamp,:FNAME, 0)  | 
Положительные квитанции ФТС ЭСВТ/ЭСКР (SW_ID=451205)
| SW_QUERY – извлечение данных | FNAME:FILE:%N%.%E% SRCFILENAME:XPATH://KVIT/ES/text() – из квитанции извлекаем имя исходного файла XML:XPATH://* – сохраняем текст xml  | 
| SW_SQL – sql инструкции добавления данных в таблицы | Сначала обновляем основную таблицу (ставим отметку о получении квитанции) и затем добавляем файл во вторичную таблицу update STAT_4512 set S4512_FTS=1 where upper(S4512_FILE)=upper(:SRCFILENAME) returning S4512_ID INSERT INTO STAT_4512_FILES (S4512F_SRC, S4512F_DATE, S4512F_FILENAME, S4512F_STATE,S4512F_XML) VALUES (:Q_1_1, current_timestamp,:FNAME, 1,:XML)  | 
Отрицательные квитанции ФТС ЭСВТ/ЭСКР (SW_ID=451206)
| SW_QUERY – извлечение данных | FNAME:FILE:%N%.%E% SRCFILENAME:XPATH://KVIT/ES/text() – из квитанции извлекаем имя исходного файла ERRORS:XPATH://KVIT/ERRORS_ES/ERR_REC/NAM_ERR/text() – извлекаем текст ошибок XML:XPATH://*  | 
| SW_SQL – sql инструкции добавления данных в таблицы | Сначала обновляем основную таблицу (ставим отметку о получении отрицательной квитанции), затем добавляем файл во вторичную таблицу и затем ставим общий статус для записи – ошибка update STAT_4512 set S4512_FTS=2 where upper(S4512_FILE)=upper(:SRCFILENAME) returning S4512_ID INSERT INTO STAT_4512_FILES (S4512F_SRC, S4512F_DATE, S4512F_FILENAME, S4512F_STATE,S4512F_XML) VALUES (:Q_1_1, current_timestamp,:FNAME, -1,:XML) update STAT_4512 set S4512_STATE=2 where S4512_ID=:Q_1_1‘)  | 
Положительные квитанции ФНС/ФТС ЭКВТ/ЭККР (SW_ID=451207)
| SW_QUERY – извлечение данных | FNAME:FILE:%N%.%E% SRCFILENAME:XPATH://KVIT/ES/text() XML:XPATH://*  | 
| SW_SQL – sql инструкции добавления данных в таблицы | select S4512F_SRC from STAT_4512_FILES where upper(S4512F_FILENAME)=upper(:SRCFILENAME) INSERT INTO STAT_4512_FILES (S4512F_SRC, S4512F_DATE, S4512F_FILENAME, S4512F_STATE,S4512F_COMMENT,S4512F_XML) VALUES (:Q_1_1, current_timestamp,:FNAME, 1,”,:XML‘)  | 
Положительные квитанции ФНС ЭСВТ/ЭСКР (SW_ID=451208)
| SW_QUERY – извлечение данных | FNAME:FILE:%N%.%E% SRCFILENAME:XPATH://KVIT/ES/text() XML:XPATH://*  | 
| SW_SQL – sql инструкции добавления данных в таблицы | update STAT_4512 set S4512_FNS=1 where upper(S4512_FILE)=upper(:SRCFILENAME) returning S4512_ID INSERT INTO STAT_4512_FILES (S4512F_SRC, S4512F_DATE, S4512F_FILENAME, S4512F_STATE,S4512F_XML) VALUES (:Q_1_1, current_timestamp,:FNAME, 1,:XML)  | 
Отрицательные квитанции ЭСКР/ЭККР (SW_ID=451209)
| SW_QUERY – извлечение данных | FNAME:FILE:%N%.%E% SRCFILENAME:XPATH://KVIT/ES/text() ERRORS:XPATHSPLIT://KVIT/ERRORS_ES/ERR_REC/NAM_ERR/text() XML:XPATH://*  | 
| SW_SQL – sql инструкции добавления данных в таблицы | update STAT_4512_FILES set S4512F_STATE=2 where upper(S4512F_FILENAME)=upper(:SRCFILENAME) returning S4512F_SRC INSERT INTO STAT_4512_FILES (S4512F_SRC, S4512F_DATE, S4512F_FILENAME, S4512F_STATE,S4512F_COMMENT,S4512F_XML) VALUES (:Q_1_1, current_timestamp,:FNAME, -1,:ERRORS,:XML update STAT_4512 set S4512_STATE=2 where S4512_ID=:Q_1_1′  | 
Рассмотрим работу на примере исходного файла PS18010001_0920_0000_1_0_0920_0000.xml
<?xml version="1.0" encoding="windows-1251"?>
<TRANSPORT verspo="string">
  <THEADER len="6669" date="68/72/6474" time="80:36:09" regn="8860/1960" file="PS18010001_0920_0000_1_0_0920_0000.xml">
    <RepType>ps_ei4</RepType>
    <Bank>string</Bank>
    <Pasport>7739T78V/8224/7691/1/1</Pasport>
    <Date>12/12/2020</Date>
  </THEADER>
  <TBODY len="8216" nTabl="8870">
<!-- ............................ -->
  </TBODY>
</TRANSPORT>
Файл классифицируется как ЭСВТ:
FILE:IN:1,2,3,4,9:%N22&1% - в нашем случае - 1
FILE:=:PS:%N1&2% - и первые два символа имени файла PS
Т.о. получаем SC_LINK=451202
Проверка перед добавлением:
451200:>:0:Файл уже присутствует в БД:select count(*) from stat_4512 where S4512_FILE=:FNAME
Если файла в таблице нет, запрос вернет 0, и условие отбраковки не сработает.
Извлечение данных:
В соответствии с SW_QUERY записи, извлекаем необходимые данные
| FILENAME:XPATH://TRANSPORT/THEADER/@file | PS18010001_0920_0000_1_0_0920_0000.xml | 
| PASSPORT:XPATH://TRANSPORT/THEADER/Pasport/text() | 7739T78V/8224/7691/1/1 | 
| CONDATE:XPATH://TRANSPORT/THEADER/Date/text() | 12/12/2020 | 
| XML:XPATH://* | (Полный текст xml) | 
Добавление данных в таблицу:
INSERT INTO STAT_4512 ( S4512_DATE, S4512_TYPE, S4512_FILE, S4512_PASSPORT, S4512_CONDATE, S4512_FNS, S4512_FTS, S4512_STATE,S4512_XML) VALUES (current_timestamp,'ЭСВТ',:FILENAME,:PASSPORT,:CONDATE,0,0,0,:XML)
		