feat: внешняя обработка «Просмотр реестров платежей» 1.0.0 — чтение XML-реестров к платёжным поручениям и печать реестра
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
# Служебные файлы EDT и ОС
|
||||||
|
.metadata/
|
||||||
|
*.log
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
Thumbs.db
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>ПросмотрРеестровПлатежей</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||||
|
<nature>com._1c.g5.v8.dt.core.V8ExternalObjectsNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"settings": {
|
||||||
|
"common-module-server-call": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
com._1c.g5.v8.dt.platform.services.core.PREF_AUTO_EXT_OBJECT_DUMP_GENERATION=true
|
||||||
|
eclipse.preferences.version=1
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
topObjects=true
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
addModuleStrictTypesAnnotation=false
|
||||||
|
createModuleStructure=false
|
||||||
|
eclipse.preferences.version=1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
commonChecks=true
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
standardChecks=true
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding/<project>=UTF-8
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Runtime-Version: 8.5.1
|
||||||
|
X-External-Script-Variant: Russian
|
||||||
|
X-External-Languages: ru;name="Русский"
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# Просмотр реестров платежей
|
||||||
|
|
||||||
|
Внешняя обработка 1С:Предприятия для просмотра и печати XML-файлов реестров к платёжным поручениям на общую сумму с реестром (формат `ProcessRegPayOrder`, поставка форматов `PPRegister`, вид обмена «Обмен с ОФК (ПП с реестром)»).
|
||||||
|
|
||||||
|
Обработка внешняя: конфигурацию не меняет, с поддержки не снимает, ставится как файл `.epf`.
|
||||||
|
|
||||||
|
## Зачем
|
||||||
|
|
||||||
|
Организации получают из СУФД файлы реестров, в которых перечислены распоряжения плательщиков. Читать XML неудобно, а грузить кассовые поступления и разбирать назначения платежей ради просмотра — избыточно. Обработка показывает содержимое файлов в таблице и печатает реестр.
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
|
||||||
|
- выбор каталога с файлами `*.xml` — кнопкой «Выбрать каталог» или в поле каталога;
|
||||||
|
- обработка всех файлов каталога за один проход, строки всех реестров в одной таблице;
|
||||||
|
- контроль целостности: сумма строк сверяется с суммой платёжного поручения из файла, расхождение выводится предупреждением;
|
||||||
|
- мягкая обработка ошибок: файл, который не удалось прочитать, пропускается, остальные обрабатываются;
|
||||||
|
- печать: заголовок «Реестр платежей», таблица с рамками и строка «ИТОГО» по сумме.
|
||||||
|
|
||||||
|
## Колонки
|
||||||
|
|
||||||
|
| Колонка | Источник в XML |
|
||||||
|
|---|---|
|
||||||
|
| Файл | имя файла |
|
||||||
|
| № ПП | `NOM_PP` |
|
||||||
|
| № распоряжения | `NOM_PAY_DOC` |
|
||||||
|
| Дата распоряжения | `DATE_PAY_DOC`, при пустом — `DATE_REESTR_PP` |
|
||||||
|
| Плательщик | `NAME_PLAT` до разделителя `//`, при пустом — `FIO_PLAT` |
|
||||||
|
| Счёт плательщика | `NOM_LS_PLAT` |
|
||||||
|
| Сумма | `SUM_REESTR_PP` (в файле в копейках, выводится в рублях) |
|
||||||
|
| Назначение платежа | `PURPOSE` целиком |
|
||||||
|
| Статус | `PAYSTATUS` |
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- платформа 1С:Предприятие 8.5.1 (под ней собран проект);
|
||||||
|
- любая конфигурация — обработка внешняя, объекты конфигурации не используются;
|
||||||
|
- файлы реестров в формате `ProcessRegPayOrder`.
|
||||||
|
|
||||||
|
## Как запустить
|
||||||
|
|
||||||
|
1. `1С:Предприятие` → **Файл → Открыть…** → `bin/ПросмотрРеестровПлатежей.epf`.
|
||||||
|
2. Нажать «Выбрать каталог» и указать папку с файлами реестров.
|
||||||
|
3. Нажать «Сформировать» — строки появятся в таблице.
|
||||||
|
4. Нажать «Печать реестра» — сформируется печатная форма.
|
||||||
|
|
||||||
|
## Как открыть и собрать в EDT
|
||||||
|
|
||||||
|
1. **File → Import → General → Existing Projects into Workspace**, выбрать корневую папку репозитория. Проект называется `ПросмотрРеестровПлатежей`.
|
||||||
|
2. Сборка: **Проект → Очистить**, затем **Проект → Собрать**. Результат — `bin/ПросмотрРеестровПлатежей.epf`. Отдельного экспорта `.epf` в EDT не требуется.
|
||||||
|
|
||||||
|
## Устройство
|
||||||
|
|
||||||
|
Вся логика — в модуле формы обработки (`src/ExternalDataProcessors/ПросмотрРеестровПлатежей/Forms/Форма/Module.bsl`); модуль объекта не используется.
|
||||||
|
|
||||||
|
- клиентские обработчики: выбор каталога, «Сформировать», «Печать реестра»;
|
||||||
|
- серверные (`&НаСервере` / `&НаСервереБезКонтекста`): чтение каталога (`НайтиФайлы`), разбор XML потоком (`ЧтениеXML`), заполнение таблицы формы, формирование табличного документа;
|
||||||
|
- суммы из файла приходят в копейках и делятся на 100; даты разбираются из формата `ГГГГ-ММ-ДД`.
|
||||||
|
|
||||||
|
## Ограничения
|
||||||
|
|
||||||
|
- назначение платежа выводится целиком и не разбирается на реквизиты (лицевой счёт ребёнка, группа, период): у разных организаций свободный текст, разбор по запятым даёт мусор;
|
||||||
|
- электронная подпись файлов не проверяется: подписанные контейнеры нужно предварительно расшифровать;
|
||||||
|
- обрабатываются только файлы формата «платёжное поручение на общую сумму с реестром»; прочие файлы пропускаются с сообщением.
|
||||||
|
|
||||||
|
## Версия
|
||||||
|
|
||||||
|
1.0.0
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,686 @@
|
|||||||
|
#Область ОбработчикиСобытийЭлементовШапкиФормы
|
||||||
|
|
||||||
|
&НаКлиенте
|
||||||
|
Процедура КаталогНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
|
||||||
|
|
||||||
|
СтандартнаяОбработка = Ложь;
|
||||||
|
ВыбратьКаталогИзДиалога();
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ОбработчикиКомандФормы
|
||||||
|
|
||||||
|
&НаКлиенте
|
||||||
|
Процедура ВыбратьКаталог(Команда)
|
||||||
|
|
||||||
|
ВыбратьКаталогИзДиалога();
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
&НаКлиенте
|
||||||
|
Процедура Сформировать(Команда)
|
||||||
|
|
||||||
|
Если Не ЗначениеЗаполнено(Каталог) Тогда
|
||||||
|
ПоказатьПредупреждение(, НСтр("ru = 'Укажите каталог с файлами реестров.'"));
|
||||||
|
Возврат;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Результат = ПрочитатьРеестры();
|
||||||
|
|
||||||
|
Если ЗначениеЗаполнено(Результат.ТекстСообщений) Тогда
|
||||||
|
ПоказатьПредупреждение(, Результат.ТекстСообщений);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
&НаКлиенте
|
||||||
|
Процедура Печать(Команда)
|
||||||
|
|
||||||
|
Если ТаблицаРеестра.Количество() = 0 Тогда
|
||||||
|
ПоказатьПредупреждение(, НСтр("ru = 'Список строк пуст. Укажите каталог и нажмите «Сформировать».'"));
|
||||||
|
Возврат;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
ТабличныйДокумент = СформироватьПечатнуюФорму();
|
||||||
|
ТабличныйДокумент.Показать(НСтр("ru = 'Реестр платежей'"));
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область СлужебныеПроцедурыИФункции
|
||||||
|
|
||||||
|
&НаКлиенте
|
||||||
|
Процедура ВыбратьКаталогИзДиалога()
|
||||||
|
|
||||||
|
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
|
||||||
|
Диалог.Заголовок = НСтр("ru = 'Каталог с файлами реестров'");
|
||||||
|
|
||||||
|
Если ЗначениеЗаполнено(Каталог) Тогда
|
||||||
|
Диалог.Каталог = Каталог;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если Диалог.Выбрать() Тогда
|
||||||
|
Каталог = Диалог.Каталог;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Читает все xml-файлы реестров из каталога и заполняет таблицу формы.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Структура - ТекстСообщений - Строка - сообщения об ошибках и итоги чтения.
|
||||||
|
//
|
||||||
|
&НаСервере
|
||||||
|
Функция ПрочитатьРеестры()
|
||||||
|
|
||||||
|
СтрокиРеестров = НоваяТаблицаСтрок();
|
||||||
|
Ошибки = Новый Массив;
|
||||||
|
Итоги = ПрочитатьКаталогФайлов(Каталог, СтрокиРеестров, Ошибки);
|
||||||
|
|
||||||
|
ТаблицаРеестра.Очистить();
|
||||||
|
|
||||||
|
Для Каждого СтрокаРеестра Из СтрокиРеестров Цикл
|
||||||
|
НоваяСтрока = ТаблицаРеестра.Добавить();
|
||||||
|
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаРеестра);
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
ТекстСообщений = СтрСоединить(Ошибки, Символы.ПС);
|
||||||
|
|
||||||
|
Если Итоги.ОбработаноФайлов = 0 И Не ЗначениеЗаполнено(ТекстСообщений) Тогда
|
||||||
|
ТекстСообщений = НСтр("ru = 'В каталоге не найдено ни одного файла реестра.'");
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если Итоги.ПропущеноФайлов > 0 Тогда
|
||||||
|
ИтогиТекст = СтрШаблон(НСтр("ru = 'Обработано файлов: %1, пропущено: %2.'"),
|
||||||
|
Итоги.ОбработаноФайлов, Итоги.ПропущеноФайлов);
|
||||||
|
ТекстСообщений = ИтогиТекст + ?(ЗначениеЗаполнено(ТекстСообщений), Символы.ПС + ТекстСообщений, "");
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Возврат Новый Структура("ТекстСообщений", ТекстСообщений);
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
&НаСервере
|
||||||
|
Функция СформироватьПечатнуюФорму()
|
||||||
|
|
||||||
|
ТабличныйДокумент = Новый ТабличныйДокумент;
|
||||||
|
ТабличныйДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
|
||||||
|
ТабличныйДокумент.АвтоМасштаб = Истина;
|
||||||
|
|
||||||
|
ШрифтОбычный = Новый Шрифт("Arial", 8);
|
||||||
|
ШрифтЖирный = Новый Шрифт("Arial", 8, Истина);
|
||||||
|
ШрифтЗаголовка = Новый Шрифт("Arial", 12, Истина);
|
||||||
|
ЛинияРамки = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
|
||||||
|
|
||||||
|
Колонки = КолонкиПечати();
|
||||||
|
КоличествоКолонок = Колонки.Количество();
|
||||||
|
ИндексСуммы = ИндексКолонкиСуммы(Колонки);
|
||||||
|
|
||||||
|
ОбластьЗаголовка = ТабличныйДокумент.Область(1, 1, 1, КоличествоКолонок);
|
||||||
|
ОбластьЗаголовка.Объединить();
|
||||||
|
ОбластьЗаголовка.Текст = НСтр("ru = 'Реестр платежей'");
|
||||||
|
ОбластьЗаголовка.Шрифт = ШрифтЗаголовка;
|
||||||
|
ОбластьЗаголовка.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
|
||||||
|
|
||||||
|
СтрокаШапки = 3;
|
||||||
|
|
||||||
|
Для Индекс = 1 По КоличествоКолонок Цикл
|
||||||
|
Колонка = Колонки[Индекс - 1];
|
||||||
|
ОбластьЯчейки = ТабличныйДокумент.Область(СтрокаШапки, Индекс);
|
||||||
|
ОбластьЯчейки.Текст = Колонка.Заголовок;
|
||||||
|
ОбластьЯчейки.Шрифт = ШрифтЖирный;
|
||||||
|
ОбластьЯчейки.Обвести(ЛинияРамки, ЛинияРамки, ЛинияРамки, ЛинияРамки);
|
||||||
|
ОбластьЯчейки.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
|
||||||
|
ОбластьЯчейки.ШиринаКолонки = Колонка.Ширина;
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
НомерСтроки = СтрокаШапки + 1;
|
||||||
|
ИтогоСумма = 0;
|
||||||
|
|
||||||
|
Для Каждого СтрокаРеестра Из ТаблицаРеестра Цикл
|
||||||
|
|
||||||
|
Для Индекс = 1 По КоличествоКолонок Цикл
|
||||||
|
|
||||||
|
Колонка = Колонки[Индекс - 1];
|
||||||
|
ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, Индекс);
|
||||||
|
ОбластьЯчейки.Текст = ТекстЗначения(СтрокаРеестра[Колонка.Данные], Колонка.Формат);
|
||||||
|
ОбластьЯчейки.Шрифт = ШрифтОбычный;
|
||||||
|
ОбластьЯчейки.Обвести(ЛинияРамки, ЛинияРамки, ЛинияРамки, ЛинияРамки);
|
||||||
|
|
||||||
|
Если Колонка.Выравнивание = "Право" Тогда
|
||||||
|
ОбластьЯчейки.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
ИтогоСумма = ИтогоСумма + СтрокаРеестра.Сумма;
|
||||||
|
НомерСтроки = НомерСтроки + 1;
|
||||||
|
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
ОбластьИтога = ТабличныйДокумент.Область(НомерСтроки, 1, НомерСтроки, ИндексСуммы - 1);
|
||||||
|
ОбластьИтога.Объединить();
|
||||||
|
ОбластьИтога.Текст = НСтр("ru = 'ИТОГО:'");
|
||||||
|
ОбластьИтога.Шрифт = ШрифтЖирный;
|
||||||
|
ОбластьИтога.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
|
||||||
|
|
||||||
|
ОбластьСуммы = ТабличныйДокумент.Область(НомерСтроки, ИндексСуммы);
|
||||||
|
ОбластьСуммы.Текст = Формат(ИтогоСумма, "ЧДЦ=2; ЧН=0");
|
||||||
|
ОбластьСуммы.Шрифт = ШрифтЖирный;
|
||||||
|
ОбластьСуммы.Обвести(ЛинияРамки, ЛинияРамки, ЛинияРамки, ЛинияРамки);
|
||||||
|
ОбластьСуммы.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
|
||||||
|
|
||||||
|
Возврат ТабличныйДокумент;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция КолонкиПечати()
|
||||||
|
|
||||||
|
Колонки = Новый Массив;
|
||||||
|
|
||||||
|
Колонки.Добавить(КолонкаПечати("Файл", "Файл", 22));
|
||||||
|
Колонки.Добавить(КолонкаПечати("№ ПП", "НомерПП", 8));
|
||||||
|
Колонки.Добавить(КолонкаПечати("№ распоряжения", "НомерРаспоряжения", 12));
|
||||||
|
Колонки.Добавить(КолонкаПечати("Дата распоряжения", "ДатаРаспоряжения", 12, "ДЛФ=D"));
|
||||||
|
Колонки.Добавить(КолонкаПечати("Плательщик", "Плательщик", 28));
|
||||||
|
Колонки.Добавить(КолонкаПечати("Счёт плательщика", "СчетПлательщика", 20));
|
||||||
|
Колонки.Добавить(КолонкаПечати("Сумма", "Сумма", 14, "ЧДЦ=2; ЧН=0", "Право"));
|
||||||
|
Колонки.Добавить(КолонкаПечати("Назначение платежа", "Назначение", 40));
|
||||||
|
Колонки.Добавить(КолонкаПечати("Статус", "Статус", 7));
|
||||||
|
|
||||||
|
Возврат Колонки;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция КолонкаПечати(Заголовок, Данные, Ширина, ФорматЗначения = "", Выравнивание = "Лево")
|
||||||
|
|
||||||
|
Колонка = Новый Структура;
|
||||||
|
Колонка.Вставить("Заголовок", Заголовок);
|
||||||
|
Колонка.Вставить("Данные", Данные);
|
||||||
|
Колонка.Вставить("Ширина", Ширина);
|
||||||
|
Колонка.Вставить("Формат", ФорматЗначения);
|
||||||
|
Колонка.Вставить("Выравнивание", Выравнивание);
|
||||||
|
|
||||||
|
Возврат Колонка;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ИндексКолонкиСуммы(Колонки)
|
||||||
|
|
||||||
|
Для Индекс = 1 По Колонки.Количество() Цикл
|
||||||
|
Если Колонки[Индекс - 1].Данные = "Сумма" Тогда
|
||||||
|
Возврат Индекс;
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Возврат Колонки.Количество();
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ТекстЗначения(Значение, ФорматЗначения)
|
||||||
|
|
||||||
|
Если Значение = Неопределено Тогда
|
||||||
|
Возврат "";
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ТипЗнч(Значение) = Тип("Дата") И Не ЗначениеЗаполнено(Значение) Тогда
|
||||||
|
Возврат "";
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ЗначениеЗаполнено(ФорматЗначения) Тогда
|
||||||
|
Возврат Формат(Значение, ФорматЗначения);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Возврат Строка(Значение);
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Создаёт пустую таблицу строк реестров.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// ТаблицаЗначений - колонки строки реестра.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция НоваяТаблицаСтрок()
|
||||||
|
|
||||||
|
КвалификаторыСуммы = Новый КвалификаторыЧисла(15, 2);
|
||||||
|
ОписаниеСуммы = Новый ОписаниеТипов("Число", КвалификаторыСуммы);
|
||||||
|
ОписаниеСтроки = Новый ОписаниеТипов("Строка");
|
||||||
|
ОписаниеДаты = Новый ОписаниеТипов("Дата");
|
||||||
|
ОписаниеНомера = Новый ОписаниеТипов("Число");
|
||||||
|
|
||||||
|
Строки = Новый ТаблицаЗначений;
|
||||||
|
Строки.Колонки.Добавить("Файл", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("НомерПП", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("ДатаПП", ОписаниеДаты);
|
||||||
|
Строки.Колонки.Добавить("НомерСтроки", ОписаниеНомера);
|
||||||
|
Строки.Колонки.Добавить("НомерРаспоряжения", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("ДатаРаспоряжения", ОписаниеДаты);
|
||||||
|
Строки.Колонки.Добавить("Плательщик", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("СчетПлательщика", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("Сумма", ОписаниеСуммы);
|
||||||
|
Строки.Колонки.Добавить("Назначение", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("Получатель", ОписаниеСтроки);
|
||||||
|
Строки.Колонки.Добавить("Статус", ОписаниеСтроки);
|
||||||
|
|
||||||
|
Возврат Строки;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает все xml-файлы реестров из каталога и добавляет их строки в общую таблицу.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Каталог - Строка - путь к каталогу с файлами реестров к платёжным поручениям.
|
||||||
|
// СтрокиРеестров - ТаблицаЗначений - таблица, созданная функцией НоваяТаблицаСтрок.
|
||||||
|
// Ошибки - Массив из Строка - в него добавляются сообщения о файлах, которые не удалось прочитать.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Структура - итоги чтения:
|
||||||
|
// * ОбработаноФайлов - Число - количество прочитанных файлов реестров;
|
||||||
|
// * ПропущеноФайлов - Число - количество файлов, которые не удалось прочитать.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ПрочитатьКаталогФайлов(Каталог, СтрокиРеестров, Ошибки)
|
||||||
|
|
||||||
|
Итоги = Новый Структура("ОбработаноФайлов, ПропущеноФайлов", 0, 0);
|
||||||
|
|
||||||
|
Попытка
|
||||||
|
Файлы = НайтиФайлы(Каталог, "*.xml");
|
||||||
|
Исключение
|
||||||
|
Ошибки.Добавить(СтрШаблон("Каталог %1 недоступен - %2", Каталог, ИнформацияОбОшибке().Описание));
|
||||||
|
Возврат Итоги;
|
||||||
|
КонецПопытки;
|
||||||
|
|
||||||
|
Для Каждого Файл Из Файлы Цикл
|
||||||
|
|
||||||
|
Если Файл.ЭтоКаталог() Тогда
|
||||||
|
Продолжить;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ПрочитатьФайл(Файл.ПолноеИмя, СтрокиРеестров, Ошибки) Тогда
|
||||||
|
Итоги.ОбработаноФайлов = Итоги.ОбработаноФайлов + 1;
|
||||||
|
Иначе
|
||||||
|
Итоги.ПропущеноФайлов = Итоги.ПропущеноФайлов + 1;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Возврат Итоги;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает один файл реестра к платёжному поручению на общую сумму с реестром.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// ИмяФайла - Строка - полный путь к файлу.
|
||||||
|
// СтрокиРеестров - ТаблицаЗначений - таблица, созданная функцией НоваяТаблицаСтрок.
|
||||||
|
// Ошибки - Массив из Строка - в него добавляются сообщения об ошибках чтения.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Булево - Истина, если файл прочитан как реестр.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ПрочитатьФайл(ИмяФайла, СтрокиРеестров, Ошибки)
|
||||||
|
|
||||||
|
ЧтениеXML = Новый ЧтениеXML;
|
||||||
|
|
||||||
|
Попытка
|
||||||
|
ЧтениеXML.ОткрытьФайл(ИмяФайла);
|
||||||
|
Исключение
|
||||||
|
Ошибки.Добавить(СтрШаблон("%1: файл не открыт - %2", ИмяФайлаИзПути(ИмяФайла), ИнформацияОбОшибке().Описание));
|
||||||
|
Возврат Ложь;
|
||||||
|
КонецПопытки;
|
||||||
|
|
||||||
|
Результат = Ложь;
|
||||||
|
|
||||||
|
Попытка
|
||||||
|
Результат = РазобратьРеестр(ЧтениеXML, ИмяФайла, СтрокиРеестров, Ошибки);
|
||||||
|
Исключение
|
||||||
|
Ошибки.Добавить(СтрШаблон("%1: ошибка разбора - %2", ИмяФайлаИзПути(ИмяФайла), ИнформацияОбОшибке().Описание));
|
||||||
|
КонецПопытки;
|
||||||
|
|
||||||
|
ЧтениеXML.Закрыть();
|
||||||
|
|
||||||
|
Возврат Результат;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Разбирает поток XML и добавляет строки реестра в общую таблицу.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// ЧтениеXML - ЧтениеXML - открытый поток чтения.
|
||||||
|
// ИмяФайла - Строка - путь к файлу, для сообщений об ошибках.
|
||||||
|
// СтрокиРеестров - ТаблицаЗначений - таблица, созданная функцией НоваяТаблицаСтрок.
|
||||||
|
// Ошибки - Массив из Строка - в него добавляются сообщения об ошибках.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Булево - Истина, если файл прочитан как реестр.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция РазобратьРеестр(ЧтениеXML, ИмяФайла, СтрокиРеестров, Ошибки)
|
||||||
|
|
||||||
|
Шапка = НоваяШапка();
|
||||||
|
СтрокиФайла = НоваяТаблицаСтрок();
|
||||||
|
|
||||||
|
Если Не ПрочитатьУзлы(ЧтениеXML, Шапка, СтрокиФайла) Тогда
|
||||||
|
Ошибки.Добавить(СтрШаблон("%1: пропущен, это не реестр к платёжному поручению", ИмяФайлаИзПути(ИмяФайла)));
|
||||||
|
Возврат Ложь;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
ДобавитьСтрокиФайла(СтрокиФайла, Шапка, ИмяФайла, СтрокиРеестров, Ошибки);
|
||||||
|
|
||||||
|
Возврат Истина;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает узлы XML, заполняя шапку реестра и строки файла.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// ЧтениеXML - ЧтениеXML - открытый поток чтения.
|
||||||
|
// Шапка - Структура - шапка реестра.
|
||||||
|
// СтрокиФайла - ТаблицаЗначений - строки текущего файла.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Булево - Истина, если корневой элемент соответствует реестру.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ПрочитатьУзлы(ЧтениеXML, Шапка, СтрокиФайла)
|
||||||
|
|
||||||
|
ЭтоРеестр = Ложь;
|
||||||
|
ТекущаяСтрока = Неопределено;
|
||||||
|
ИмяЭлемента = "";
|
||||||
|
|
||||||
|
Пока ЧтениеXML.Прочитать() Цикл
|
||||||
|
|
||||||
|
ТипУзла = ЧтениеXML.ТипУзла;
|
||||||
|
|
||||||
|
Если ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
||||||
|
|
||||||
|
ИмяЭлемента = ЧтениеXML.Имя;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "ProcessRegPayOrder" Тогда
|
||||||
|
ЭтоРеестр = Истина;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "RegPP" Тогда
|
||||||
|
ТекущаяСтрока = СтрокиФайла.Добавить();
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
ИначеЕсли ТипУзла = ТипУзлаXML.Текст Тогда
|
||||||
|
|
||||||
|
Значение = СокрЛП(ЧтениеXML.Значение);
|
||||||
|
|
||||||
|
Если ТекущаяСтрока = Неопределено Тогда
|
||||||
|
ЗаполнитьШапку(Шапка, ИмяЭлемента, Значение);
|
||||||
|
Иначе
|
||||||
|
ЗаполнитьСтроку(ТекущаяСтрока, Шапка, ИмяЭлемента, Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
ИначеЕсли ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
|
||||||
|
|
||||||
|
Если ЧтениеXML.Имя = "RegPP" Тогда
|
||||||
|
ТекущаяСтрока = Неопределено;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Возврат ЭтоРеестр;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Переносит строки файла в общую таблицу и сверяет их сумму с суммой платёжного поручения.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// СтрокиФайла - ТаблицаЗначений - строки текущего файла.
|
||||||
|
// Шапка - Структура - шапка реестра.
|
||||||
|
// ИмяФайла - Строка - путь к файлу, для сообщений об ошибках.
|
||||||
|
// СтрокиРеестров - ТаблицаЗначений - общая таблица строк реестров.
|
||||||
|
// Ошибки - Массив из Строка - в него добавляются сообщения об ошибках.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Процедура ДобавитьСтрокиФайла(СтрокиФайла, Шапка, ИмяФайла, СтрокиРеестров, Ошибки)
|
||||||
|
|
||||||
|
СуммаСтрок = 0;
|
||||||
|
|
||||||
|
Для Каждого СтрокаФайла Из СтрокиФайла Цикл
|
||||||
|
|
||||||
|
СтрокаФайла.Файл = ИмяФайлаИзПути(ИмяФайла);
|
||||||
|
СтрокаФайла.НомерПП = Шапка.НомерПП;
|
||||||
|
СтрокаФайла.ДатаПП = Шапка.ДатаПП;
|
||||||
|
СтрокаФайла.Получатель = Шапка.Получатель;
|
||||||
|
СуммаСтрок = СуммаСтрок + СтрокаФайла.Сумма;
|
||||||
|
|
||||||
|
НоваяСтрока = СтрокиРеестров.Добавить();
|
||||||
|
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаФайла);
|
||||||
|
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Если Шапка.СуммаПП <> 0 И СуммаСтрок <> Шапка.СуммаПП Тогда
|
||||||
|
Ошибки.Добавить(СтрШаблон("%1: сумма строк %2 не равна сумме платёжного поручения %3",
|
||||||
|
ИмяФайлаИзПути(ИмяФайла), Формат(СуммаСтрок, "ЧДЦ=2; ЧН=0"), Формат(Шапка.СуммаПП, "ЧДЦ=2; ЧН=0")));
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Возвращает пустую шапку платёжного поручения.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Структура - реквизиты шапки реестра.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция НоваяШапка()
|
||||||
|
|
||||||
|
Шапка = Новый Структура;
|
||||||
|
Шапка.Вставить("НомерПП", "");
|
||||||
|
Шапка.Вставить("ДатаПП", Дата(1, 1, 1));
|
||||||
|
Шапка.Вставить("СуммаПП", 0);
|
||||||
|
Шапка.Вставить("НазначениеПП", "");
|
||||||
|
Шапка.Вставить("Получатель", "");
|
||||||
|
Шапка.Вставить("Исполнитель", "");
|
||||||
|
Шапка.Вставить("Телефон", "");
|
||||||
|
|
||||||
|
Возврат Шапка;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Заполняет реквизит шапки по имени элемента XML.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Шапка - Структура - шапка реестра.
|
||||||
|
// ИмяЭлемента - Строка - имя элемента XML.
|
||||||
|
// Значение - Строка - текст элемента.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Процедура ЗаполнитьШапку(Шапка, ИмяЭлемента, Значение)
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "NOM_PP" Тогда
|
||||||
|
Шапка.НомерПП = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "DATE_PP" Тогда
|
||||||
|
Шапка.ДатаПП = РазобратьДату(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "SUM_PP" Тогда
|
||||||
|
Шапка.СуммаПП = РазобратьСумму(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "PURPOSE_PP" Тогда
|
||||||
|
Шапка.НазначениеПП = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "FIO_ISP" Тогда
|
||||||
|
Шапка.Исполнитель = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "TEL_ISP" Тогда
|
||||||
|
Шапка.Телефон = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Заполняет реквизит строки реестра по имени элемента XML.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Строка - СтрокаТаблицыЗначений - строка реестра.
|
||||||
|
// Шапка - Структура - шапка реестра, заполняется получателем средств.
|
||||||
|
// ИмяЭлемента - Строка - имя элемента XML.
|
||||||
|
// Значение - Строка - текст элемента.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Процедура ЗаполнитьСтроку(Строка, Шапка, ИмяЭлемента, Значение)
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "NAME_RCV" Тогда
|
||||||
|
Шапка.Получатель = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "NOM_LINE" И ЗначениеЗаполнено(Значение) Тогда
|
||||||
|
Строка.НомерСтроки = Число(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "NOM_PAY_DOC" Тогда
|
||||||
|
Строка.НомерРаспоряжения = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "DATE_PAY_DOC" Тогда
|
||||||
|
Строка.ДатаРаспоряжения = РазобратьДату(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "DATE_REESTR_PP" И Не ЗначениеЗаполнено(Строка.ДатаРаспоряжения) Тогда
|
||||||
|
Строка.ДатаРаспоряжения = РазобратьДату(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "SUM_REESTR_PP" Тогда
|
||||||
|
Строка.Сумма = РазобратьСумму(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "NAME_PLAT" Тогда
|
||||||
|
Строка.Плательщик = ИмяПлательщика(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "FIO_PLAT" И Не ЗначениеЗаполнено(Строка.Плательщик) Тогда
|
||||||
|
Строка.Плательщик = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "NOM_LS_PLAT" Тогда
|
||||||
|
Строка.СчетПлательщика = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "PURPOSE" Тогда
|
||||||
|
Строка.Назначение = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если ИмяЭлемента = "PAYSTATUS" Тогда
|
||||||
|
Строка.Статус = Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Извлекает имя плательщика из строки вида "ФИО//адрес//".
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Значение - Строка - значение элемента NAME_PLAT.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Строка - имя плательщика без адреса.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ИмяПлательщика(Значение)
|
||||||
|
|
||||||
|
Если Не ЗначениеЗаполнено(Значение) Тогда
|
||||||
|
Возврат "";
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Части = СтрРазделить(Значение, "//", Ложь);
|
||||||
|
|
||||||
|
Если Части.Количество() = 0 Тогда
|
||||||
|
Возврат "";
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Возврат СокрЛП(Части[0]);
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Преобразует сумму в копейках из файла в рубли.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Значение - Строка - значение элемента с суммой в копейках.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Число - сумма в рублях.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция РазобратьСумму(Значение)
|
||||||
|
|
||||||
|
Если Не ЗначениеЗаполнено(Значение) Тогда
|
||||||
|
Возврат 0;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
СтрокаСуммы = СтрЗаменить(СтрЗаменить(Значение, " ", ""), Символ(160), "");
|
||||||
|
|
||||||
|
Если Не СтрПодобнаПоРегулярномуВыражению(СтрокаСуммы, "^-?[0-9]+$") Тогда
|
||||||
|
Возврат 0;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Возврат Число(СтрокаСуммы) / 100;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Преобразует дату из формата ГГГГ-ММ-ДД в дату.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Значение - Строка - значение элемента с датой.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Дата - прочитанная дата, при ошибке - пустая дата.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция РазобратьДату(Значение)
|
||||||
|
|
||||||
|
ПустаяДата = Дата(1, 1, 1);
|
||||||
|
|
||||||
|
Если Не ЗначениеЗаполнено(Значение) Тогда
|
||||||
|
Возврат ПустаяДата;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Если Не СтрПодобнаПоРегулярномуВыражению(Значение, "^[0-9]{4}-[0-9]{2}-[0-9]{2}") Тогда
|
||||||
|
Возврат ПустаяДата;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Части = СтрРазделить(Значение, "-");
|
||||||
|
|
||||||
|
Попытка
|
||||||
|
Возврат Дата(Число(Части[0]), Число(Части[1]), Число(Лев(Части[2], 2)));
|
||||||
|
Исключение
|
||||||
|
Возврат ПустаяДата;
|
||||||
|
КонецПопытки;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Возвращает имя файла без пути.
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Путь - Строка - полный путь к файлу.
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Строка - имя файла с расширением.
|
||||||
|
//
|
||||||
|
&НаСервереБезКонтекста
|
||||||
|
Функция ИмяФайлаИзПути(Путь)
|
||||||
|
|
||||||
|
Части = СтрРазделить(Путь, ПолучитьРазделительПути());
|
||||||
|
|
||||||
|
Возврат Части[Части.Количество() - 1];
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<mdclass:ExternalDataProcessor xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="61a311a9-1805-4eac-9d9a-09162e9958b4">
|
||||||
|
<producedTypes>
|
||||||
|
<objectType typeId="f41ce4fe-2d25-4e4f-914e-be53ce98d993" valueTypeId="3e58cf5e-ff31-4485-a4ec-dee49878a22f"/>
|
||||||
|
</producedTypes>
|
||||||
|
<name>ПросмотрРеестровПлатежей</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Просмотр реестров платежей</value>
|
||||||
|
</synonym>
|
||||||
|
<containedObjects classId="c3831ec8-d8d5-4f93-8a22-f9bfae07327f" objectId="f05660b4-4ee8-43bd-9d49-f75b911cb5a8"/>
|
||||||
|
<defaultForm>ExternalDataProcessor.ПросмотрРеестровПлатежей.Form.Форма</defaultForm>
|
||||||
|
<forms uuid="65082154-b36d-4815-8818-6e5b9c5935d1">
|
||||||
|
<name>Форма</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Форма</value>
|
||||||
|
</synonym>
|
||||||
|
<usePurposes>PersonalComputer</usePurposes>
|
||||||
|
<usePurposes>MobileDevice</usePurposes>
|
||||||
|
</forms>
|
||||||
|
</mdclass:ExternalDataProcessor>
|
||||||
Reference in New Issue
Block a user