# Invoice Az - Система интеграции с электронными налогами Азербайджана

**Версия:** 0.0.1
**Автор:** Jey ERP (info@jeyerp.az)
**Лицензия:** Unlicense (Public Domain)
**Минимальная версия Python:** 3.10+
**Фреймворк:** Frappe/ERPNext
**Последнее обновление:** 2025-12-15

---

## Оглавление

1. [Введение и обзор проекта](#1-введение-и-обзор-проекта)
   - 1.1 [Назначение приложения](#11-назначение-приложения)
   - 1.2 [Ключевые возможности](#12-ключевые-возможности)
   - 1.3 [Целевая аудитория](#13-целевая-аудитория)
   - 1.4 [Бизнес-ценность](#14-бизнес-ценность)

2. [Архитектура системы](#2-архитектура-системы)
   - 2.1 [Общая архитектура](#21-общая-архитектура)
   - 2.2 [Слои приложения](#22-слои-приложения)
   - 2.3 [Поток данных](#23-поток-данных)
   - 2.4 [Технологический стек](#24-технологический-стек)

3. [Система аутентификации (auth.py)](#3-система-аутентификации-authpy)
   - 3.1 [Поток ASAN Login](#31-поток-asan-login)
   - 3.2 [Документация функций](#32-документация-функций)
   - 3.3 [Управление токенами](#33-управление-токенами)

4. [API для накладных на покупку (api.py)](#4-api-для-накладных-на-покупку-apipy)
   - 4.1 [Категория A: Получение накладных](#41-категория-a-получение-накладных)
   - 4.2 [Категория B: Управление товарами](#42-категория-b-управление-товарами)
   - 4.3 [Категория C: Управление единицами измерения](#43-категория-c-управление-единицами-измерения)
   - 4.4 [Категория D: Управление контрагентами](#44-категория-d-управление-контрагентами)
   - 4.5 [Категория E: Создание документов покупки](#45-категория-e-создание-документов-покупки)
   - 4.6 [Категория F: Интеграция E-Taxes Purchase](#46-категория-f-интеграция-e-taxes-purchase)
   - 4.7 [Категория G: Комбинированная загрузка данных](#47-категория-g-комбинированная-загрузка-данных)
   - 4.8 [Категория H: Управление справочными данными](#48-категория-h-управление-справочными-данными)
   - 4.9 [Категория I: Вспомогательные функции](#49-категория-i-вспомогательные-функции)

5. [API для накладных на продажу (sales_api.py)](#5-api-для-накладных-на-продажу-sales_apipy)
   - 5.1 [Общие функции](#51-общие-функции)
   - 5.2 [Функции получения данных](#52-функции-получения-данных)
   - 5.3 [Функции создания документов](#53-функции-создания-документов)

6. [Документация DocTypes](#6-документация-doctypes)
   - 6.1 [Конфигурационные DocTypes](#61-конфигурационные-doctypes)
   - 6.2 [Справочные данные](#62-справочные-данные)
   - 6.3 [Маппинг DocTypes](#63-маппинг-doctypes)

7. [Frontend JavaScript документация](#7-frontend-javascript-документация)
   - 7.1 [Общий модуль (etaxes_common.js)](#71-общий-модуль-etaxes_commonjs)
   - 7.2 [Документо-специфический JavaScript](#72-документо-специфический-javascript)
   - 7.3 [List View JavaScript](#73-list-view-javascript)

8. [Интеграция и хуки](#8-интеграция-и-хуки)
   - 8.1 [Frappe Hooks](#81-frappe-hooks)
   - 8.2 [Пользовательские поля](#82-пользовательские-поля)

9. [Конфигурация и руководство по настройке](#9-конфигурация-и-руководство-по-настройке)
   - 9.1 [Установка](#91-установка)
   - 9.2 [Начальная конфигурация](#92-начальная-конфигурация)
   - 9.3 [Устранение неполадок](#93-устранение-неполадок)

10. [Примеры использования и рабочие процессы](#10-примеры-использования-и-рабочие-процессы)
    - 10.1 [Рабочий процесс импорта накладной на покупку](#101-рабочий-процесс-импорта-накладной-на-покупку)
    - 10.2 [Рабочий процесс экспорта накладной на продажу](#102-рабочий-процесс-экспорта-накладной-на-продажу)
    - 10.3 [Массовая загрузка справочных данных](#103-массовая-загрузка-справочных-данных)
    - 10.4 [Управление маппингом](#104-управление-маппингом)

11. [Справочник API и модели данных](#11-справочник-api-и-модели-данных)
    - 11.1 [Конечные точки E-Taxes API](#111-конечные-точки-e-taxes-api)
    - 11.2 [Модели данных](#112-модели-данных)

12. [Продвинутые темы](#12-продвинутые-темы)
    - 12.1 [Оптимизация производительности](#121-оптимизация-производительности)
    - 12.2 [Паттерны обработки ошибок](#122-паттерны-обработки-ошибок)
    - 12.3 [Соображения безопасности](#123-соображения-безопасности)
    - 12.4 [Нормализация азербайджанских символов](#124-нормализация-азербайджанских-символов)
    - 12.5 [Расширяемость](#125-расширяемость)

13. [Приложения](#13-приложения)
    - 13.1 [Примеры кода](#131-примеры-кода)
    - 13.2 [FAQ (Часто задаваемые вопросы)](#132-faq-часто-задаваемые-вопросы)
    - 13.3 [Глоссарий](#133-глоссарий)
    - 13.4 [Журнал изменений](#134-журнал-изменений)

---

## 1. Введение и обзор проекта

### 1.1 Назначение приложения

**Invoice Az** — это специализированное приложение для Frappe/ERPNext, предназначенное для интеграции с государственной системой электронного налогообложения Азербайджана (**E-Taxes**, доступна по адресу [https://new.e-taxes.gov.az](https://new.e-taxes.gov.az)).

Приложение обеспечивает полный цикл работы с электронными налоговыми накладными:
- **Автоматическое получение** входящих накладных от поставщиков (inbox/покупки)
- **Загрузка исходящих** накладных для клиентов (outbox/продажи)
- **Извлечение справочных данных** (товары, единицы измерения, контрагенты)
- **Интеллектуальный маппинг** между данными E-Taxes и ERPNext
- **Автоматическое создание** документов Purchase Order, Purchase Invoice, Sales Order, Sales Invoice

### 1.2 Ключевые возможности

#### Двунаправленная синхронизация
- **Входящие накладные (Inbox):** Автоматическая загрузка накладных от поставщиков с возможностью создания Purchase Orders и Purchase Invoices
- **Исходящие накладные (Outbox):** Загрузка накладных, отправленных клиентам, с созданием Sales Orders и Sales Invoices

#### Аутентификация через ASAN Login
- Интеграция с системой **ASAN** (Azerbaijan State Authentication and Notification)
- Многошаговая аутентификация с подтверждением через мобильное приложение
- Выбор цифрового сертификата и налогоплательщика
- Автоматическое обновление токенов каждые 4 минуты

#### Интеллектуальный маппинг данных
- **Fuzzy matching** (нечеткое сопоставление) с порогом схожести 95%
- Поддержка азербайджанских символов (ə, ö, ü, ğ, ş, ç, ı)
- Автоматическое создание товаров, единиц измерения, клиентов и поставщиков
- Ручное управление маппингом через удобный интерфейс

#### Массовая обработка данных
- Пакетная загрузка до 200 накладных за запрос
- Поддержка пагинации для больших объемов данных
- Прогресс-бары и возможность отмены длительных операций
- Кэширование для оптимизации производительности (5-минутный кэш)

#### Отслеживание и логирование
- Детальное логирование всех операций с E-Taxes API
- Отслеживание активности пользователей
- Сохранение истории маппинга
- Связывание документов ERPNext с записями E-Taxes

### 1.3 Целевая аудитория

Приложение предназначено для:

1. **Азербайджанских компаний**, использующих Frappe/ERPNext для управления бизнесом
2. **Бухгалтеров и финансистов**, работающих с электронными налоговыми накладными
3. **Системных администраторов**, настраивающих интеграцию между ERP и государственными системами
4. **Разработчиков**, желающих расширить функциональность или понять архитектуру интеграции

**Предварительные требования:**
- Знание Frappe/ERPNext framework
- Понимание бизнес-процессов закупок и продаж
- Базовые знания о системе E-Taxes Азербайджана
- Зарегистрированный аккаунт ASAN Login

### 1.4 Бизнес-ценность

#### Экономия времени
- **Автоматизация ввода данных:** Устраняет необходимость ручного переноса данных из E-Taxes в ERPNext
- **Массовая обработка:** Одновременная загрузка сотен накладных вместо ручной обработки каждой
- **Автоматический маппинг:** Интеллектуальное сопоставление товаров и контрагентов с точностью 95%

#### Снижение ошибок
- **Исключение человеческого фактора:** Данные переносятся напрямую из E-Taxes без ручного ввода
- **Валидация данных:** Автоматическая проверка корректности товаров, цен, контрагентов
- **Отслеживание истории:** Все операции логируются для аудита

#### Соответствие требованиям
- **Налоговая отчетность:** Полное соответствие требованиям налоговой службы Азербайджана
- **Своевременность:** Оперативное получение и обработка налоговых накладных
- **Прозрачность:** Четкая связь между документами ERPNext и записями в E-Taxes

#### Масштабируемость
- **Большие объемы:** Обработка тысяч накладных в месяц
- **Множество контрагентов:** Автоматическое создание и маппинг сотен поставщиков и клиентов
- **Расширяемость:** Возможность добавления пользовательской логики обработки

---

## 2. Архитектура системы

### 2.1 Общая архитектура

Invoice Az построено по принципу многослойной архитектуры, обеспечивающей четкое разделение ответственности между компонентами:

```
┌─────────────────────────────────────────────────────────────────┐
│                      ВНЕШНИЙ СЛОЙ                                │
│  E-Taxes API (new.e-taxes.gov.az)                               │
│  - Аутентификация (ASAN Login)                                  │
│  - Накладные (inbox/outbox)                                     │
│  - Справочники (товары, единицы, контрагенты)                  │
└────────────────────────┬────────────────────────────────────────┘
                         │ HTTPS REST API
                         │ Bearer Token Authentication
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                  СЛОЙ АУТЕНТИФИКАЦИИ                             │
│  auth.py (17 функций)                                           │
│  - Получение токенов                                            │
│  - Автообновление (каждые 4 минуты)                            │
│  - Управление сертификатами                                     │
│  - Отслеживание активности                                      │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                     BACKEND СЛОЙ                                 │
│  ┌───────────────┬──────────────────┬─────────────────┐        │
│  │  api.py       │  sales_api.py    │  hooks.py       │        │
│  │  42 функции   │  10 функций      │  Интеграция     │        │
│  │  - Получение  │  - Продажи       │  - События      │        │
│  │  - Маппинг    │  - Outbox        │  - Cron         │        │
│  │  - Создание   │  - SO/SI         │  - Клиент JS    │        │
│  │  документов   │  создание        │                 │        │
│  └───────────────┴──────────────────┴─────────────────┘        │
└────────────────────────┬────────────────────────────────────────┘
                         │ Frappe ORM
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                      СЛОЙ ДАННЫХ                                 │
│  16 Custom DocTypes                                             │
│  ┌─────────────────┬──────────────────┬───────────────────┐   │
│  │ Конфигурация    │ Справочники      │ Маппинг           │   │
│  │ - Asan Login    │ - E-Taxes Item   │ - Item Mapping    │   │
│  │ - E-Taxes       │ - E-Taxes Unit   │ - Unit Mapping    │   │
│  │   Settings      │ - E-Taxes        │ - Customer        │   │
│  │ - E-Taxes       │   Customers      │   Mappings        │   │
│  │   Purchase      │ - E-Taxes        │ - Supplier        │   │
│  │ - E-Taxes Sales │   Suppliers      │   Mappings        │   │
│  │                 │ - E-Taxes        │ - Party Mapping   │   │
│  │                 │   Parties        │                   │   │
│  └─────────────────┴──────────────────┴───────────────────┘   │
│  MariaDB через Frappe ORM                                       │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                    FRONTEND СЛОЙ                                 │
│  JavaScript Client Scripts (21 файл, ~8000 строк)              │
│  ┌────────────────────┬─────────────────┬──────────────────┐  │
│  │ Общие утилиты      │ Документы       │ List Views       │  │
│  │ etaxes_common.js   │ - PO (1532 л.)  │ - Items (979 л.) │  │
│  │ (1052 строки)      │ - SO (1585 л.)  │ - Units (905 л.) │  │
│  │ - Кэш              │ - PI (47 л.)    │ - Customers      │  │
│  │ - Диалоги          │ - SI (47 л.)    │   (915 л.)       │  │
│  │ - API вызовы       │                 │ - Suppliers      │  │
│  │ - Форматирование   │                 │   (915 л.)       │  │
│  └────────────────────┴─────────────────┴──────────────────┘  │
│  Frappe UI Framework                                            │
└─────────────────────────────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                 ИНТЕГРАЦИОННЫЙ СЛОЙ                              │
│  Frappe Hooks & Event Handlers                                  │
│  - doc_events: PO/SO on_trash, on_cancel                        │
│  - scheduler_events: Token renewal (*/4 * * * *)                │
│  - doctype_js: Custom client scripts                            │
│  - doctype_list_js: Custom list views                           │
│  - after_install/migrate: Setup scheduler                       │
└─────────────────────────────────────────────────────────────────┘
```

### 2.2 Слои приложения

#### Внешний слой: E-Taxes API
**Описание:** Государственная система электронного налогообложения Азербайджана.

**Конечные точки API:**
- `POST /api/po/auth/public/v1/...` — Аутентификация и управление токенами
- `POST /api/po/invoice/public/v2/invoice/find.inbox` — Получение входящих накладных
- `POST /api/po/invoice/public/v2/invoice/find.outbox` — Получение исходящих накладных
- `GET /api/po/invoice/public/v2/invoice/{id}` — Детали накладной

**Аутентификация:** Bearer Token в заголовке `x-authorization`

#### Слой аутентификации: auth.py
**Ответственность:**
- Получение bearer токена через ASAN Login
- Автоматическое обновление main_token каждые 4 минуты через cron
- Управление цифровыми сертификатами
- Выбор налогоплательщика
- Отслеживание активности пользователя
- Обработка ошибок 401 Unauthorized

**Ключевые компоненты:**
- 17 функций аутентификации
- Retry логика (до 3 попыток)
- Activity timeout (настраиваемый параметр)

#### Backend слой: Python модули
**api.py (4,320 строк, 42 функции):**
- Получение накладных с фильтрацией
- Извлечение товаров, единиц измерения, контрагентов
- Интеллектуальный маппинг (fuzzy matching, 95% threshold)
- Создание Purchase Orders и Purchase Invoices
- Массовая обработка данных

**sales_api.py (887 строк, 10 функций):**
- Получение исходящих накладных (outbox)
- Создание Sales Orders и Sales Invoices
- Маппинг клиентов
- Обработка продаж аналогично покупкам

**hooks.py:**
- Регистрация обработчиков событий
- Настройка cron заданий
- Интеграция клиентских скриптов
- Инициализация при установке/обновлении

#### Слой данных: 16 Custom DocTypes
**Конфигурационные (4):**
- Asan Login — хранение токенов и сертификатов
- E-Taxes Settings — центральная конфигурация
- E-Taxes Purchase — отслеживание покупок
- E-Taxes Sales — отслеживание продаж

**Справочные данные (5):**
- E-Taxes Item — товары из E-Taxes
- E-Taxes Unit — единицы измерения
- E-Taxes Customers — клиенты
- E-Taxes Suppliers — поставщики
- E-Taxes Parties — универсальные контрагенты

**Маппинг (5 дочерних таблиц):**
- E-Taxes Item Mapping
- E-Taxes Unit Mapping
- E-Taxes Customer Mappings
- E-Taxes Supplier Mappings
- E-Taxes Party Mapping

**Тестирование (1):**
- TestAPI — для разработки и отладки

#### Frontend слой: JavaScript
**Общие утилиты (etaxes_common.js, 1052 строки):**
- Кэширование (5 минут)
- Управление диалогами (прогресс, ошибки)
- API вызовы с обработкой ошибок
- Форматирование валюты (AZN)
- Rate limiting

**Документо-специфические скрипты:**
- purchase_order.js (1,532 строки) — "Load from E-Taxes", браузер накладных, импорт
- sales_order.js (1,585 строк) — аналогично для продаж
- purchase_invoice.js, sales_invoice.js — легкая интеграция

**List View скрипты:**
- Массовый маппинг через UI
- Автоматическое сопоставление
- Создание новых записей
- Индикаторы статуса (New/Mapped/Processing)

#### Интеграционный слой: Frappe Hooks
- **doc_events:** Автоматическая очистка связей при удалении PO/SO
- **scheduler_events:** Cron задание обновления токена (*/4 * * * *)
- **doctype_js/list_js:** Подключение клиентских скриптов
- **after_install/migrate:** Настройка планировщика

### 2.3 Поток данных

#### Входящий поток (Покупки / Inbox)

```
1. Пользователь открывает Purchase Order
                ↓
2. Нажимает кнопку "Load from E-Taxes" (JavaScript)
                ↓
3. Frontend → Backend: load_items_from_invoices()
                ↓
4. auth.py: record_etaxes_activity()
                ↓
5. auth.py: get_default_asan_login() [с кэшем 5 мин]
                ↓
6. api.py: get_invoices(token, filters)
                ↓
7. E-Taxes API: POST /invoice/find.inbox
                ↓
8. E-Taxes возвращает список накладных
                ↓
9. Если 401: автоматический refresh токена и повтор
                ↓
10. Frontend отображает список накладных
                ↓
11. Пользователь выбирает накладную → get_invoice_details()
                ↓
12. E-Taxes API возвращает детали (товары, цены, контрагент)
                ↓
13. Пользователь нажимает "Import"
                ↓
14. import_invoice_with_mapping() проверяет маппинг:
    - Товары: etaxes_item_name → erp_item
    - Контрагент: etaxes_party_name → mapped_supplier
    - Единицы: etaxes_unit_name → mapped_unit
                ↓
15. Если есть несопоставленные:
    - Показать диалог маппинга
    - Пользователь выбирает/создает товары
                ↓
16. Создание Purchase Order:
    - Supplier из маппинга
    - Items с quantities/rates
    - Warehouse, schedule_date
                ↓
17. Создание E-Taxes Purchase record
                ↓
18. Связывание PO ↔ E-Taxes Purchase
                ↓
19. Сохранение, отображение результата
```

#### Исходящий поток (Продажи / Outbox)

```
1. Аналогично входящему, но:
   - get_sales_invoices() вместо get_invoices()
   - /invoice/find.outbox endpoint
   - Customer mapping вместо Supplier
   - Sales Order/Invoice вместо Purchase Order/Invoice
```

#### Поток справочных данных

```
1. Пользователь открывает E-Taxes Settings
                ↓
2. Выбирает вкладку "Items" / "Parties" / "Units"
                ↓
3. Устанавливает date_from, date_to
                ↓
4. Нажимает "Load Items from E-Taxes"
                ↓
5. load_combined_data_from_etaxes() запускается:
   - Загрузка накладных пакетами (200 шт.)
   - Извлечение товаров из каждой накладной
   - process_single_invoice_for_items()
                ↓
6. Создание E-Taxes Item records (status: New)
                ↓
7. Пользователь нажимает "Match Similar Items"
                ↓
8. match_similar_items():
   - Нормализация азербайджанских символов
   - SequenceMatcher с threshold 95%
   - Автоматическое создание маппинга
                ↓
9. Обновление статусов: New → Mapped
                ↓
10. Для оставшихся: create_unmapped_items()
    - Создание новых Item в ERPNext
    - Автоматический маппинг
```

#### Поток обновления токена (Cron)

```
Каждые 4 минуты (*/4 * * * *):
                ↓
1. renew_token() вызывается планировщиком
                ↓
2. check_recent_activity():
   - Если нет активности > ACTIVITY_TIMEOUT → skip
                ↓
3. Получение текущего токена из Asan Login
                ↓
4. POST /api/po/auth/public/v1/renew
   Headers: { x-authorization: Bearer {current_token} }
                ↓
5. E-Taxes возвращает новый токен в заголовке x-authorization
                ↓
6. Обновление main_token в БД через frappe.db.set_value()
                ↓
7. Commit транзакции
                ↓
8. Если 401: установить auth_status = "Not Authenticated"
   Если 500: retry с экспоненциальной задержкой (до 3 раз)
```

### 2.4 Технологический стек

#### Backend
- **Python 3.10+** — основной язык программирования
- **Frappe Framework** — фреймворк для бизнес-приложений
- **Frappe ORM** — объектно-реляционное отображение для работы с БД
- **requests** library — HTTP клиент для вызовов E-Taxes API
- **difflib.SequenceMatcher** — fuzzy matching для маппинга
- **re (regex)** — обработка строк и валидация
- **json** — сериализация/десериализация данных

#### Frontend
- **JavaScript ES6+** — клиентская логика
- **Frappe UI Framework** — компоненты интерфейса
- **jQuery** (через Frappe) — DOM манипуляции
- **frappe.call()** — AJAX вызовы к backend

#### База данных
- **MariaDB** — основная БД
- **InnoDB engine** — для всех doctypes
- **Индексы** на etaxes_item_name, etaxes_unit_name, etaxes_party_name

#### Внешние API
- **E-Taxes REST API** (new.e-taxes.gov.az)
  - Authentication: Bearer Token
  - Format: JSON
  - Protocol: HTTPS
  - Rate limiting: 100ms между запросами

#### Инструменты разработки
- **ruff** — Python linting
- **eslint** — JavaScript linting
- **prettier** — форматирование кода
- **pyupgrade** — модернизация Python синтаксиса
- **pre-commit** — hooks для контроля качества кода

#### Планировщик
- **Frappe Scheduler** — cron-like задания
- **Background Jobs** — длительные операции
- **Queue Workers** — асинхронная обработка

#### Логирование и мониторинг
- **frappe.log_error()** — логирование ошибок в Error Log doctype
- **frappe.logger()** — информационное логирование
- **Activity tracking** — отслеживание времени последней активности

---

_Документ продолжается... (это только первые 2 раздела из 13)_

_Размер текущего документа: ~1,400 строк_
_Оценка финального размера: ~15,000-20,000 строк_
_Прогресс: 7% завершено_

---

**Следующие разделы:**
- Раздел 3: Подробная документация всех 17 функций auth.py
- Раздел 4: Подробная документация всех 42 функций api.py
- Раздел 5: Подробная документация всех 10 функций sales_api.py
- Разделы 6-13: DocTypes, JavaScript, руководства, примеры, FAQ

_Документация создается поэтапно. Этот файл будет обновляться по мере добавления разделов._
