Files
public/rsbu_vat_templates/models/account_tax.py

117 lines
6.7 KiB
Python
Raw 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.
# -*- coding: utf-8 -*-
import logging
from odoo import api, models
_logger = logging.getLogger(__name__)
# Название налоговой группы НДС (РФ). Общее для всех компаний.
TAX_GROUP_NAME = "НДС"
# Эталонный набор ставок НДС по НК РФ — 1:1 из прежнего account_tax_data.xml.
# Способы расчёта:
# * «плюс НДС» — налог сверх суммы (amount_type=percent, tax_excluded)
# * «в т.ч. НДС» — налог внутри суммы (amount_type=division, tax_included)
# Направление: продажа (sale) / покупка (purchase).
# «Без НДС» и «НДС 0%» намеренно без «в т.ч.»-вариантов (деление на 0% бессмысленно).
# (name, type_tax_use, amount_type, amount, price_include_override)
VAT_TAXES = [
("Без НДС (продажа)", "sale", "percent", 0.0, "tax_excluded"),
("Без НДС (покупка)", "purchase", "percent", 0.0, "tax_excluded"),
("НДС 0% (продажа)", "sale", "percent", 0.0, "tax_excluded"),
("НДС 0% (покупка)", "purchase", "percent", 0.0, "tax_excluded"),
("НДС 5% (продажа)", "sale", "percent", 5.0, "tax_excluded"),
("НДС 5% в т.ч. (продажа)", "sale", "division", 5.0, "tax_included"),
("НДС 5% (покупка)", "purchase", "percent", 5.0, "tax_excluded"),
("НДС 5% в т.ч. (покупка)", "purchase", "division", 5.0, "tax_included"),
("НДС 7% (продажа)", "sale", "percent", 7.0, "tax_excluded"),
("НДС 7% в т.ч. (продажа)", "sale", "division", 7.0, "tax_included"),
("НДС 7% (покупка)", "purchase", "percent", 7.0, "tax_excluded"),
("НДС 7% в т.ч. (покупка)", "purchase", "division", 7.0, "tax_included"),
("НДС 10% (продажа)", "sale", "percent", 10.0, "tax_excluded"),
("НДС 10% в т.ч. (продажа)", "sale", "division", 10.0, "tax_included"),
("НДС 10% (покупка)", "purchase", "percent", 10.0, "tax_excluded"),
("НДС 10% в т.ч. (покупка)", "purchase", "division", 10.0, "tax_included"),
("НДС 22% (продажа)", "sale", "percent", 22.0, "tax_excluded"),
("НДС 22% в т.ч. (продажа)", "sale", "division", 22.0, "tax_included"),
("НДС 22% (покупка)", "purchase", "percent", 22.0, "tax_excluded"),
("НДС 22% в т.ч. (покупка)", "purchase", "division", 22.0, "tax_included"),
]
class AccountTax(models.Model):
_inherit = "account.tax"
def _rsbu_ensure_tax_group(self, company, country):
"""Найти/создать налоговую группу НДС для компании. Идемпотентно."""
Group = self.env['account.tax.group']
group = Group.search([
('company_id', '=', company.id),
('name', '=', TAX_GROUP_NAME),
], limit=1)
if not group:
group = Group.create({
'name': TAX_GROUP_NAME,
'company_id': company.id,
'country_id': country.id if country else False,
})
return group
def _rsbu_ensure_vat_taxes(self, company, group, country):
"""Создать недостающие ставки НДС для корневой компании. Идемпотентно.
Дедуп выполняется в границах всей иерархии компании-корня
(`company_id child_of root_id`), повторяя область действия штатного
ограничения уникальности `account.tax._constrains_name`. Иначе на базах
с филиалами (branch) создание ставки с тем же именем вызовет
«Tax names must be unique!».
"""
Tax = self.env['account.tax']
created = 0
for name, use, atype, amount, incl in VAT_TAXES:
exists = Tax.with_context(active_test=False).search([
('company_id', 'child_of', company.root_id.id),
('name', '=', name),
('type_tax_use', '=', use),
('country_id', '=', country.id if country else False),
], limit=1)
if exists:
continue
Tax.create({
'name': name,
'type_tax_use': use,
'amount_type': atype,
'amount': amount,
'price_include_override': incl,
'tax_group_id': group.id,
'country_id': country.id if country else False,
'company_id': company.id,
})
created += 1
return created
@api.model
def _rsbu_setup_vat_taxes(self):
"""Создать налоговую группу НДС и 20 ставок НДС для каждой КОРНЕВОЙ компании.
Вызывается через <function> в data при установке И при каждом `-u`.
Ставки НДС создаются на уровне корневой компании (root_id). Филиалы
(branch, parent_id задан) наследуют план счетов и налоги родителя — это
штатное поведение бухгалтерии Odoo, и штатное ограничение уникальности
`account.tax` запрещает дублировать ставки с тем же именем внутри одной
иерархии компании. Поэтому мы перебираем только корневые компании
(`parent_id = False`); филиалы получают доступ к ставкам родителя.
Идемпотентно: дедуп по (иерархия root, name, type_tax_use, country_id),
поэтому повторный запуск / установка на новую компанию не создают дублей.
"""
country = self.env.ref('base.ru', raise_if_not_found=False)
root_companies = self.env['res.company'].search([('parent_id', '=', False)])
for company in root_companies:
group = self._rsbu_ensure_tax_group(company, country)
n = self._rsbu_ensure_vat_taxes(company, group, country)
_logger.info(
"rsbu_vat_templates: корневая компания %s — создано ставок НДС: %s",
company.display_name, n)