# Библиотека _treport_

## Назначение библиотеки

Библиотека _treport_ предназначена для формирования отчетов, имеющих исключительно табличное представление 
и фиксированное количество колонок. Результат формирования отчета выводится в формате _MS Excel_.

## Установка зависимостей

Для работы библиотеки требуется установить следующие пакеты:

- lxml >= 4.8.0
- Jinja2 >= 3.1.2
- openpyxl >= 3.0.10
- postgres >= 4.0

Файл, в котором хранится информация о все необходимых пакетах, можно скачать по [ссылке](https://github.com/novikov-nsa/treport/blob/master/requirements.txt).
Для установки всех требуемых пакетов необходимо выполнить команду

```bash
pip install -r requirements.txt
```

## Установка библиотеки

Установить библиотеку можно, выполнив команду

```bash
pip install treport
```
Или скачать проект с [GitHub](https://github.com/novikov-nsa/treport).

## Использование библиотеки

### Подготовительные мероприятия

Перед использованием библиотеки рекомендуется создать рабочий каталог, где будут размещаться файлы с SQL-запросами
к базе данных, шаблоны отчетных форм, описание параметров формирования отчетов, описание параметров подключения
к базе данных. Для удобства внутри рабочего каталога можно создать другие каталоги, где можно было бы размещать файлы
SQL-запросов, файлы шаблонов отчетов и т.п.

### Пример, демонстрирующий работу библиотеки

Пример, демонстрирующий работу библиотеки, можно увидеть, перейдя по [ссылке](https://github.com/novikov-nsa/treport/tree/master/treport_example). 
В качестве примера рабочего каталога был создан каталог ```treport_example```. Внутри него были размещены следующие файлы:

- ```run_report.xml```- декларативное описание параметров формирования отчетных форм;
- ```run_report.ini``` - ini-файл, в котором прописаны параметры подклбчения к базе данных и путь к файлу _run_report.xml_
- ```run_report.py``` - программа на языке программирования _Python_, демонстрирующая использование библиотеки.

Внутри каталога ```treport_example``` размещаются следующие каталоги:

- ```sql``` - каталог для хранения файлов с SQL-запросами, которые формируют контент отчета;
- ```templates``` - каталог для хранения файлов шаблонов отчетных форм;
- ```out``` - каталог для хранения файлов сформированных отчетов.

Для демонстрации работы библиотеки необходимо иметь возможность подключения к базе данных _PostgreSQL_. 
Необходимо создать таблицу ```documents```.

~~~sql
-- documents definition

CREATE TABLE documents (
	id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
	docnum varchar NOT NULL,
	docdate date NOT NULL,
	docsum numeric NOT NULL,
	docsum2 numeric NOT NULL
);
~~~
Содержимое таблицы представлено в файле [documents.csv](https://github.com/novikov-nsa/treport/blob/master/treport_example/documents.csv). 
Для импорта данных из CSV-файла необходимо выполнить команду

~~~sql
copy documents(docnum, docdate, docsum, docsum2) from '/path/to/documents.csv' delimiter ';' csv header;
~~~

### Подготовка шаблона отчета

Шаблон отчета- это файл в формате __xlsx__. Отчет может состоять из нескольких листов.
Нужно иметь в виду, что данная библиотека позволяет формировать отчетные формы, которые имеют
__исключительно табличный вид__. Отчет может содержать формулы MS Excel. В этом случае
необходимо в SQL-запросе предусмотреть выводить в данной колонке пустого значения, а 
XML-файле, описывающем свойства отчета, указать номера колонок, которые необходимо
игнорировать при формировании отчета. 

### Подготовка SQL-файла

Для получения данных из БД необходимо подготовить файл с SQL-запросом.
Для каждого листа отчета необходимо подготовить свой файл.
Если требуется формировать отчет по заданным параметрам, то необходимо чтобы
значения этих параметров были переданы в SQL-запрос. Для этого в тексте SQL-запроса
параметры обрамляются двойными фигурными скобками (например ```{{ p_start_date }}```).

### Подготовка ini-файла

Необходимо подготовить ini-файл, в котором описываются параметры подключение к базе данных и путь к декларативному
описанию свойств отчетов.

Пример ini-файла.

~~~ini
[database]
login = sergejnovikov
password =
port = 5432
host = localhost
database = postgres

[report]
params_reports = run_report.xml
~~~

Секция ```database```- описываются параметры подключения к БД.

Список параметров:

- ```login``` - имя пользователя для подключения к БД;
- ```password``` - пароль пользователя для подключения к БД;
- ```port``` - порт, по которому происходит подключение к БД;
- ```host``` - адрес хоста, на котором размещается СУБД PostgreSQL;
- ```database``` - наименование БД.

Секция ```report``` - описывает параметры отчетных форм.

В данной секции пока только один параметр- ```params_reports```. Значение параметра- путь к файлу, 
в котором приведено описание свойств отчетных форм.

### Декларативное описание отчета

Отчет состоит из двух основных частей- SQL-запроса к базе данных и шаблона, описывающего его внешний вид.

Для того чтобы библиотека понимала какие параметры допустимы для формирования отчета, какой шаблон использовать
для формирования отчета, какой SQL-запрос является источником данных для страницы отчета и т.д. необходимо 
описать характеристики отчетов.

Свойства отчета описываются в файле в формате XML. Правило описания свойства
отчетов приведено в [документации](https://github.com/novikov-nsa/treport/wiki/%D0%94%D0%B5%D0%BA%D0%BB%D0%B0%D1%80%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5-%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BE%D1%82%D1%87%D0%B5%D1%82%D0%B0).
Файл с [XSD-схемой](https://github.com/novikov-nsa/treport/blob/master/treport/treport.xsd) можно скачать со страницы проекта.

### Формирование отчета

#### С использованием программы на Pythonn

После того как подключение к БД настроено, разработаны SQL-запросы, подготовлен шаблон отчета,
можно приступить к написанию скрипта, который вызовет библиотеку и сформирует отчет.

~~~python
from treport.report import Report, get_config

if __name__ == '__main__':
    parameters = {'p_start_date': '01.05.2022', 'p_end_date': '31.05.2022'}
    db_url, path_to_params_reports_file = get_config('run_report.ini')
    report = Report('treport_example', path_to_params_reports_file, parameters, db_url)

    if report.isCorrect:
        report.contentReport.save(report.outDir + report.report_file_name)
        report.logger.info(f'Файл {report.outDir + report.report_file_name} сохранен')
~~~

В переменной ```parameters``` хранятся параметры формирования отчета
и их значения.

```db_url, path_to_params_reports_file = get_config('run_report.ini')``` - 
вызывается функция ```get_config```, аргумент функции- путь к ini-файлу, 
возвращается URL  подключения к БД и путь к XML-файлу, описывающему свойства
отчетов.

Далее создается объект ```report``. В конструктор класса передаются код формируемого отчета,
путь к XML-файлу, описывающему свойства отчетов, параметры формирования отчета и URL подключения к БД.

Далее происходит проверка на предмет того соответствует ли XML-файл XSD-схеме.
Если соответствует, то происходит сохранение файла отчета на файловую систему.

#### Из командной строки

Для формирования отчета из командной строки необходимо выолнить команду

```bash
python -m treport --report <код отчета> --config <ini-файл> --parameters-file <файл с параметрами отчета> --parameters <параметры отчета>
```

Аргументы командной строки:

```--help``` - выводит помощь с описанием списка аргументов;<br/>
```--report``` - код отчета, который необходимо сформировать;<br/>
```--config``` - наименование конфигурационного файла, если параметр не указан, то
в текущем каталоге ищется файл ```treport.ini```;<br/>
```--parameters-file``` - имя файла, в котором хранятся значения, в качестве разделителя 
используется символ "=";<br/>
```--parameters``` - список передаваемых параметров, указывается в кавычках,
в качестве разделителя используется символ ":".

__Пример 1__

```bash
python -m treport --report treport_example --parameters "p_start_date:01.04.2022;p_end_date:31.05.2022"
```

Будет сформирован отчет ```treport_example``` за период с 01.04.2022 по 31.05.2022,
параметры подключения к базе данных и имя XML-файла будут прочитаны из
файла ```treport.ini```. Если такой файл в рабочем каталоге будет отсутствовать,
то формирование отчета будет прервано.

__Пример 2__

```bash
python -m treport --report treport_example --config run_report.ini --parameters "p_start_date:01.04.2022;p_end_date:31.05.2022"
```

Параметры формирование отчета аналогичные параметрам в Примере 1, параметры подключения к базе данных и имя XML-файла будут прочитаны из
файла ```run_report.ini```.

__Пример 3__

```bash
python -m treport --report treport_example --parameters-file run_report_params.txt
```

Параметры подключения к базе данных и имя XML-файла будут прочитаны из
файла ```treport.ini```, параметры формирования отчета - из файла [```run_report_params.txt```](https://github.com/novikov-nsa/treport/blob/master/treport_example/run_report_params.txt).

__Пример 4__

```bash
python -m treport --report treport_example --parameters-file run_report_params.txt --parameters "p_end_date:31.05.2022"
```
Параметры подключения к базе данных и имя XML-файла будут прочитаны из
файла ```treport.ini```, параметры формирования отчета - из файла ```run_report_params.txt```,
но более приоритетным значением будет значение, указанное в качестве значения
параметра ```--parameters``` (дата окончания условий отбора будет установлена
"31.05.2022", вне зависимости от того, какой значенние этого параметра указано
в файле).

__Пример 5__

```bash
python -m treport --help
```

В результате выполннения команды бужет отображена следующая информация

```bash
usage: __main__.py [-h] [-c CONFIG] [-r REPORT] [-pf PARAMETERS_FILE] [-p PARAMETERS]

Программа предназначена для формирования отчетов, имеющих табличное представление

optional arguments:
  -h, --help            show this help message and exit
  -c CONFIG, --config CONFIG
                        Указывается путь конфигурационному файлу
  -r REPORT, --report REPORT
                        Код формируемого отчета
  -pf PARAMETERS_FILE, --parameters-file PARAMETERS_FILE
                        Файл с параметрами отчета
  -p PARAMETERS, --parameters PARAMETERS
                        Параметры отчета. Например: "param_name1:value_param1;param_name2:value_param2"
```