Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC
This commit is contained in:
1
rsbu_journal/wizards/__init__.py
Normal file
1
rsbu_journal/wizards/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import rsbu_trial_balance_wizard
|
||||
119
rsbu_journal/wizards/rsbu_trial_balance_wizard.py
Normal file
119
rsbu_journal/wizards/rsbu_trial_balance_wizard.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Мастер формирования оборотно-сальдовой ведомости (ОСВ)."""
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import float_is_zero
|
||||
|
||||
|
||||
class RsbuTrialBalanceWizard(models.TransientModel):
|
||||
_name = 'rsbu.trial.balance.wizard'
|
||||
_description = 'РСБУ — Мастер оборотно-сальдовой ведомости'
|
||||
|
||||
company_id = fields.Many2one(
|
||||
'res.company', string='Компания', required=True,
|
||||
default=lambda self: self.env.company)
|
||||
date_from = fields.Date(
|
||||
string='Период с', required=True,
|
||||
default=lambda self: fields.Date.today().replace(month=1, day=1))
|
||||
date_to = fields.Date(
|
||||
string='Период по', required=True,
|
||||
default=lambda self: fields.Date.today())
|
||||
hide_zero = fields.Boolean(
|
||||
string='Скрывать счета без данных', default=True,
|
||||
help='Не показывать счета с нулевыми сальдо и оборотами.')
|
||||
only_posted = fields.Boolean(
|
||||
string='Только проведённые', default=True, readonly=True,
|
||||
help='ОСВ строится по проведённым проводкам (иных в РСБУ-журнале '
|
||||
'к учёту не принимается).')
|
||||
line_ids = fields.One2many(
|
||||
'rsbu.trial.balance.line', 'wizard_id', string='Строки ОСВ')
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
def _iter_accounts(self):
|
||||
"""Счета компании для ОСВ (все, порядок по коду)."""
|
||||
self.ensure_one()
|
||||
return self.env['rsbu.account'].search([
|
||||
('company_id', '=', self.company_id.id),
|
||||
], order='complete_code, code')
|
||||
|
||||
def _account_values(self, account):
|
||||
"""Шесть показателей ОСВ по счёту (развёрнутое сальдо для АП)."""
|
||||
self.ensure_one()
|
||||
cid = self.company_id.id
|
||||
day_before = self.date_from - timedelta(days=1)
|
||||
# Сальдо на начало (до date_from) — развёрнутое по субконто.
|
||||
opening = account.get_expanded_balance(
|
||||
date_to=day_before, company_id=cid)
|
||||
# Обороты за период (по поддереву счёта).
|
||||
turnover = account.get_turnover(
|
||||
date_from=self.date_from, date_to=self.date_to,
|
||||
company_id=cid, include_children=True)
|
||||
# Сальдо на конец (до date_to включительно) — развёрнутое.
|
||||
closing = account.get_expanded_balance(
|
||||
date_to=self.date_to, company_id=cid)
|
||||
return {
|
||||
'opening_debit': opening['debit'],
|
||||
'opening_credit': opening['credit'],
|
||||
'turnover_debit': turnover['debit'],
|
||||
'turnover_credit': turnover['credit'],
|
||||
'closing_debit': closing['debit'],
|
||||
'closing_credit': closing['credit'],
|
||||
}
|
||||
|
||||
def _is_zero_row(self, vals):
|
||||
rounding = self.company_id.currency_id.rounding or 0.01
|
||||
return all(float_is_zero(vals[f], precision_rounding=rounding)
|
||||
for f in ('opening_debit', 'opening_credit',
|
||||
'turnover_debit', 'turnover_credit',
|
||||
'closing_debit', 'closing_credit'))
|
||||
|
||||
def action_generate(self):
|
||||
"""Пересчитать строки ОСВ и открыть отчёт на экране (QWeb-HTML)."""
|
||||
self.ensure_one()
|
||||
self.line_ids.unlink()
|
||||
Line = self.env['rsbu.trial.balance.line']
|
||||
currency = self.company_id.currency_id
|
||||
vals_list = []
|
||||
for account in self._iter_accounts():
|
||||
vals = self._account_values(account)
|
||||
if self.hide_zero and self._is_zero_row(vals):
|
||||
continue
|
||||
vals.update({
|
||||
'wizard_id': self.id,
|
||||
'account_id': account.id,
|
||||
'code': account.code,
|
||||
'name': account.name,
|
||||
'level': account.level,
|
||||
'is_group': bool(account.child_ids),
|
||||
'parent_code': account.parent_id.code or False,
|
||||
'company_id': self.company_id.id,
|
||||
'currency_id': currency.id,
|
||||
})
|
||||
vals_list.append(vals)
|
||||
Line.create(vals_list)
|
||||
return self.action_view_report()
|
||||
|
||||
def action_view_report(self):
|
||||
"""Открыть отчёт ОСВ (QWeb-HTML) для текущего мастера."""
|
||||
self.ensure_one()
|
||||
return self.env.ref(
|
||||
'rsbu_journal.action_report_rsbu_trial_balance').report_action(self)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
def _report_totals(self):
|
||||
"""Итоги ОСВ — только по счетам верхнего уровня (без двойного счёта).
|
||||
|
||||
Итог считается по корневым счетам (level 0), чтобы не суммировать
|
||||
родителя и его потомков дважды.
|
||||
"""
|
||||
self.ensure_one()
|
||||
roots = self.line_ids.filtered(lambda l: not l.parent_code)
|
||||
return {
|
||||
'opening_debit': sum(roots.mapped('opening_debit')),
|
||||
'opening_credit': sum(roots.mapped('opening_credit')),
|
||||
'turnover_debit': sum(roots.mapped('turnover_debit')),
|
||||
'turnover_credit': sum(roots.mapped('turnover_credit')),
|
||||
'closing_debit': sum(roots.mapped('closing_debit')),
|
||||
'closing_credit': sum(roots.mapped('closing_credit')),
|
||||
}
|
||||
58
rsbu_journal/wizards/rsbu_trial_balance_wizard_views.xml
Normal file
58
rsbu_journal/wizards/rsbu_trial_balance_wizard_views.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Мастер параметров ОСВ. -->
|
||||
<record id="view_rsbu_trial_balance_wizard_form" model="ir.ui.view">
|
||||
<field name="name">rsbu.trial.balance.wizard.form</field>
|
||||
<field name="model">rsbu.trial.balance.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Оборотно-сальдовая ведомость">
|
||||
<group>
|
||||
<group>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_id"
|
||||
groups="base.group_multi_company"/>
|
||||
<field name="hide_zero"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_generate" type="object"
|
||||
string="Сформировать" class="btn-primary"/>
|
||||
<button string="Отмена" special="cancel"
|
||||
class="btn-secondary"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_rsbu_trial_balance_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Оборотно-сальдовая ведомость</field>
|
||||
<field name="res_model">rsbu.trial.balance.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<!-- Табличный просмотр строк ОСВ с drill-down по счёту. -->
|
||||
<record id="view_rsbu_trial_balance_line_list" model="ir.ui.view">
|
||||
<field name="name">rsbu.trial.balance.line.list</field>
|
||||
<field name="model">rsbu.trial.balance.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="ОСВ" create="false" delete="false"
|
||||
default_order="code">
|
||||
<field name="code" string="Счёт"/>
|
||||
<field name="name" string="Наименование"/>
|
||||
<field name="opening_debit" sum="Сальдо нач. Дт"/>
|
||||
<field name="opening_credit" sum="Сальдо нач. Кт"/>
|
||||
<field name="turnover_debit" sum="Оборот Дт"/>
|
||||
<field name="turnover_credit" sum="Оборот Кт"/>
|
||||
<field name="closing_debit" sum="Сальдо кон. Дт"/>
|
||||
<field name="closing_credit" sum="Сальдо кон. Кт"/>
|
||||
<field name="currency_id" column_invisible="1"/>
|
||||
<button name="action_open_entries" type="object"
|
||||
string="Проводки" icon="fa-search"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user