26 KiB
Техническое задание: Автоматизация заполнения Декларации по налогу на имущество
1. Общее описание
Цель: Автоматизировать заполнение дочерних таблиц Əlavə 1 и Əlavə 2 в декларации по налогу на имущество (Property Tax Return) на основе данных об активах (Assets) с использованием логики отчета "Asset Depreciations and Balances" из ERPNext.
Дата создания: 2025-12-11
Версия: 1.0
2. Бизнес-требования
2.1 Функциональные требования
-
Добавление полей выбора периода:
- Добавить два взаимоисключающих чекбокса в форму Property Tax Return:
Tam İl(Полный год) - по умолчанию включенİl Ərzində(В течение года)
- Чекбоксы должны располагаться сразу после поля
İl(Год) на главной странице декларации
- Добавить два взаимоисключающих чекбокса в форму Property Tax Return:
-
Автоматическое заполнение данных:
- При изменении года (
İl) или чекбоксов система должна автоматически:- Получить данные об активах из базы данных
- Рассчитать балансовые стоимости активов
- Агрегировать данные по типам активов и налоговым статьям
- Заполнить соответствующие строки в дочерних таблицах
- При изменении года (
-
Источник данных:
- Все расчеты должны базироваться на отчете ERPNext "Asset Depreciations and Balances"
- Использовать данные из doctype
Assetкомпании пользователя
2.2 Пользовательский сценарий
- Пользователь открывает/создает документ Property Tax Return
- Заполняет поле
İl(год декларации, например: 2024) - Выбирает режим расчета:
Tam İl- если компания работала полный годİl Ərzində- если компания была создана в течение года
- Система автоматически:
- Преобразует год в диапазон дат (01.01.YYYY - 31.12.YYYY)
- Получает данные об активах
- Заполняет таблицы Əlavə 1 и Əlavə 2
3. Технические требования
3.1 Изменения в схеме данных
3.1.1 Property Tax Return DocType JSON
Файл: /home/frappe/frappe-bench/apps/taxes_az/taxes_az/taxes_az/doctype/property_tax_return/property_tax_return.json
Новые поля:
{
"fieldname": "tam_il",
"fieldtype": "Check",
"label": "Tam İl",
"default": "1"
},
{
"fieldname": "il_erzinde",
"fieldtype": "Check",
"label": "İl Ərzində",
"default": "0"
}
Позиция: После поля il в массиве field_order
3.2 Логика расчетов
3.2.1 Преобразование даты
- Вход: Год (Int, например: 2024)
- Выход:
from_date= "2024-01-01"to_date= "2024-12-31"
3.2.2 Режимы расчета
Режим "Tam İl" (Полный год)
Для Əlavə 2 (Taxable Assets):
- Поле
hesabatilininəvvəlinəəsasvəsaitlərinqalıqdəyəri(501.1) ← Остаточная стоимость на начало года - Поле
hesabatilinsonunaəsasvəsaitlərinqalıqdəyəri(504.1) ← Остаточная стоимость на конец года
Для Əlavə 1 (Tax Exempt Assets):
- Поле
hesabatilininəvvəlinəəsasvəsaitlərinqalıqdəyərimanatla5012(501.2) ← Остаточная стоимость на начало года - Поле
ilinsonunaəsasvəsaitlərinqalıqdəyəri(504.2) ← Остаточная стоимость на конец года
Режим "İl Ərzində" (В течение года)
Для Əlavə 2 (Taxable Assets):
- Поле
hesabatilierzindeuçotaalınan(503.1) ← Стоимость новых приобретений - Поле
hesabatilinsonunaəsasvəsaitlərinqalıqdəyəri(504.1) ← Остаточная стоимость на конец года
Для Əlavə 1 (Tax Exempt Assets):
- Поле
hesabatiliərzindəəsasvəsaitlərinqalıqdəyəri(503.2) ← Стоимость новых приобретений - Поле
ilinsonunaəsasvəsaitlərinqalıqdəyəri(504.2) ← Остаточная стоимость на конец года
3.3 Правила агрегации данных
3.3.1 Для Əlavə 2 (Налогооблагаемые активы)
Источник данных:
- Активы с заполненным полем
taxable_asset_type
Правило сопоставления:
- Значение
taxable_asset_typeиз актива = Значение "Vergiyə cəlb olunan əmlakların kateqoriyası" в строке таблицы Əlavə 2
Возможные значения taxable_asset_type:
- Çoxmərtəbəli (çoxmənzilli) yaşayış binaları
- Qeyri-yaşayış binaları (sahələri)
- Əmlak kompleksi kimi müəssisələr
- Qurğular
- Mənzillər
- Fərdi yaşayış və bağ evləri
- Maşınlar və avadanlıqlar
- Yüksək texnologiyalar məhsulu olan hesablama texnikası
- Nəqliyyat vasitələri
- Digər əsas vəsaitlər
Логика:
- Получить все активы компании с
taxable_asset_type IS NOT NULL - Для каждого актива рассчитать балансовые стоимости
- Агрегировать (суммировать) по
taxable_asset_type - Найти соответствующую строку в Əlavə 2 по совпадению
taxable_asset_type - Обновить значения полей в найденной строке
3.3.2 Для Əlavə 1 (Налогово-освобожденные активы)
Источник данных:
- Активы с заполненным полем
industrial_tax_articleИЛИtax_exempt_tax_article - ИСКЛЮЧИТЬ активы с
agricultural_tax_article(налог на сельскохозяйственные земли)
Правило сопоставления:
- Извлечь номер статьи из названия Tax Article (например: "199.1", "207.3", "227.1")
- Найти строку в Əlavə 1, где поле "Azadolma səbəbi" содержит этот номер
Примеры извлечения номера статьи:
- "Vergi Məcəlləsinin 199.1-ci maddəsinə əsasən" → "199.1"
- "Vergi Məcəlləsinin 207.3-cü maddəsinə əsasən" → "207.3"
- "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən" → "199.4.1"
Логика:
- Получить все активы с
industrial_tax_articleилиtax_exempt_tax_article - Для каждого актива:
- Извлечь номер статьи regex:
(\d+(?:\.\d+)*(?:-\d+)?) - Рассчитать балансовые стоимости
- Извлечь номер статьи regex:
- Агрегировать по номеру статьи
- Найти соответствующую строку в Əlavə 1
- Обновить значения полей
3.4 Расчет балансовых стоимостей
Использовать логику стандартного отчета ERPNext "Asset Depreciations and Balances":
Формулы:
-
Остаточная стоимость на начало периода (Opening Balance):
Чистая стоимость активов, приобретенных до from_date = Валовая стоимость - Накопленная амортизация на from_date -
Стоимость новых приобретений (New Purchases):
Валовая стоимость активов, приобретенных в период [from_date, to_date] -
Остаточная стоимость на конец периода (Closing Balance):
Opening Balance + New Purchases - Sold Assets - Scrapped Assets - Capitalized Assets + Adjustments during period - Accumulated Depreciation as on to_date
Источники данных для расчетов:
tabAsset- основные данные об активахtabGL Entry- записи амортизации и корректировок стоимостиtabAsset Category Account- счета амортизацииtabAsset Capitalization- капитализированные активы (если доступно в версии ERPNext)
3.5 Важные ограничения
-
НЕ создавать новые строки в дочерних таблицах
- Строки в Əlavə 1 и Əlavə 2 должны быть предварительно созданы клиентскими скриптами
- Система только ОБНОВЛЯЕТ значения в существующих строках
-
Сохранять строки без совпадений
- Если для строки не найдено данных об активах, не очищать ее значения
- Оставлять строку как есть
-
Обработка дубликатов
- Если актив имеет оба поля (
tax_exempt_tax_articleИtaxable_asset_type), включить его в обе таблицы - Приоритет при наличии нескольких tax article полей:
industrial_tax_article>tax_exempt_tax_article
- Если актив имеет оба поля (
4. Архитектура решения
4.1 Серверная часть (Python)
Файл: property_tax_return.py
4.1.1 Основной метод API
@frappe.whitelist()
def populate_property_tax_tables(company, year, from_date, to_date,
calculation_mode, existing_elave_1, existing_elave_2)
Параметры:
company- Название компанииyear- Год декларацииfrom_date- Дата начала периода (YYYY-MM-DD)to_date- Дата окончания периода (YYYY-MM-DD)calculation_mode- Режим расчета: 'tam_il' или 'il_erzinde'existing_elave_1- JSON массив существующих строк Əlavə 1existing_elave_2- JSON массив существующих строк Əlavə 2
Возвращает:
{
'success': True/False,
'elave_1_data': {
'matching_key': {
'field_name': value,
...
},
...
},
'elave_2_data': {
'matching_key': {
'field_name': value,
...
},
...
},
'error': 'Error message' (если success=False)
}
4.1.2 Вспомогательные функции
-
get_taxable_assets_aggregated(company, from_date, to_date)
- Получает налогооблагаемые активы
- Агрегирует по
taxable_asset_type
-
get_tax_exempt_assets_aggregated(company, from_date, to_date)
- Получает налогово-освобожденные активы
- Агрегирует по номеру статьи
-
get_asset_balances_using_standard_logic(company, from_date, to_date, asset_names)
- Рассчитывает балансовые стоимости активов
- Использует логику стандартного отчета ERPNext
-
extract_article_number(tax_article_name)
- Извлекает номер статьи из названия Tax Article
- Использует regex:
(\d+(?:\.\d+)*(?:-\d+)?)
-
find_matching_azadolma_sebeb(article_number, existing_rows)
- Находит строку в Əlavə 1 по номеру статьи
-
check_erpnext_version()
- Проверяет версию ERPNext для совместимости полей
-
get_asset_cost_details(...) - Получает данные о стоимости активов
-
get_asset_depreciation_details(...) - Получает данные об амортизации
-
get_asset_value_adjustments(...) - Получает корректировки стоимости
4.2 Клиентская часть (JavaScript)
Файл: property_tax_return.js
4.2.1 Обработчики событий формы
frappe.ui.form.on('Property tax return', {
refresh: function(frm) {
// Инициализация взаимоисключающих чекбоксов
setup_checkbox_exclusivity(frm);
},
il: function(frm) {
// Автоматическая перезагрузка при изменении года
reload_property_tax_data(frm);
},
tam_il: function(frm) {
// Обработка изменения чекбокса "Полный год"
// Снимает il_erzinde, если tam_il включен
// Перезагружает данные
},
il_erzinde: function(frm) {
// Обработка изменения чекбокса "В течение года"
// Снимает tam_il, если il_erzinde включен
// Перезагружает данные
}
});
4.2.2 Вспомогательные функции
-
setup_checkbox_exclusivity(frm)
- Гарантирует, что только один чекбокс выбран
- Если оба сняты, устанавливает tam_il=1
-
reload_property_tax_data(frm)
- Валидирует входные данные
- Показывает индикатор загрузки
- Вызывает серверный метод
- Обновляет дочерние таблицы
- Показывает сообщения об успехе/ошибке
-
update_child_table_values(frm, table_name, data_map)
- Обновляет значения в строках дочерних таблиц
- Использует квадратные скобки для полей с юникодными символами
- Не создает новые строки
5. Обработка ошибок
5.1 Валидация на клиенте
-
Год не указан:
Сообщение: "Please select a year (İl) first" Действие: Прерывание выполнения -
Ни один чекбокс не выбран:
Сообщение: "Please select either Tam İl or İl Ərzində" Действие: Прерывание выполнения
5.2 Обработка на сервере
-
Ошибка получения данных:
- Логирование в Error Log:
frappe.log_error() - Возврат
{'success': False, 'error': error_message}
- Логирование в Error Log:
-
Нет активов:
- Возврат пустых словарей для elave_1_data и elave_2_data
{'success': True, 'elave_1_data': {}, 'elave_2_data': {}}
-
Отсутствующие custom fields:
- Логирование предупреждения
- Продолжение работы без ошибки
5.3 Визуальная обратная связь
-
Во время загрузки:
frappe.dom.freeze(__('Loading property tax data...')); -
При успехе:
frappe.show_alert({ message: __('Property tax data loaded successfully'), indicator: 'green' }); -
При ошибке:
frappe.msgprint({ title: __('Error'), message: error_message, indicator: 'red' });
6. Тестирование
6.1 Модульное тестирование (Python)
Тестовые случаи:
-
extract_article_number()
- Входные данные: "Vergi Məcəlləsinin 199.1-ci maddəsinə əsasən"
- Ожидаемый результат: "199.1"
-
get_taxable_assets_aggregated()
- Создать 3 актива с одним
taxable_asset_type - Проверить корректность агрегации
- Создать 3 актива с одним
-
get_asset_balances_using_standard_logic()
- Создать активы с амортизацией
- Сравнить результаты с отчетом "Asset Depreciations and Balances"
6.2 Интеграционное тестирование
-
Полный рабочий процесс - Tam İl:
- Создать Property Tax Return
- Выбрать год 2024
- Включить "Tam İl"
- Проверить заполнение полей 501.x и 504.x
-
Полный рабочий процесс - İl Ərzində:
- Создать Property Tax Return
- Выбрать год 2024
- Включить "İl Ərzində"
- Проверить заполнение полей 503.x и 504.x
-
Переключение между режимами:
- Изменить с "Tam İl" на "İl Ərzində"
- Проверить пересчет значений
6.3 Тестирование UI
-
Взаимоисключающие чекбоксы:
- Включить "Tam İl" → "İl Ərzində" должен быть выключен
- Включить "İl Ərzində" → "Tam İl" должен быть выключен
- Снять оба → "Tam İl" должен автоматически включиться
-
Индикаторы загрузки:
- Проверить отображение при вызове сервера
- Проверить исчезновение после завершения
7. Производительность
7.1 Оптимизация запросов
-
Единый вызов сервера:
- Все данные получаются за один запрос
- Избегать множественных вызовов API
-
Пакетная обработка активов:
- Получение всех активов одним SQL запросом
- Использование оператора IN для фильтрации
-
Агрегация в памяти:
- Суммирование значений в Python, а не в SQL
- Уменьшение нагрузки на БД
7.2 Ожидаемая производительность
- До 100 активов: < 3 секунд
- 100-500 активов: 3-10 секунд
- 500+ активов: 10-30 секунд
7.3 Timeout настройки
// В JavaScript нет explicit timeout, используется стандартный Frappe timeout
// Для Python метода можно увеличить через:
frappe.call({
...,
timeout: 120000 // 2 минуты
});
8. Безопасность
8.1 Аутентификация и авторизация
-
Метод доступен только аутентифицированным пользователям:
@frappe.whitelist() -
Проверка прав на doctype:
- Пользователь должен иметь права на Property Tax Return
- Автоматически проверяется Frappe framework
-
Фильтрация по компании:
- Данные фильтруются по компании пользователя
- Невозможно получить данные других компаний
8.2 Валидация входных данных
-
Тип данных:
yearдолжен быть Integerfrom_date,to_dateдолжны быть в формате YYYY-MM-DDcalculation_modeдолжен быть 'tam_il' или 'il_erzinde'
-
SQL Injection Prevention:
- Использование параметризованных запросов
- Никаких прямых вставок пользовательского ввода в SQL
9. Миграция и развертывание
9.1 Шаги развертывания
-
Обновление JSON схемы:
cd /home/frappe/frappe-bench bench --site site1 migrate -
Очистка кэша:
bench --site site1 clear-cache -
Перезапуск (опционально):
bench restart
9.2 Откат изменений
-
Удаление новых полей через UI:
- Customize Form → Property Tax Return
- Удалить поля tam_il и il_erzinde
-
Откат кода:
git revert <commit_hash> bench --site site1 migrate
10. Документация для пользователей
10.1 Краткая инструкция
Заголовок: Автоматическое заполнение декларации по налогу на имущество
Шаги:
- Откройте документ "Property Tax Return" (Декларация по налогу на имущество)
- Заполните поле "İl" (Год), например: 2024
- Выберите период:
- Tam İl - если компания работала полный год
- İl Ərzində - если компания была создана в течение года
- Система автоматически заполнит таблицы Əlavə 1 и Əlavə 2 данными из ваших активов
Примечания:
- Для работы функции необходимо, чтобы в системе были созданы активы (Assets) с заполненными полями:
taxable_asset_type- для налогооблагаемых активовindustrial_tax_articleилиtax_exempt_tax_article- для освобожденных от налога активов
- Данные рассчитываются на основе фактической амортизации активов
11. Список файлов
11.1 Измененные файлы
-
property_tax_return.json
- Путь:
/home/frappe/frappe-bench/apps/taxes_az/taxes_az/taxes_az/doctype/property_tax_return/property_tax_return.json - Изменения: Добавлены поля tam_il и il_erzinde
- Путь:
-
property_tax_return.py
- Путь:
/home/frappe/frappe-bench/apps/taxes_az/taxes_az/taxes_az/doctype/property_tax_return/property_tax_return.py - Изменения: Реализован весь серверный код (~684 строки)
- Путь:
-
property_tax_return.js
- Путь:
/home/frappe/frappe-bench/apps/taxes_az/taxes_az/taxes_az/doctype/property_tax_return/property_tax_return.js - Изменения: Добавлен клиентский код автозаполнения (~177 строк)
- Путь:
11.2 Новые файлы
- TECHNICAL_SPECIFICATION_PROPERTY_TAX_AUTOMATION.md (этот документ)
- Путь:
/home/frappe/frappe-bench/apps/taxes_az/TECHNICAL_SPECIFICATION_PROPERTY_TAX_AUTOMATION.md
- Путь:
12. Известные ограничения
-
Предварительное создание строк:
- Строки в Əlavə 1 и Əlavə 2 должны быть созданы заранее клиентскими скриптами
- Система не создает новые строки автоматически
-
Один год за раз:
- Расчет выполняется только для одного календарного года
- Невозможно рассчитать для нескольких лет одновременно
-
Зависимость от ERPNext версии:
- Код проверяет наличие полей net_purchase_amount и Asset Capitalization
- Может требовать адаптации для очень старых версий ERPNext
-
Производительность для больших объемов:
- Для компаний с 1000+ активами может потребоваться оптимизация
- Рекомендуется тестирование на реальных данных
13. Будущие улучшения
13.1 Краткосрочные (v1.1)
- Добавить кнопку принудительного пересчета
- Показывать количество обработанных активов
- Логирование детальной информации о расчетах
13.2 Долгосрочные (v2.0)
- Поддержка расчета за произвольный период (не только календарный год)
- Экспорт детального отчета по расчетам в Excel
- Предварительный просмотр изменений перед применением
- Batch processing для очень больших объемов данных
14. Контакты и поддержка
Разработчик: Claude (Anthropic)
Дата разработки: 2025-12-11
Версия системы: Frappe v15, ERPNext
Git репозиторий: /home/frappe/frappe-bench/apps/taxes_az
15. История изменений
| Версия | Дата | Описание | Автор |
|---|---|---|---|
| 1.0 | 2025-12-11 | Первоначальная разработка и развертывание | Claude |
| 1.0.1 | 2025-12-11 | Исправление ошибок в JavaScript (квадратные скобки для Unicode полей) | Claude |
Конец документа