mis-builder/mis_builder_budget/models/mis_report_instance.py
2024-05-03 10:57:01 +02:00

120 lines
4.4 KiB
Python

# Copyright 2017 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from flectra import api, models
from flectra.osv.expression import AND
from flectra.addons.mis_builder.models.accounting_none import AccountingNone
from flectra.addons.mis_builder.models.expression_evaluator import ExpressionEvaluator
from .mis_report_instance_period import SRC_MIS_BUDGET, SRC_MIS_BUDGET_BY_ACCOUNT
class MisBudgetAwareExpressionEvaluator(ExpressionEvaluator):
def __init__(self, date_from, date_to, kpi_data, additional_move_line_filter):
super().__init__(
aep=None,
date_from=date_from,
date_to=date_to,
additional_move_line_filter=additional_move_line_filter,
aml_model=None,
)
self.kpi_data = kpi_data
@api.model
def _get_kpi_for_expressions(self, expressions):
kpi = None
for expression in expressions:
if not expression:
continue
if kpi is None:
kpi = expression.kpi_id
else:
assert (
kpi == expression.kpi_id
), "expressions must belong to the same kpi"
return kpi
def eval_expressions(self, expressions, locals_dict):
kpi = self._get_kpi_for_expressions(expressions)
if kpi and kpi.budgetable:
vals = []
drilldown_args = []
for expression in expressions:
vals.append(self.kpi_data.get(expression, AccountingNone))
drilldown_args.append({"expr_id": expression.id})
return vals, drilldown_args, False
return super().eval_expressions(expressions, locals_dict)
class MisReportInstance(models.Model):
_inherit = "mis.report.instance"
def _add_column_mis_budget(self, aep, kpi_matrix, period, label, description):
# fetch budget data for the period
base_domain = AND(
[
[("budget_id", "=", period.source_mis_budget_id.id)],
period._get_additional_budget_item_filter(),
]
)
kpi_data = self.env["mis.budget.item"]._query_kpi_data(
period.date_from, period.date_to, base_domain
)
expression_evaluator = MisBudgetAwareExpressionEvaluator(
period.date_from,
period.date_to,
kpi_data,
period._get_additional_move_line_filter(),
)
return self.report_id._declare_and_compute_period(
expression_evaluator,
kpi_matrix,
period.id,
label,
description,
period.subkpi_ids,
period._get_additional_query_filter,
no_auto_expand_accounts=self.no_auto_expand_accounts,
)
def _add_column(self, aep, kpi_matrix, period, label, description):
if period.source == SRC_MIS_BUDGET:
return self._add_column_mis_budget(
aep, kpi_matrix, period, label, description
)
elif period.source == SRC_MIS_BUDGET_BY_ACCOUNT:
return self._add_column_move_lines(
aep, kpi_matrix, period, label, description
)
else:
return super()._add_column(aep, kpi_matrix, period, label, description)
def drilldown(self, arg):
self.ensure_one()
period_id = arg.get("period_id")
if period_id:
period = self.env["mis.report.instance.period"].browse(period_id)
if period.source == SRC_MIS_BUDGET:
expr_id = arg.get("expr_id")
if not expr_id:
return False
domain = [
("date_from", "<=", period.date_to),
("date_to", ">=", period.date_from),
("kpi_expression_id", "=", expr_id),
("budget_id", "=", period.source_mis_budget_id.id),
]
domain.extend(period._get_additional_budget_item_filter())
return {
"name": period.name,
"domain": domain,
"type": "ir.actions.act_window",
"res_model": "mis.budget.item",
"views": [[False, "list"], [False, "form"]],
"view_mode": "list",
"target": "current",
}
return super().drilldown(arg)