You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.5 KiB
Python

# -*- coding: utf-8 -*-
from collections import defaultdict
from datetime import timedelta
from odoo import api, models, fields
def balance_debit_to_balance_direction(balance_debit):
if balance_debit > 0:
balance = balance_debit
direction = 'debit'
elif balance_debit < 0:
balance = - balance_debit
direction = 'credit'
else:
balance = 0
direction = 'balance'
return balance, direction
class LedgerPrintWizard(models.TransientModel):
"""总账打印向导"""
_name = 'ledger.print.wizard'
_description = '总账打印向导'
def _default_fiscalyear_id(self):
fiscalyears = self.env['fr.account.fiscalyear'].search([])
if len(fiscalyears) > 1:
return fiscalyears[1]
else:
return fiscalyears
fiscalyear_id = fields.Many2one('fr.account.fiscalyear', string='会计年度', default=_default_fiscalyear_id, required=True, ondelete='cascade')
account_ids = fields.Many2many('account.account', string='会计科目')
def confirm(self):
self.ensure_one()
# 获取要打印的科目
if self.account_ids:
account_ids = self.account_ids
else:
account_ids = self.env['account.account'].search([('state', '=', 'on_use')])
date_start = self.fiscalyear_id.period_ids.filtered(lambda x: x.state != 'unuse')[0].date_start
date = date_start - timedelta(days=1)
balance_data = self._fetch_balance_data(self.fiscalyear_id.company_id.id, date)
period_data = self._fetch_period_data(self.fiscalyear_id.company_id.id, self.fiscalyear_id.id)
# 生成临时总账报表记录
vals_list = []
for account in account_ids:
line_vals_list = []
descendant_ids = account.get_descendant_ids(leaf=True)
# 上年结转/初始余额
balance_start = sum([balance_data[descendant_id] for descendant_id in descendant_ids])
balance_temp, direction_temp = balance_debit_to_balance_direction(balance_start)
line_vals_list.append((0, 0, {
'name': '上年结转',
'direction': direction_temp,
'balance': balance_temp
}))
# 期间总账
balance = balance_start
debit_fiscalyear = credit_fiscalyear = 0
for period in self.fiscalyear_id.period_ids.filtered(lambda x: x.state != 'unuse'):
debit_period = credit_period = 0
# 从下级科目获取
for descendant_id in descendant_ids:
data_key = f"{descendant_id}-{period.id}"
debit_period += period_data[data_key][0]
credit_period += period_data[data_key][1]
balance += debit_period - credit_period
balance, direction = balance_debit_to_balance_direction(balance)
# 本期合计
line_vals_list.append((0, 0, {
'period_id': period.id,
'name': '本期合计',
'debit': debit_period,
'credit': credit_period,
'direction': direction,
'balance': balance
}))
# 本年累计
debit_fiscalyear += debit_period
credit_fiscalyear += credit_period
line_vals_list.append((0, 0, {
'name': '本年累计',
'debit': debit_fiscalyear,
'credit': credit_fiscalyear,
}))
vals_list.append({
'account_id': account.id,
'fiscalyear_id': self.fiscalyear_id.id,
'line_ids': line_vals_list,
})
# 创建临时记录集
report_recs = self.env['report.account.ledger'].create(vals_list)
# 获取报表
act_report = self.env.ref('account_ledger.ReportAccountLedgerAction')
report = act_report.report_action(report_recs, config=False)
return report
def _fetch_balance_data(self, company_id, date_end):
# 期末余额数据读取
self.env.cr.execute(f"""
SELECT
account_id,
sum( balance ) AS balance
FROM
account_move_line
WHERE
company_id = {company_id} and date <= '{date_end}' and fr_state = 'posted'
GROUP BY
account_id
""")
balance_data = defaultdict(float)
for res in self.env.cr.fetchall():
balance_data[res[0]] = res[1]
return balance_data
def _fetch_period_data(self, company_id, fiscalyear_id):
# 期间借贷发生数据读取
self.env.cr.execute(f"""
SELECT
account_id,
fr_period_id,
sum( debit ) AS debit,
sum( credit ) AS credit
FROM
account_move_line
WHERE
company_id = {company_id} and fr_fiscalyear_id = {fiscalyear_id} and fr_state = 'posted'
GROUP BY
account_id,
fr_period_id
""")
period_data = defaultdict(lambda: (0, 0))
for res in self.env.cr.fetchall():
data_key = f"{res[0]}-{res[1]}"
period_data[data_key] = (res[2], res[3])
return period_data