[содержание](/readme.md)  

# Практическое задание: Создание распределенной системы оплаты услуг

Система оплаты состоит из нескольких независимых участников:
* *потребитель* услуг
* *поставщик* услуг
* *процессинговый* центр
* *агент* (терминалы оплаты)

Краткое описание системы: независимые *поставщики* услуг (Мегафон, ТЕЛЕ2, Эр-телеком...) заключают договора с *потребителями* (физические лица). Для облегчения оплаты услуг существуют независимые *процессинговые* центры (Киберплат, ОСМП) и подключенные к ним *агенты* с терминалами оплаты.

Технические задания на элементы системы:

>- для всех обязательное **логгирование**, **тестирование** и **документирование**;
>- визуальный интерфейс это окно, нарисованное с помощью tkinter или PyQT (можно использовать и другие библиотеки)
>- хранение данных: JSON, SQLite...
>- POST-запросы отправляются с помощью модуля **requests** (примеры есть в лекциях)
>- пример простого HTTP-сервера с базовой авторизацией есть в лекциях
>- весь обмен по HTTP с Basic Authentication (базовой авторизацией)

**Потребитель**
* заключает договора (получает номер телефона или договора, УРЛ для получения услуги и протокол взаимодействия) с произвольным количеством *поставщиков*
* в **визуальном интерфейсе** ведет список договоров (добавление/редактирование/удаление) и эмулирует пользование услугами (кнопочки "позвонить"/"выйти в интернет" в зависимости от выбранного *поставщика*). Для эмуляции пользования услугой соответствующему *поставщику* отправляется **POST-запрос** (параметры задаются при заключении договора).
* **хранит данные** о договорах в файле

**Поставщик**
* предоставляет **визуальный интерфейс** для заключения договора с *потребителем* (получить ФИО, паспорт, е-майл; выдать уникальный идентификатор (телефон/договор), УРЛ и протокол обмена)
* **хранит данные** поставищиков в базе данных
* заключает договор на оплату услуг с произвольным количеством **процессинговых центров** (предоставляет УРЛ своего HTTP-сервера, логин/пароль для авторизации, поля для заполнения при оплате с регулярными выражениями для проверки)
* **HTTP-сервер** для эмуляции оказания услуг *потребителям* (все транзакции сохраняются в базе данных) и проверки наличия телефона/номера *процессинговым центром* (логгируются)
* дополнительно: формирование отчета по оказанным услугам в Excel и отправка на электронную почту *потребителя*

**Процессинговый центр**
* предоставляет **визуальный интерфейс** для заключения договора с *поставщиками* (получить УРЛ, логин/пароль для авторизации, протокол обмена для проверки номера и зачисления баланса, поля с регулярками) и *агентами* (предоставить уникальный номер договора, логин/пароль доступа к процессингу, протокол обмена, задать комиссию процессинга, пополнить баланс)
* **хранит данные** о *поставщиках*, *агентах* и транзакциях в базе данных
* **HTTP-сервер** для приема запросов от *агентов*
* **POST-запросы** *поставщикам* 
    * проксирование запросов проверки номера
    * зачисление баланса (заворачивать в транзакцию)
* дополнительно: отчеты итоговые и по транзакциям в Excel для *поставщиков* и *агентов*

**Агенты**
* заключение договора с *процессингом* (получение УРЛа, логина/пароля...)
* **Визуальный интерфейс** (обязательно на CEF) для эмуляции оплаты *потребителем*
* **POST-запросы** *процессингу*
    * получение списка *поставщиков* с реквизитами для оплаты (раз в 30 мин)
    * получение баланса агента раз в 5 мин (при нулевом балансе блокировать работу терминала)
    * проверка номера перед оплатой
    * транзакция после оплаты (номер, сумма...), с учетом комиссии агента
* **хранить данные** о транзакциях в базе данных
* дополнительно: подключить реальный купюроприемник CashCode CCNET (реализовать протокол обмена по СОМ-порту и события приема денег)

# ЧТО ДЕЛАТЬ?

* установите Python, Visual Studio Code (VSC)
* создайте на диске папку для проекта
* в VSC откройте папку проекта и создайте в ней файл test.py
* следуя подсказкам VSC установите расширение для Питона и линтер
* творите...

# Как установить Qt Designer
В лекциях написана команда ``pip install pyqt5``, но она устанавливает только фреймворк, для установки designer-а установите ``pip install pyqt5-tools``
          
На некоторых компьютерах может выдать ошибку "недостаточно прав", там же будет и подсказка, что установить можно только для текущего пользователя с ключом --user

``pip install pyqt5-tools --user``

# Динамическое создание класса
При реализации процессинга возник вопрос как работать с поставщиками (список поставщиков динамический и заранее неизвестно название класса)

Родил такую иерархию:

* классы поставщиков лежат в подкаталоге providers
```
providers\
  beeline.py
  mts.py
```
* подкаталог providers оформлен как модуль, для этого в него добавляется служебный файл ``__init__.py``, в котором для каждого отлаженного поставщика добавляется импорт

```py
#__init__.py
from providers.beeline import Beeline
...
```

* теперь в основном модуле мы просто импортируем все объекты из модуля providers и при этом классы, которые мы импортировали в ``__init__.py``, попадают в глобальную область видимости и мы можем создавать экземпляры нужных классов:

```py
# main.py
from providers import *

if __name__ == "__main__":
  # название класса поставщика мы берем из базы или конфига, главное что здесь он в виде строки
  provider_name = 'Beeline'  
  #globals() возвращает список объектов
  provider = globals()[provider_name]()
```


[содержание](/readme.md)  
