-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #69 from Escodoo/14.0-add-mis_builder_kpi_code
[14.0][ADD] mis_builder_kpi_code: add new module
- Loading branch information
Showing
21 changed files
with
966 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
==================== | ||
MIS Builder KPI Code | ||
==================== | ||
|
||
.. | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! source digest: sha256:de0015ad668a8823ac2513115d7e71cae0d60124519c91a708190607873cbf07 | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png | ||
:target: https://odoo-community.org/page/development-status | ||
:alt: Beta | ||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png | ||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html | ||
:alt: License: AGPL-3 | ||
.. |badge3| image:: https://img.shields.io/badge/github-Escodoo%2Faccount--addons-lightgray.png?logo=github | ||
:target: https://github.com/Escodoo/account-addons/tree/14.0/mis_builder_kpi_code | ||
:alt: Escodoo/account-addons | ||
|
||
|badge1| |badge2| |badge3| | ||
|
||
This module includes the option to fill in the code field when creating a KPI in the MIS Report Template. This code field will be visible in the MIS Report Preview in the first column and will also be included when exporting documents to PDF or XLSX formats. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
1. Fill in the code field when creating or editing a KPI in a MIS Report Template. | ||
2. Open a MIS Report using this Template and see the new column in Preview Mode or in the exported PDF or XLSX files. | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/Escodoo/account-addons/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us to smash it by providing a detailed and welcomed | ||
`feedback <https://github.com/Escodoo/account-addons/issues/new?body=module:%20mis_builder_kpi_code%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Authors | ||
~~~~~~~ | ||
|
||
* Escodoo | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* `Escodoo <https://www.escodoo.com.br>`_: | ||
|
||
* Marcel Savegnago <[email protected]> | ||
* Wesley Oliveira <[email protected]> | ||
|
||
Maintainers | ||
~~~~~~~~~~~ | ||
|
||
This module is part of the `Escodoo/account-addons <https://github.com/Escodoo/account-addons/tree/14.0/mis_builder_kpi_code>`_ project on GitHub. | ||
|
||
You are welcome to contribute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import models | ||
from . import report |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright 2024 - TODAY, Escodoo | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
{ | ||
"name": "MIS Builder KPI Code", | ||
"summary": """ | ||
MIS Builder KPI Code""", | ||
"version": "14.0.1.0.0", | ||
"license": "AGPL-3", | ||
"author": "Escodoo", | ||
"website": "https://github.com/Escodoo/account-addons", | ||
"depends": ["mis_builder"], | ||
"data": [ | ||
"views/mis_report.xml", | ||
"report/mis_report_instance_qweb.xml", | ||
], | ||
"qweb": [ | ||
"static/src/xml/mis_report_widget.xml", | ||
], | ||
"demo": [], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import mis_report | ||
from . import mis_report_instance |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Copyright 2024 - TODAY, Wesley Oliveira <[email protected]> | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import fields, models | ||
|
||
|
||
class MisReportKpi(models.Model): | ||
|
||
_inherit = "mis.report.kpi" | ||
|
||
code = fields.Char() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Copyright 2024 - TODAY, Wesley Oliveira <[email protected]> | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import models | ||
|
||
|
||
class MisReportInstance(models.Model): | ||
|
||
_inherit = "mis.report.instance" | ||
|
||
def compute(self): | ||
self.ensure_one() | ||
kpi_matrix = self._compute_matrix() | ||
kpi_matrix_dict = kpi_matrix.as_dict() | ||
|
||
empty_col = [{"label": "", "description": "", "colspan": 1}] | ||
kpi_matrix_dict["header"][0]["cols"] = ( | ||
empty_col + kpi_matrix_dict["header"][0]["cols"] | ||
) | ||
kpi_matrix_dict["header"][1]["cols"] = ( | ||
empty_col + kpi_matrix_dict["header"][1]["cols"] | ||
) | ||
|
||
for idx, row in enumerate(kpi_matrix_dict["body"]): | ||
code = self.report_id.kpi_ids.filtered( | ||
lambda k: k.name == row["row_id"] | ||
).code | ||
kpi_matrix_dict["body"][idx].update({"code": code}) | ||
|
||
return kpi_matrix_dict |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
* `Escodoo <https://www.escodoo.com.br>`_: | ||
|
||
* Marcel Savegnago <[email protected]> | ||
* Wesley Oliveira <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This module includes the option to fill in the code field when creating a KPI in the MIS Report Template. This code field will be visible in the MIS Report Preview in the first column and will also be included when exporting documents to PDF or XLSX formats. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
To use this module, you need to: | ||
|
||
1. Fill in the code field when creating or editing a KPI in a MIS Report Template. | ||
2. Open a MIS Report using this Template and see the new column in Preview Mode or in the exported PDF or XLSX files. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import mis_report_instance_xlsx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<!-- Copyright 2024 - TODAY, Wesley Oliveira <[email protected]> | ||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> | ||
<odoo> | ||
<template | ||
id="assets_report" | ||
name="mis_builder_kpi_code" | ||
inherit_id="web.report_assets_common" | ||
> | ||
<xpath expr="." position="inside"> | ||
<link | ||
href="/mis_builder_kpi_code/static/src/css/report.css" | ||
rel="stylesheet" | ||
/> | ||
</xpath> | ||
</template> | ||
<template | ||
id="report_mis_report_instance" | ||
inherit_id="mis_builder.report_mis_report_instance" | ||
> | ||
<xpath | ||
expr="//div[hasclass('mis_thead')]/div[hasclass('mis_row')][1]/div[hasclass('mis_collabel')][1]" | ||
position="before" | ||
> | ||
<div class="mis_cell mis_collabel" /> | ||
</xpath> | ||
<xpath | ||
expr="//div[hasclass('mis_thead')]/div[hasclass('mis_row')][2]/div[hasclass('mis_collabel')][1]" | ||
position="before" | ||
> | ||
<div class="mis_cell mis_collabel" /> | ||
</xpath> | ||
<xpath | ||
expr="//div[hasclass('mis_tbody')]/t[@t-as='row']/div[hasclass('mis_row')]/div[hasclass('mis_rowlabel')]" | ||
position="before" | ||
> | ||
<div | ||
t-att-style="style_obj.to_css_style(row.style_props)" | ||
class="mis_cell mis_rowlabel" | ||
> | ||
<t | ||
t-set="code" | ||
t-value="o.report_id.kpi_ids.filtered(lambda k: k.id == row.kpi.id).code" | ||
/> | ||
<t t-esc="code or ''" /> | ||
</div> | ||
</xpath> | ||
</template> | ||
</odoo> |
181 changes: 181 additions & 0 deletions
181
mis_builder_kpi_code/report/mis_report_instance_xlsx.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
# Copyright 2024 - TODAY, Wesley Oliveira <[email protected]> | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
import logging | ||
import numbers | ||
from collections import defaultdict | ||
from datetime import datetime | ||
|
||
from odoo import _, fields, models | ||
|
||
from odoo.addons.mis_builder.models.accounting_none import AccountingNone | ||
from odoo.addons.mis_builder.models.data_error import DataError | ||
from odoo.addons.mis_builder.models.mis_report_style import TYPE_STR | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
ROW_HEIGHT = 15 # xlsxwriter units | ||
COL_WIDTH = 0.9 # xlsxwriter units | ||
MIN_COL_WIDTH = 10 # characters | ||
MAX_COL_WIDTH = 50 # characters | ||
|
||
|
||
class MisBuilderXlsx(models.AbstractModel): | ||
_inherit = "report.mis_builder.mis_report_instance_xlsx" | ||
|
||
def generate_xlsx_report(self, workbook, data, objects): | ||
|
||
# get the computed result of the report | ||
matrix = objects._compute_matrix() | ||
style_obj = self.env["mis.report.style"] | ||
|
||
# create worksheet | ||
report_name = "{} - {}".format( | ||
objects[0].name, ", ".join([a.name for a in objects[0].query_company_ids]) | ||
) | ||
sheet = workbook.add_worksheet(report_name[:31]) | ||
row_pos = 0 | ||
col_pos = 0 | ||
# width of the labels column | ||
label_col_width = MIN_COL_WIDTH | ||
# {col_pos: max width in characters} | ||
col_width = defaultdict(lambda: MIN_COL_WIDTH) | ||
|
||
# document title | ||
bold = workbook.add_format({"bold": True}) | ||
header_format = workbook.add_format( | ||
{"bold": True, "align": "center", "bg_color": "#F0EEEE"} | ||
) | ||
sheet.write(row_pos, 0, report_name, bold) | ||
row_pos += 2 | ||
|
||
# filters | ||
if not objects.hide_analytic_filters: | ||
for filter_description in objects.get_filter_descriptions_from_context(): | ||
sheet.write(row_pos, 0, filter_description) | ||
row_pos += 1 | ||
row_pos += 1 | ||
|
||
# column headers | ||
sheet.write(row_pos, 0, "", header_format) | ||
sheet.write(row_pos, 1, "", header_format) | ||
col_pos = 2 | ||
for col in matrix.iter_cols(): | ||
label = col.label | ||
if col.description: | ||
label += "\n" + col.description | ||
sheet.set_row(row_pos, ROW_HEIGHT * 2) | ||
if col.colspan > 1: | ||
sheet.merge_range( | ||
row_pos, | ||
col_pos, | ||
row_pos, | ||
col_pos + col.colspan - 1, | ||
label, | ||
header_format, | ||
) | ||
else: | ||
sheet.write(row_pos, col_pos, label, header_format) | ||
col_width[col_pos] = max( | ||
col_width[col_pos], len(col.label or ""), len(col.description or "") | ||
) | ||
col_pos += col.colspan | ||
row_pos += 1 | ||
|
||
# sub column headers | ||
sheet.write(row_pos, 0, "", header_format) | ||
sheet.write(row_pos, 1, "", header_format) | ||
col_pos = 2 | ||
for subcol in matrix.iter_subcols(): | ||
label = subcol.label | ||
if subcol.description: | ||
label += "\n" + subcol.description | ||
sheet.set_row(row_pos, ROW_HEIGHT * 2) | ||
sheet.write(row_pos, col_pos, label, header_format) | ||
col_width[col_pos] = max( | ||
col_width[col_pos], | ||
len(subcol.label or ""), | ||
len(subcol.description or ""), | ||
) | ||
col_pos += 1 | ||
row_pos += 1 | ||
|
||
# rows | ||
for row in matrix.iter_rows(): | ||
if ( | ||
row.style_props.hide_empty and row.is_empty() | ||
) or row.style_props.hide_always: | ||
continue | ||
row_xlsx_style = style_obj.to_xlsx_style(TYPE_STR, row.style_props) | ||
row_format = workbook.add_format(row_xlsx_style) | ||
col_pos = 0 | ||
|
||
code = ( | ||
objects[0].report_id.kpi_ids.filtered(lambda k: k.id == row.kpi.id).code | ||
) | ||
sheet.write(row_pos, col_pos, code, row_format) | ||
col_pos += 1 | ||
|
||
label = row.label | ||
if row.description: | ||
label += "\n" + row.description | ||
sheet.set_row(row_pos, ROW_HEIGHT * 2) | ||
sheet.write(row_pos, col_pos, label, row_format) | ||
label_col_width = max( | ||
label_col_width, len(row.label or ""), len(row.description or "") | ||
) | ||
for cell in row.iter_cells(): | ||
col_pos += 1 | ||
if not cell or cell.val is AccountingNone: | ||
# TODO col/subcol format | ||
sheet.write(row_pos, col_pos, "", row_format) | ||
continue | ||
cell_xlsx_style = style_obj.to_xlsx_style( | ||
cell.val_type, cell.style_props, no_indent=True | ||
) | ||
cell_xlsx_style["align"] = "right" | ||
cell_format = workbook.add_format(cell_xlsx_style) | ||
if isinstance(cell.val, DataError): | ||
val = cell.val.name | ||
# TODO display cell.val.msg as Excel comment? | ||
elif cell.val is None or cell.val is AccountingNone: | ||
val = "" | ||
else: | ||
divider = float(cell.style_props.get("divider", 1)) | ||
if ( | ||
divider != 1 | ||
and isinstance(cell.val, numbers.Number) | ||
and not cell.val_type == "pct" | ||
): | ||
val = cell.val / divider | ||
else: | ||
val = cell.val | ||
sheet.write(row_pos, col_pos, val, cell_format) | ||
col_width[col_pos] = max( | ||
col_width[col_pos], len(cell.val_rendered or "") | ||
) | ||
row_pos += 1 | ||
|
||
# Add date/time footer | ||
row_pos += 1 | ||
footer_format = workbook.add_format( | ||
{"italic": True, "font_color": "#202020", "size": 9} | ||
) | ||
lang_model = self.env["res.lang"] | ||
lang = lang_model._lang_get(self.env.user.lang) | ||
|
||
now_tz = fields.Datetime.context_timestamp( | ||
self.env["res.users"], datetime.now() | ||
) | ||
create_date = _("Generated on {} at {}").format( | ||
now_tz.strftime(lang.date_format), now_tz.strftime(lang.time_format) | ||
) | ||
sheet.write(row_pos, 0, create_date, footer_format) | ||
|
||
# adjust col widths | ||
sheet.set_column(0, 1, min(label_col_width, MAX_COL_WIDTH) * COL_WIDTH) | ||
data_col_width = min(MAX_COL_WIDTH, max(col_width.values())) | ||
min_col_pos = min(col_width.keys()) | ||
max_col_pos = max(col_width.keys()) | ||
sheet.set_column(min_col_pos, max_col_pos, data_col_width * COL_WIDTH) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.