invoice_az/BUGS_VAT_OPERATIONS.md

360 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Статус исправления багов VAT Operations Import
**Дата:** 2026-01-13
**Статус лимита токенов:** ~73K остаток
---
## ✅ ИСПРАВЛЕНО И РАБОТАЕТ
### БАГ 1: Фильтрация операций (income без expense)
**Статус:** ✅ РАБОТАЕТ
**Исправление:** Добавлена фильтрация в `vat_api.py` в функцию `get_vat_operations()` (строки 124-143)
**Проверено:** Пользователь подтвердил - фильтр работает
---
## ❌ НЕ РАБОТАЕТ / ЕСТЬ ПРОБЛЕМЫ
### БАГ 2: Визуальные баги (прогресс-бар, алерты)
**Статус:** ⚠️ ЧАСТИЧНО (требует проверки после bench build)
**Что исправлено в коде:**
- `journal_entry.js` строка 1198: `currentIndex - 1``currentIndex`
- `journal_entry.js` строки 1237-1239: убраны индивидуальные `frappe.show_alert()` во время импорта
**Почему может не работать:**
- Нужно выполнить `bench build --app invoice_az` чтобы скомпилировать JavaScript
- Нужно обновить страницу в браузере (Ctrl+F5)
**Проблема:** Пользователь не проверял после исправлений
---
### БАГ 3: Детальные ошибки не отображаются
**Статус:** ❌ НЕ РАБОТАЕТ
**Проблема:** При "Import Completed with Errors" нет информации о том, что именно пошло не так
**Что исправлено в коде:**
1. **vat_api.py** (строки 489-513): Добавлены поля `tin`, `customer_name`, `income`, `operation_date`, `operation_type`, `account_number`, `missing_tin` в errors
2. **journal_entry.js** (строка 1242): Изменено с `VATETaxes.errors.add(operation, error.error_type, error.message)` на `VATETaxes.errors.add(operation, error.error_type, error.message, error)` - передается полный объект
3. **journal_entry.js** (строки 628-654): Добавлено отображение Amount, Customer Name, Missing Account, Missing TIN
**Почему не работает:**
- JavaScript не пересобран: нужен `bench build --app invoice_az`
- Кэш браузера: нужен Ctrl+F5
**Как проверить что работает:**
1. Импортировать операцию с несуществующим TIN
2. Кликнуть "View Error Details"
3. Должны видеть:
- **Amount:** сумма в AZN
- **Customer Name:** название клиента из операции
- **Missing TIN:** TIN который не найден
- **Missing Account:** номер счета (226 или 211) который отсутствует
---
### БАГ 4: ПАРАДОКС УДАЛЕНИЯ (КРИТИЧЕСКАЯ ПРОБЛЕМА!)
**Статус:** 🔴 КРИТИЧЕСКИЙ БАГ - СОЗДАН DEADLOCK
**Проблема:**
1. Нельзя удалить **E-Taxes VAT Operations** → выходит ошибка "Cannot delete... because it is linked with Journal Entry"
2. Нельзя удалить **Journal Entry** → при попытке удалить JE, система пытается удалить связанный E-Taxes VAT Operations
3. E-Taxes VAT Operations выбрасывает ошибку из `on_trash()` → удаление JE прерывается
4. **РЕЗУЛЬТАТ: Невозможно удалить ни JE, ни VAT Operations!**
**Текущий код:**
**e_taxes_vat_operations.py** (строки 10-19):
```python
def on_trash(self):
"""Защита от удаления если связано с Journal Entry"""
if self.journal_entry:
# Проверяем, существует ли Journal Entry
if frappe.db.exists("Journal Entry", self.journal_entry):
frappe.throw(
_("Cannot delete or cancel E-Taxes VAT Operations {0} because it is linked with Journal Entry {1}").format(
self.name,
self.journal_entry
)
)
```
**vat_operations.py** (строки 28-34):
```python
# Удаляем с force=True чтобы обойти before_delete()
frappe.delete_doc(
'E-Taxes VAT Operations',
record.name,
ignore_permissions=True,
force=True # ⚠️ НЕ ОБХОДИТ on_trash!!!
)
```
**ПРОБЛЕМА:** `force=True` игнорирует только permissions, но **НЕ** игнорирует `on_trash()`!
---
## 🔧 РЕШЕНИЯ ДЛЯ БАГА 4 (ПАРАДОКС УДАЛЕНИЯ)
### Вариант 1: Использовать frappe.db.delete() (РЕКОМЕНДУЕТСЯ)
**Изменить `vat_operations.py`:**
```python
# ВМЕСТО:
frappe.delete_doc('E-Taxes VAT Operations', record.name, ignore_permissions=True, force=True)
# ИСПОЛЬЗОВАТЬ:
frappe.db.delete('E-Taxes VAT Operations', {'name': record.name})
frappe.db.commit()
```
**Плюсы:**
- Прямое удаление из БД, обходит все хуки
- Простое и надежное
**Минусы:**
- Не запускает cascade delete для связанных документов (но у VAT Operations нет связанных)
---
### Вариант 2: Проверка контекста в on_trash()
**Изменить `e_taxes_vat_operations.py`:**
```python
def on_trash(self):
"""Защита от удаления если связано с Journal Entry"""
# Проверяем флаг принудительного удаления
if getattr(self, '_skip_trash_validation', False):
return
if self.journal_entry:
if frappe.db.exists("Journal Entry", self.journal_entry):
frappe.throw(
_("Cannot delete or cancel E-Taxes VAT Operations {0} because it is linked with Journal Entry {1}").format(
self.name,
self.journal_entry
)
)
```
**Изменить `vat_operations.py`:**
```python
for record in vat_records:
# Получаем документ
doc = frappe.get_doc('E-Taxes VAT Operations', record.name)
# Устанавливаем флаг для обхода валидации
doc._skip_trash_validation = True
# Удаляем
doc.delete(ignore_permissions=True, force=True)
```
**Плюсы:**
- Сохраняет логику валидации для ручного удаления
- Разрешает каскадное удаление из кода
**Минусы:**
- Более сложная логика
- Использует "внутренний" флаг
---
### Вариант 3: Изменить логику защиты (САМЫЙ ПРАВИЛЬНЫЙ)
**Идея:** Разрешить удаление VAT Operations всегда, но проверять только если пытаемся удалить ВРУЧНУЮ (не программно)
**Изменить `e_taxes_vat_operations.py`:**
```python
def on_trash(self):
"""Защита от удаления если связано с Journal Entry"""
# Пропускаем проверку если удаление идет из кода (не от пользователя)
if frappe.flags.in_test or frappe.flags.in_migrate:
return
# Проверяем только при ручном удалении
if self.journal_entry:
if frappe.db.exists("Journal Entry", self.journal_entry):
frappe.throw(
_("Cannot delete E-Taxes VAT Operations {0} because it is linked with Journal Entry {1}. "
"Please delete the Journal Entry first.").format(
self.name,
self.journal_entry
)
)
```
**НО:** Это не различает программное удаление от ручного! Все равно заблокирует.
---
### Вариант 4: Вообще убрать защиту от удаления
**Просто удалить метод `on_trash()` из `e_taxes_vat_operations.py`**
**Плюсы:**
- Просто
- Нет парадокса
**Минусы:**
- Пользователь может случайно удалить VAT Operations вручную
- Нарушится связь с Journal Entry
---
## 📋 РЕКОМЕНДУЕМОЕ РЕШЕНИЕ
### Использовать **Вариант 1** - frappe.db.delete()
**Файл:** `/home/frappe/frappe-bench/apps/invoice_az/invoice_az/vat_operations.py`
**Заменить строки 28-34:**
```python
# СТАРЫЙ КОД (не работает):
frappe.delete_doc(
'E-Taxes VAT Operations',
record.name,
ignore_permissions=True,
force=True
)
# НОВЫЙ КОД:
frappe.db.delete('E-Taxes VAT Operations', {'name': record.name})
```
**Полная функция:**
```python
@frappe.whitelist()
def on_delete_journal_entry(doc, method):
"""Удаляет связанные E-Taxes VAT Operations при удалении Journal Entry"""
try:
vat_records = frappe.get_all(
"E-Taxes VAT Operations",
filters={"journal_entry": doc.name},
fields=["name"]
)
if vat_records:
for record in vat_records:
frappe.logger().info(
f"Deleting E-Taxes VAT Operations {record.name} "
f"due to Journal Entry {doc.name} deletion"
)
# Прямое удаление из БД (обходит on_trash)
frappe.db.delete('E-Taxes VAT Operations', {'name': record.name})
frappe.db.commit()
frappe.logger().info(f"Successfully deleted {len(vat_records)} VAT Operations records")
except Exception as e:
frappe.log_error(
f"Error deleting E-Taxes VAT Operations for Journal Entry {doc.name}: {str(e)}\n{frappe.get_traceback()}",
"Journal Entry Delete Error"
)
```
**После исправления:**
```bash
bench restart
```
**Тест:**
1. Импортировать операцию → создается JE + VAT Operations
2. Попытаться удалить VAT Operations вручную → ошибка (защита работает)
3. Удалить Journal Entry → VAT Operations автоматически удаляется (каскад работает)
---
## 📝 КОМАНДЫ ДЛЯ ПРИМЕНЕНИЯ ВСЕХ ИСПРАВЛЕНИЙ
```bash
# 1. Очистить кэш
bench clear-cache
# 2. Собрать JavaScript (для БАГ 2 и БАГ 3)
bench build --app invoice_az
# 3. Перезапустить сервер (для всех Python изменений)
bench restart
# 4. В браузере: Ctrl+F5 (полная перезагрузка страницы)
```
---
## 🧪 ТЕСТИРОВАНИЕ ПОСЛЕ ИСПРАВЛЕНИЙ
### Тест 1: Фильтрация
**Работает** - пользователь подтвердил
### Тест 2: Визуальные баги
**Проверить:**
1. Импортировать 5-10 операций
2. Прогресс-бар должен идти от 0% до 100% плавно
3. Не должно быть зеленых алертов во время импорта
4. Только один диалог в конце
### Тест 3: Детальные ошибки
**Проверить:**
1. Импортировать операцию с несуществующим TIN
2. Кликнуть "View Error Details"
3. Должны увидеть: Amount, Customer Name, Missing TIN
4. Экспорт в CSV должен содержать эти поля
### Тест 4: Удаление (после исправления)
**Проверить:**
1. Импортировать операцию → создается JE + VAT Operations
2. Открыть VAT Operations напрямую → попытаться удалить → должна быть ошибка
3. Открыть Journal Entry → удалить → JE удален + VAT Operations автоматически удален
4. Проверить что VAT Operations больше нет в списке
---
## 📊 ИТОГОВАЯ СТАТИСТИКА
| Баг | Статус | Что нужно |
|-----|--------|-----------|
| **1. Фильтрация** | ✅ Работает | - |
| **2. Визуальные баги** | ⚠️ Требует bench build | `bench build --app invoice_az` |
| **3. Детальные ошибки** | ⚠️ Требует bench build | `bench build --app invoice_az` |
| **4. Парадокс удаления** | 🔴 Критический | Заменить `frappe.delete_doc` на `frappe.db.delete` |
---
## 📁 ИЗМЕНЕННЫЕ ФАЙЛЫ
1.`/home/frappe/frappe-bench/apps/invoice_az/invoice_az/vat_api.py`
- Строки 124-143: фильтрация в `get_vat_operations()`
- Строки 489-513: детальные ошибки в `import_vat_operations()`
2.`/home/frappe/frappe-bench/apps/invoice_az/invoice_az/client/journal_entry.js`
- Строка 1198: исправлен прогресс-бар
- Строки 1237-1239: убраны алерты
- Строка 1242: передача полного объекта ошибки
- Строки 628-654: отображение детальной информации
3.`/home/frappe/frappe-bench/apps/invoice_az/invoice_az/invoice_az/doctype/e_taxes_vat_operations/e_taxes_vat_operations.py`
- Строки 10-19: защита от удаления через `on_trash()`
4.`/home/frappe/frappe-bench/apps/invoice_az/invoice_az/vat_operations.py`
- Создан новый файл с каскадным удалением
- ⚠️ **ТРЕБУЕТ ИСПРАВЛЕНИЯ** - заменить `frappe.delete_doc` на `frappe.db.delete`
5.`/home/frappe/frappe-bench/apps/invoice_az/invoice_az/hooks.py`
- Добавлен хук для Journal Entry `on_trash` и `on_cancel`
---
## 🎯 ПРИОРИТЕТ ИСПРАВЛЕНИЙ
1. **ВЫСОКИЙ:** БАГ 4 - Парадокс удаления (блокирует удаление документов)
2. **СРЕДНИЙ:** БАГ 3 - Детальные ошибки (нужно для отладки)
3. **НИЗКИЙ:** БАГ 2 - Визуальные баги (косметические)
---
**Конец документа**