1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/account_consolidation/report/builder/comparison.py
2024-12-10 09:04:09 +07:00

100 lines
4.2 KiB
Python

from math import copysign
from odoo import _
from odoo.tools.float_utils import float_is_zero
from .abstract import AbstractBuilder
class ComparisonBuilder(AbstractBuilder):
# OVERRIDES
def _get_params(self, period_ids: list, options: dict, line_id: str = None) -> dict:
chart_ids = self.env['consolidation.chart'].search([('period_ids', 'in', period_ids)]).ids
cols_amount = len(period_ids)
include_percentage = cols_amount == 2
params = super()._get_params(period_ids, options, line_id)
params.update({
'chart_ids': chart_ids,
'cols_amount': cols_amount,
'include_percentage': include_percentage,
})
return params
def _output_will_be_empty(self, period_ids: list, options: dict, line_id: str = None) -> bool:
return len(period_ids) == 0
def _compute_account_totals(self, account, **kwargs) -> list:
domain = [
('account_id', '=', account.id),
('period_id', 'in', kwargs.get('period_ids', []))
]
total_lines = self.env['consolidation.journal.line']._read_group(domain, ['period_id'], ['amount:sum'])
if len(total_lines) == 0:
return []
totals = []
total_dict = {period.id: total for period, total in total_lines}
# Need to keep the order of periods as nothing in DB can order them
for period_id in kwargs.get('period_ids', []):
totals.append(account.sign * total_dict.get(period_id, 0.0))
return totals
def _get_default_line_totals(self, options: dict, **kwargs) -> list:
return kwargs.get('cols_amount', len(kwargs.get('period_ids', []))) * [0.0]
def _format_account_line(self, account, parent_id, level: int, totals: list, options: dict, **kwargs) -> dict:
account_line = super()._format_account_line(account, parent_id, level, totals, options, **kwargs)
if kwargs.get('include_percentage', False) and totals and account_line:
account_line['columns'].append(self._build_percentage_column(*totals))
return account_line
def _build_section_line(self, section, level: int, options: dict, **kwargs):
section_totals, section_lines = super()._build_section_line(section, level, options, **kwargs)
if kwargs.get('include_percentage', False) and section_totals and section_lines:
section_lines[0]['columns'].append(self._build_percentage_column(*section_totals))
return section_totals, section_lines
def _build_total_line(self, totals: list, options: dict, **kwargs) -> dict:
total_line = super()._build_total_line(totals, options, **kwargs)
if kwargs.get('include_percentage', False) and total_line and totals:
total_line['columns'].append(self._build_percentage_column(*totals))
return total_line
@staticmethod
def _build_percentage_column(orig_value: float, now_value: float) -> dict:
"""
Build the percentage column based on the two given values
:param orig_value: the original value
:type orig_value: float
:param now_value: the value of now
:type now_value: float
:return: a formatted dict containing the percentage increase between the two given values and ready to be added
as a column inside a report line
:rtype: dict
"""
if not float_is_zero(orig_value, 6):
res = round((now_value - orig_value) / orig_value * 100, 1)
classes = ['number']
if float_is_zero(res, precision_rounding=0.1):
val = 0.0
elif (res > 0) == (orig_value > 0):
classes.append('color-green')
val = copysign(res, 1)
else:
classes.append('color-red')
val = copysign(res, -1)
return {
'name': ('%s%%' % val),
'no_format': val,
'figure_type': 'percentage',
'class': ' '.join(classes)
}
# res > 0
# orig > 0 :: GREEN
# orig < 0 :: RED
# res < 0
# orig < 0 :: GREEN
# orig > 0 :: RED
else:
return {'name': _('n/a'), 'figure_type': 'percentage'}