|
|
# -*- coding: utf-8 -*-
|
|
|
from odoo import api, fields, models
|
|
|
from odoo.exceptions import ValidationError, UserError, MissingError
|
|
|
|
|
|
|
|
|
class AccountLedgerValue(models.Model):
|
|
|
|
|
|
_name = 'account.ledger.value'
|
|
|
_description = '报表取值'
|
|
|
|
|
|
def _default_from_type(self):
|
|
|
if self.report_id and self.report_type == 'cash_flow':
|
|
|
from_type = 'cash_flow'
|
|
|
else:
|
|
|
from_type = 'ledger_line'
|
|
|
|
|
|
return from_type
|
|
|
|
|
|
# 基础字段
|
|
|
name = fields.Char(string='名称', required=True)
|
|
|
from_type = fields.Selection([
|
|
|
('ledger_line', '科目余额表'),
|
|
|
('cash_flow', '现金流量项目'),
|
|
|
('other_value', '其他取值')], string='取值来源', required=True, default=_default_from_type)
|
|
|
|
|
|
# 关系字段
|
|
|
report_id = fields.Many2one('account.ledger.report', string='报表', ondelete='cascade')
|
|
|
ledger_line_ids = fields.One2many('account.ledger.value.line', 'value_id', domain=[('from_type', '=', 'ledger_line')])
|
|
|
cash_flow_ids = fields.One2many('account.ledger.value.line', 'value_id', domain=[('from_type', '=', 'cash_flow')])
|
|
|
other_value_ids = fields.One2many('account.ledger.value.line', 'value_id', domain=[('from_type', '=', 'other_value')])
|
|
|
|
|
|
# 关系字段
|
|
|
report_type = fields.Selection(related='report_id.report_type', string='报表类型')
|
|
|
company_id = fields.Many2one(related='report_id.company_id', string='公司')
|
|
|
|
|
|
# ===================
|
|
|
# 公用方法
|
|
|
# ===================
|
|
|
|
|
|
def get_value(self, data_cache):
|
|
|
"""单实例方法:根据期间年度和期间号获取对应值"""
|
|
|
self.ensure_one()
|
|
|
value = 0
|
|
|
|
|
|
# 直接从缓存获取值
|
|
|
if not data_cache['value_cache'].get(self.id, None) is None:
|
|
|
return data_cache['value_cache'][self.id]
|
|
|
|
|
|
# 从科目余额表取数
|
|
|
if self.from_type == 'ledger_line':
|
|
|
value = round(sum([line.get_value(data_cache) for line in self.ledger_line_ids]), 2)
|
|
|
|
|
|
# 从现金流量项目取数
|
|
|
elif self.from_type == 'cash_flow':
|
|
|
value = round(sum([line.get_value(data_cache) for line in self.cash_flow_ids]), 2)
|
|
|
|
|
|
# 从其他取值取数
|
|
|
elif self.from_type == 'other_value':
|
|
|
value = round(sum([line.get_value(data_cache) for line in self.other_value_ids]), 2)
|
|
|
|
|
|
# 存入缓存
|
|
|
data_cache['value_cache'][self.id] = value
|
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
class AccountLedgerValueLine(models.Model):
|
|
|
|
|
|
_name = 'account.ledger.value.line'
|
|
|
_description = '报表取值明细'
|
|
|
|
|
|
# 基础字段
|
|
|
value_sign = fields.Selection([('add', '+'), ('minus', '-')], string='符号', default='add', required=True)
|
|
|
|
|
|
# 关系字段
|
|
|
value_id = fields.Many2one('account.ledger.value', string='报表取值', required=True, ondelete='cascade')
|
|
|
account_id = fields.Many2one('account.account', string='来源科目')
|
|
|
cash_flow_id = fields.Many2one('account.cash.flow', string='现金流量项目')
|
|
|
value_type = fields.Many2one('account.ledger.value.type', string='取值类型')
|
|
|
value_from_id = fields.Many2one('account.ledger.value', string='来源取值')
|
|
|
|
|
|
# 关联字段
|
|
|
report_type = fields.Selection(related='value_id.report_id.report_type', string='报表类型')
|
|
|
from_type = fields.Selection(related='value_id.from_type', string='取值来源')
|
|
|
company_id = fields.Many2one(related='account_id.company_id', string='来源公司')
|
|
|
|
|
|
# ===================
|
|
|
# 公用方法
|
|
|
# ===================
|
|
|
|
|
|
def get_value(self, data_cache):
|
|
|
"""单实例方法:根据期间年度和期间编号获取明细取值"""
|
|
|
self.ensure_one()
|
|
|
value = 0
|
|
|
|
|
|
# 从科目余额表取数
|
|
|
if self.from_type == 'ledger_line' and self.account_id and self.value_type:
|
|
|
value = self._get_ledger_line_value(data_cache)
|
|
|
|
|
|
# 现金流量表取数
|
|
|
elif self.from_type == 'cash_flow' and self.cash_flow_id and self.value_type:
|
|
|
value = self._get_cash_flow_value(data_cache)
|
|
|
|
|
|
# 从其他取值取数
|
|
|
elif self.from_type == 'other_value' and self.value_from_id:
|
|
|
value = self.value_from_id.get_value(data_cache)
|
|
|
|
|
|
# 判断是否取负
|
|
|
if self.value_sign == 'minus':
|
|
|
value = -value
|
|
|
|
|
|
return value
|
|
|
|
|
|
# ===================
|
|
|
# 约束方法
|
|
|
# ===================
|
|
|
@api.constrains('value_id', 'value_from_id', 'value_form_id.line_ids.value_from_id')
|
|
|
def _constraints_value_id(self):
|
|
|
for rec in self:
|
|
|
if rec.value_id == rec.value_from_id:
|
|
|
raise ValidationError('来源报表取值不能为当前报表取值!')
|
|
|
|
|
|
if rec.value_id in rec.value_from_id.other_value_ids.mapped('value_from_id'):
|
|
|
raise ValidationError(f'报表取值{rec.value_from_id.name}存在递归调用{rec.value_id.name}!')
|
|
|
|
|
|
# ===================
|
|
|
# 私有方法
|
|
|
# ===================
|
|
|
def _get_ledger_line_value(self, data_cache):
|
|
|
"""单实例方法:从科目余额表获取取值"""
|
|
|
self.ensure_one()
|
|
|
|
|
|
if not self.account_id:
|
|
|
raise ValidationError('取值科目不能为空!')
|
|
|
|
|
|
value = 0
|
|
|
descendant_ids = self.account_id.get_descendant_ids(leaf=True)
|
|
|
|
|
|
# 获取期末借方余额
|
|
|
if self.value_type.code == 'balance_period_end_deb':
|
|
|
if not(data_cache.get('co_accounts', False) and self.account_id in data_cache['co_accounts']):
|
|
|
balance_data_qm = data_cache.get('balance_data_qm', False)
|
|
|
if balance_data_qm is not False:
|
|
|
balance_qm = sum([balance_data_qm[descendant_id] for descendant_id in descendant_ids])
|
|
|
if balance_qm > 0:
|
|
|
value = balance_qm
|
|
|
else:
|
|
|
value = data_cache['balance_data_qm_co'][self.account_id.id]
|
|
|
|
|
|
# 获取期末贷方余额
|
|
|
elif self.value_type.code == 'balance_period_end_cre':
|
|
|
if not(data_cache.get('co_accounts', False) and self.account_id in data_cache['co_accounts']):
|
|
|
balance_data_qm = data_cache.get('balance_data_qm', False)
|
|
|
if balance_data_qm is not False:
|
|
|
balance_qm = sum([balance_data_qm[descendant_id] for descendant_id in descendant_ids])
|
|
|
if balance_qm < 0:
|
|
|
value = - balance_qm
|
|
|
else:
|
|
|
value = - data_cache['balance_data_qm_co'][self.account_id.id]
|
|
|
|
|
|
# 获取期初借方余额
|
|
|
if self.value_type.code == 'balance_period_start_deb':
|
|
|
if not(data_cache.get('co_accounts', False) and self.account_id in data_cache['co_accounts']):
|
|
|
balance_data_qc = data_cache.get('balance_data_qc', False)
|
|
|
if balance_data_qc is not False:
|
|
|
balance_qc = sum([balance_data_qc[descendant_id] for descendant_id in descendant_ids])
|
|
|
if balance_qc > 0:
|
|
|
value = balance_qc
|
|
|
|
|
|
# 获取期初贷方余额
|
|
|
elif self.value_type.code == 'balance_period_start_cre':
|
|
|
if not(data_cache.get('co_accounts', False) and self.account_id in data_cache['co_accounts']):
|
|
|
balance_data_qc = data_cache.get('balance_data_qc', False)
|
|
|
if balance_data_qc is not False:
|
|
|
balance_qc = sum([balance_data_qc[descendant_id] for descendant_id in descendant_ids])
|
|
|
if balance_qc < 0:
|
|
|
value = - balance_qc
|
|
|
|
|
|
# 获取年初借方余额
|
|
|
elif self.value_type.code == 'balance_year_start_deb':
|
|
|
if not(data_cache.get('co_accounts', False) and self.account_id in data_cache['co_accounts']):
|
|
|
balance_data_nc = data_cache.get('balance_data_nc', False)
|
|
|
if balance_data_nc is not False:
|
|
|
balance_nc = sum([balance_data_nc[descendant_id] for descendant_id in descendant_ids])
|
|
|
if balance_nc > 0:
|
|
|
value = balance_nc
|
|
|
else:
|
|
|
value = data_cache['balance_data_nc_co'][self.account_id.id]
|
|
|
|
|
|
# 获取年初贷方余额
|
|
|
elif self.value_type.code == 'balance_year_start_cre':
|
|
|
if not(data_cache.get('co_accounts', False) and self.account_id in data_cache['co_accounts']):
|
|
|
balance_data_nc = data_cache.get('balance_data_nc', False)
|
|
|
if balance_data_nc is not False:
|
|
|
balance_nc = sum([balance_data_nc[descendant_id] for descendant_id in descendant_ids])
|
|
|
if balance_nc < 0:
|
|
|
value = - balance_nc
|
|
|
else:
|
|
|
value = - data_cache['balance_data_nc_co'][self.account_id.id]
|
|
|
|
|
|
# 获取本期借方发生
|
|
|
elif self.value_type.code == 'period_deb':
|
|
|
occur_data_bq = data_cache.get('occur_data_bq', False)
|
|
|
if occur_data_bq is not False:
|
|
|
value = sum([occur_data_bq[descendant_id][0] for descendant_id in descendant_ids])
|
|
|
|
|
|
# 获取本期贷方发生
|
|
|
elif self.value_type.code == 'period_cre':
|
|
|
occur_data_bq = data_cache.get('occur_data_bq', False)
|
|
|
if occur_data_bq is not False:
|
|
|
value = sum([occur_data_bq[descendant_id][1] for descendant_id in descendant_ids])
|
|
|
|
|
|
# 获取本年借方发生
|
|
|
elif self.value_type.code == 'fiscalyear_deb':
|
|
|
occur_data_bn = data_cache.get('occur_data_bn', False)
|
|
|
if occur_data_bn is not False:
|
|
|
value = sum([occur_data_bn[descendant_id][0] for descendant_id in descendant_ids])
|
|
|
|
|
|
# 获取本年贷方发生
|
|
|
elif self.value_type.code == 'fiscalyear_cre':
|
|
|
occur_data_bn = data_cache.get('occur_data_bn', False)
|
|
|
if occur_data_bn is not False:
|
|
|
value = sum([occur_data_bn[descendant_id][1] for descendant_id in descendant_ids])
|
|
|
|
|
|
# return value
|
|
|
return value
|
|
|
|
|
|
def _get_profit_value(self, data_cache):
|
|
|
|
|
|
self.ensure_one()
|
|
|
|
|
|
if not self.account_id:
|
|
|
raise ValidationError('取值科目不能为空!')
|
|
|
|
|
|
value = 0
|
|
|
occur_data_bn = data_cache['occur_data_bn']
|
|
|
occur_data_bq = data_cache['occur_data_bq']
|
|
|
descendant_ids = self.account_id.get_descendant_ids(leaf=True)
|
|
|
|
|
|
# 获取本年借方发生
|
|
|
if self.value_type.code == 'fiscalyear_deb':
|
|
|
value = sum([occur_data_bn[descendant_id][0] for descendant_id in descendant_ids])
|
|
|
|
|
|
# 获取本年贷方发生
|
|
|
elif self.value_type.code == 'fiscalyear_cre':
|
|
|
value = sum([occur_data_bn[descendant_id][1] for descendant_id in descendant_ids])
|
|
|
|
|
|
# 获取本期借方发生
|
|
|
elif self.value_type.code == 'period_deb':
|
|
|
value = sum([occur_data_bq[descendant_id][0] for descendant_id in descendant_ids])
|
|
|
|
|
|
# 获取本期贷方发生
|
|
|
elif self.value_type.code == 'period_cre':
|
|
|
value = sum([occur_data_bq[descendant_id][1] for descendant_id in descendant_ids])
|
|
|
|
|
|
return value
|
|
|
|
|
|
def _get_cash_flow_value(self, data_cache):
|
|
|
"""单实例方法:从现金流量项目计算取值"""
|
|
|
self.ensure_one()
|
|
|
|
|
|
if not self.cash_flow_id:
|
|
|
raise ValidationError('现金流量项目不能为空!')
|
|
|
|
|
|
value = 0
|
|
|
cash_flow_data_bn = data_cache['cash_flow_data_bn']
|
|
|
cash_flow_data_bq = data_cache['cash_flow_data_bq']
|
|
|
|
|
|
# 获取本年借方差额
|
|
|
if self.value_type.code == 'fiscalyear_deb_diff':
|
|
|
value = cash_flow_data_bn[self.cash_flow_id.id][0]
|
|
|
|
|
|
elif self.value_type.code == 'fiscalyear_cre_diff':
|
|
|
value = cash_flow_data_bn[self.cash_flow_id.id][1]
|
|
|
|
|
|
elif self.value_type.code == 'period_deb_diff':
|
|
|
value = cash_flow_data_bq[self.cash_flow_id.id][0]
|
|
|
|
|
|
elif self.value_type.code == 'period_cre_diff':
|
|
|
value = cash_flow_data_bq[self.cash_flow_id.id][1]
|
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
class AccountLedgerValueType(models.Model):
|
|
|
_name = 'account.ledger.value.type'
|
|
|
_description = '报表取值类型'
|
|
|
_order = 'sequence'
|
|
|
|
|
|
sequence = fields.Integer(string='序号')
|
|
|
code = fields.Char(string='代码', required=True)
|
|
|
name = fields.Char(string='名称', required=True)
|
|
|
value_type = fields.Selection([
|
|
|
('ledger_line', '科目余额表'),
|
|
|
('cash_flow', '现金流量表项目'),
|
|
|
], string='取值类型', required=True)
|
|
|
|
|
|
|
|
|
class AccountCashFlow(models.Model):
|
|
|
_name = 'account.cash.flow'
|
|
|
_description = '现金流量项目'
|
|
|
|
|
|
name = fields.Char(string='名称')
|
|
|
code = fields.Char(string='代码')
|
|
|
company_id = fields.Many2one('res.company', string='公司', default=lambda self: self.env.user.company_id.id)
|