OCA-git-bot
4 years ago
23 changed files with 929 additions and 0 deletions
-
21mis_builder_cash_flow/README.rst
-
4mis_builder_cash_flow/__init__.py
-
26mis_builder_cash_flow/__manifest__.py
-
105mis_builder_cash_flow/data/mis_report.xml
-
146mis_builder_cash_flow/data/mis_report_instance.xml
-
71mis_builder_cash_flow/data/mis_report_style.xml
-
4mis_builder_cash_flow/models/__init__.py
-
12mis_builder_cash_flow/models/account_account.py
-
44mis_builder_cash_flow/models/mis_cash_flow_forecast_line.py
-
3mis_builder_cash_flow/readme/CONTRIBUTORS.rst
-
5mis_builder_cash_flow/readme/DESCRIPTION.rst
-
3mis_builder_cash_flow/readme/ROADMAP.rst
-
4mis_builder_cash_flow/readme/USAGE.rst
-
3mis_builder_cash_flow/report/__init__.py
-
132mis_builder_cash_flow/report/mis_cash_flow.py
-
92mis_builder_cash_flow/report/mis_cash_flow_views.xml
-
27mis_builder_cash_flow/security/mis_cash_flow_security.xml
-
BINmis_builder_cash_flow/static/description/icon.png
-
1mis_builder_cash_flow/tests/__init__.py
-
130mis_builder_cash_flow/tests/test_cash_flow.py
-
14mis_builder_cash_flow/views/account_account_views.xml
-
81mis_builder_cash_flow/views/mis_cash_flow_forecast_line_views.xml
-
1oca_dependencies.txt
@ -0,0 +1,21 @@ |
|||||
|
**This file is going to be generated by oca-gen-addon-readme.** |
||||
|
|
||||
|
*Manual changes will be overwritten.* |
||||
|
|
||||
|
Please provide content in the ``readme`` directory: |
||||
|
|
||||
|
* **DESCRIPTION.rst** (required) |
||||
|
* INSTALL.rst (optional) |
||||
|
* CONFIGURE.rst (optional) |
||||
|
* **USAGE.rst** (optional, highly recommended) |
||||
|
* DEVELOP.rst (optional) |
||||
|
* ROADMAP.rst (optional) |
||||
|
* HISTORY.rst (optional, recommended) |
||||
|
* **CONTRIBUTORS.rst** (optional, highly recommended) |
||||
|
* CREDITS.rst (optional) |
||||
|
|
||||
|
Content of this README will also be drawn from the addon manifest, |
||||
|
from keys such as name, authors, maintainers, development_status, |
||||
|
and license. |
||||
|
|
||||
|
A good, one sentence summary in the manifest is also highly recommended. |
@ -0,0 +1,4 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
from . import models |
||||
|
from . import report |
@ -0,0 +1,26 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
{ |
||||
|
'name': 'MIS Builder Cash Flow', |
||||
|
'version': '11.0.1.1.0', |
||||
|
'license': 'LGPL-3', |
||||
|
'author': 'ADHOC SA, ' |
||||
|
'Odoo Community Association (OCA)', |
||||
|
'website': 'https://github.com/OCA/mis-builder', |
||||
|
'depends': [ |
||||
|
'mis_builder', |
||||
|
], |
||||
|
'data': [ |
||||
|
'security/mis_cash_flow_security.xml', |
||||
|
'report/mis_cash_flow_views.xml', |
||||
|
'views/mis_cash_flow_forecast_line_views.xml', |
||||
|
'views/account_account_views.xml', |
||||
|
'data/mis_report_style.xml', |
||||
|
'data/mis_report.xml', |
||||
|
'data/mis_report_instance.xml', |
||||
|
], |
||||
|
'installable': True, |
||||
|
'maintainers': ['jjscarafia'], |
||||
|
'development_status': 'Beta', |
||||
|
} |
@ -0,0 +1,105 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2019 ADHOC SA |
||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> |
||||
|
|
||||
|
<odoo noupdate="True"> |
||||
|
|
||||
|
<record id="mis_report_cash_flow" model="mis.report"> |
||||
|
<field name="name">Cash Flow</field> |
||||
|
<field name="style_id" ref="mis_style_cash_flow"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_aliquidity" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">liquidity</field> |
||||
|
<field name="description">LIQUIDITY</field> |
||||
|
<field name="style_id" ref="mis_style_account_sub_total"/> |
||||
|
<field name="auto_expand_accounts" eval="True"/> |
||||
|
<field name="auto_expand_accounts_style_id" ref="mis_style_account_detail"/> |
||||
|
<field name="sequence">20</field> |
||||
|
<field name="expression">bal[][('account_id.internal_type', '=', 'liquidity'), ('line_type', '=', 'move_line'), ('account_id.hide_in_cash_flow', '=', False)]</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_in_total" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">in_total</field> |
||||
|
<field name="description">IN TOTAL</field> |
||||
|
<field name="style_id" ref="mis_style_account_sub_total"/> |
||||
|
<field name="sequence">30</field> |
||||
|
<field name="expression">in_receivable + in_forecast</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_in_receivable" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">in_receivable</field> |
||||
|
<field name="description">In receivable</field> |
||||
|
<field name="style_id" ref="mis_style_account_line"/> |
||||
|
<field name="auto_expand_accounts" eval="True"/> |
||||
|
<field name="auto_expand_accounts_style_id" ref="mis_style_account_detail"/> |
||||
|
<field name="sequence">50</field> |
||||
|
<field name="expression">bal[][('account_id.internal_type', '=', 'receivable'), ('full_reconcile_id', '=', False), ('line_type', '=', 'move_line'), ('account_id.hide_in_cash_flow', '=', False)]</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_in_forecast" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">in_forecast</field> |
||||
|
<field name="description">In forecast</field> |
||||
|
<field name="style_id" ref="mis_style_account_line"/> |
||||
|
<field name="auto_expand_accounts" eval="True"/> |
||||
|
<field name="auto_expand_accounts_style_id" ref="mis_style_account_detail"/> |
||||
|
<field name="sequence">70</field> |
||||
|
<field name="expression">bal[][('line_type', '=', 'forecast_line'), ('debit', '!=', 0.0), ('account_id.hide_in_cash_flow', '=', False)]</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_out_total" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">out_total</field> |
||||
|
<field name="description">OUT TOTAL</field> |
||||
|
<field name="style_id" ref="mis_style_account_sub_total"/> |
||||
|
<field name="sequence">80</field> |
||||
|
<field name="expression">out_payable + out_forecast</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_out_payable" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">out_payable</field> |
||||
|
<field name="description">Out payable</field> |
||||
|
<field name="style_id" ref="mis_style_account_line"/> |
||||
|
<field name="auto_expand_accounts" eval="True"/> |
||||
|
<field name="auto_expand_accounts_style_id" ref="mis_style_account_detail"/> |
||||
|
<field name="sequence">100</field> |
||||
|
<field name="expression">bal[][('account_id.internal_type', '=', 'payable'), ('full_reconcile_id', '=', False), ('line_type', '=', 'move_line'), ('account_id.hide_in_cash_flow', '=', False)]</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_out_forecast" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">out_forecast</field> |
||||
|
<field name="description">Out forecast</field> |
||||
|
<field name="style_id" ref="mis_style_account_line"/> |
||||
|
<field name="auto_expand_accounts" eval="True"/> |
||||
|
<field name="auto_expand_accounts_style_id" ref="mis_style_account_detail"/> |
||||
|
<field name="sequence">120</field> |
||||
|
<field name="expression">bal[][('line_type', '=', 'forecast_line'), ('credit', '!=', 0.0), ('account_id.hide_in_cash_flow', '=', False)]</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_period_balance" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">period_balance</field> |
||||
|
<field name="description">PERIOD BALANCE</field> |
||||
|
<field name="style_id" ref="mis_style_account_sub_total"/> |
||||
|
<field name="sequence">130</field> |
||||
|
<field name="expression">in_total + out_total</field> |
||||
|
<field name="style_expression">'Cash Flow - Good' if period_balance >= 0.0 else 'Cash Flow - Bad'</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_kpi_balance" model="mis.report.kpi"> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="name">balance</field> |
||||
|
<field name="description">BALANCE</field> |
||||
|
<field name="style_id" ref="mis_style_account_total"/> |
||||
|
<field name="sequence">150</field> |
||||
|
<field name="expression">bale[][('account_id.hide_in_cash_flow', '=', False), '|', ('line_type', '=', 'forecast_line'), ('line_type', '=', 'move_line'), '|', ('account_id.internal_type', '=', 'liquidity'), ('account_id.internal_type', 'in', ('receivable', 'payable')), ('full_reconcile_id', '=', False)]</field> |
||||
|
<field name="style_expression">'Cash Flow - Good' if balance >= 0.0 else 'Cash Flow - Bad'</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,146 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2019 ADHOC SA |
||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> |
||||
|
|
||||
|
<odoo noupdate="True"> |
||||
|
|
||||
|
<record id="mis_instance_cash_flow" model="mis.report.instance"> |
||||
|
<field name="name">Cash Flow</field> |
||||
|
<field name="report_id" ref="mis_report_cash_flow"/> |
||||
|
<field name="comparison_mode" eval="True"/> |
||||
|
<field name="landscape_pdf" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_current" model="mis.report.instance.period"> |
||||
|
<field name="name">Current</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">-4000</field> |
||||
|
<field name="duration">4001</field> |
||||
|
<field name="sequence">4</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_1w" model="mis.report.instance.period"> |
||||
|
<field name="name">+1w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">1</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">10</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_2w" model="mis.report.instance.period"> |
||||
|
<field name="name">+2w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">2</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">20</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_3w" model="mis.report.instance.period"> |
||||
|
<field name="name">+3w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">3</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">30</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_4w" model="mis.report.instance.period"> |
||||
|
<field name="name">+4w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">4</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">40</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_5w" model="mis.report.instance.period"> |
||||
|
<field name="name">+5w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">5</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">50</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_6w" model="mis.report.instance.period"> |
||||
|
<field name="name">+6w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">6</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">60</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_7w" model="mis.report.instance.period"> |
||||
|
<field name="name">+7w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">7</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">70</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_8w" model="mis.report.instance.period"> |
||||
|
<field name="name">+8w</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">8</field> |
||||
|
<field name="duration">1</field> |
||||
|
<field name="sequence">80</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_third_month" model="mis.report.instance.period"> |
||||
|
<field name="name">third month</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">9</field> |
||||
|
<field name="duration">4</field> |
||||
|
<field name="sequence">90</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_period_plus_fourth_month" model="mis.report.instance.period"> |
||||
|
<field name="name">fourth month</field> |
||||
|
<field name="report_instance_id" ref="mis_instance_cash_flow"/> |
||||
|
<field name="source">actuals_alt</field> |
||||
|
<field name="source_aml_model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="mode">relative</field> |
||||
|
<field name="type">w</field> |
||||
|
<field name="offset">13</field> |
||||
|
<field name="duration">4</field> |
||||
|
<field name="sequence">90</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,71 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2019 ADHOC SA |
||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> |
||||
|
|
||||
|
<odoo noupdate="True"> |
||||
|
|
||||
|
<record id="mis_style_cash_flow" model="mis.report.style"> |
||||
|
<field name="name">Cash Flow</field> |
||||
|
<field name="hide_empty_inherit" eval="False"/> |
||||
|
<field name="hide_empty" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_account_detail" model="mis.report.style"> |
||||
|
<field name="name">Cash flow style account detail</field> |
||||
|
<field name="font_style_inherit" eval="False"/> |
||||
|
<field name="font_style">italic</field> |
||||
|
<field name="indent_level_inherit" eval="False"/> |
||||
|
<field name="indent_level">2</field> |
||||
|
<field name="font_size_inherit" eval="False"/> |
||||
|
<field name="font_size">x-small</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_account_line" model="mis.report.style"> |
||||
|
<field name="name">Cash flow line</field> |
||||
|
<field name="color_inherit" eval="False"/> |
||||
|
<field name="color">#FFFFFF</field> |
||||
|
<field name="background_color_inherit" eval="False"/> |
||||
|
<field name="background_color">#D4AFC4</field> |
||||
|
<field name="indent_level_inherit" eval="False"/> |
||||
|
<field name="indent_level">1</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_account_sub_total" model="mis.report.style"> |
||||
|
<field name="name">Cash flow style sub-total</field> |
||||
|
<field name="color_inherit" eval="False"/> |
||||
|
<field name="color">#FFFFFF</field> |
||||
|
<field name="background_color_inherit" eval="False"/> |
||||
|
<field name="background_color">#967C8B</field> |
||||
|
<field name="font_weight_inherit" eval="False"/> |
||||
|
<field name="font_weight">bold</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_account_total" model="mis.report.style"> |
||||
|
<field name="name">Cash flow style total</field> |
||||
|
<field name="color_inherit" eval="False"/> |
||||
|
<field name="color">#FFFFFF</field> |
||||
|
<field name="background_color_inherit" eval="False"/> |
||||
|
<field name="background_color">#7A6571</field> |
||||
|
<field name="font_weight_inherit" eval="False"/> |
||||
|
<field name="font_weight">bold</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_hidden" model="mis.report.style"> |
||||
|
<field name="name">Cash Flow - hidden</field> |
||||
|
<field name="hide_always_inherit" eval="False"/> |
||||
|
<field name="hide_always" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_good" model="mis.report.style"> |
||||
|
<field name="name">Cash Flow - Good</field> |
||||
|
<field name="color_inherit" eval="False"/> |
||||
|
<field name="color">#005700</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mis_style_bad" model="mis.report.style"> |
||||
|
<field name="name">Cash Flow - Bad</field> |
||||
|
<field name="color_inherit" eval="False"/> |
||||
|
<field name="color">#7A0000</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,4 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
from . import mis_cash_flow_forecast_line |
||||
|
from . import account_account |
@ -0,0 +1,12 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountAccount(models.Model): |
||||
|
|
||||
|
_inherit = 'account.account' |
||||
|
|
||||
|
hide_in_cash_flow = fields.Boolean( |
||||
|
string='Hide in Cash Flow?', |
||||
|
) |
@ -0,0 +1,44 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
from odoo import fields, models, api, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class MisCashFlowForecastLine(models.Model): |
||||
|
|
||||
|
_name = 'mis.cash_flow.forecast_line' |
||||
|
_description = 'MIS Cash Flow Forecast Line' |
||||
|
|
||||
|
date = fields.Date( |
||||
|
required=True, |
||||
|
index=True, |
||||
|
) |
||||
|
account_id = fields.Many2one( |
||||
|
comodel_name='account.account', |
||||
|
string='Account', |
||||
|
required=True, |
||||
|
help='The account of the forecast line is only for informative ' |
||||
|
'purpose', |
||||
|
) |
||||
|
name = fields.Char( |
||||
|
required=True, |
||||
|
default='/', |
||||
|
) |
||||
|
balance = fields.Float( |
||||
|
required=True, |
||||
|
) |
||||
|
company_id = fields.Many2one( |
||||
|
'res.company', |
||||
|
string='Company', |
||||
|
required=True, |
||||
|
default=lambda self: self.env.user.company_id.id, |
||||
|
index=True, |
||||
|
) |
||||
|
|
||||
|
@api.multi |
||||
|
@api.constrains('company_id', 'account_id') |
||||
|
def _check_company_id_account_id(self): |
||||
|
if self.filtered(lambda x: x.company_id != x.account_id.company_id): |
||||
|
raise ValidationError(_( |
||||
|
'The Company and the Company of the Account must be the ' |
||||
|
'same.')) |
@ -0,0 +1,3 @@ |
|||||
|
* Juan José Scarafía <jjs@adhoc.com.ar> |
||||
|
* Gonzalo Ruzafa <gr@adhoc.com.ar> |
||||
|
* Enric Tobella <etobella@creublanca.es> |
@ -0,0 +1,5 @@ |
|||||
|
This module allows you to have a cash flow forecast. |
||||
|
The forecast is based on two types of date: |
||||
|
|
||||
|
* Accounting entries: Due date field instead of Date |
||||
|
* Forecast lines: manual lines created that forecast in/out cashflow moves. |
@ -0,0 +1,3 @@ |
|||||
|
The mis_builder `roadmap <https://github.com/OCA/mis-builder/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement>`_ |
||||
|
and `known issues <https://github.com/OCA/mis-builder/issues?q=is%3Aopen+is%3Aissue+label%3Abug>`_ can |
||||
|
be found on GitHub. |
@ -0,0 +1,4 @@ |
|||||
|
To use this module, you need to: |
||||
|
|
||||
|
#. Go to Accounting > Reports > MIS Reporting > MIS Reports and choose "Cash Flow" report |
||||
|
#. You can add forecast lines on Accounting > Reports > MIS Reporting > Cash Flow Forecast Line |
@ -0,0 +1,3 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
from . import mis_cash_flow |
@ -0,0 +1,132 @@ |
|||||
|
# Copyright 2019 ADHOC SA |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
from odoo import api, fields, models, tools |
||||
|
from psycopg2.extensions import AsIs |
||||
|
|
||||
|
|
||||
|
class MisCashFlow(models.Model): |
||||
|
|
||||
|
_name = 'mis.cash_flow' |
||||
|
_description = 'MIS Cash Flow' |
||||
|
_auto = False |
||||
|
|
||||
|
line_type = fields.Selection( |
||||
|
[('forecast_line', 'Forecast Line'), ('move_line', 'Journal Item')], |
||||
|
index=True, |
||||
|
readonly=True, |
||||
|
) |
||||
|
name = fields.Char( |
||||
|
readonly=True, |
||||
|
) |
||||
|
account_id = fields.Many2one( |
||||
|
comodel_name='account.account', |
||||
|
string='Account', |
||||
|
auto_join=True, |
||||
|
index=True, |
||||
|
readonly=True, |
||||
|
) |
||||
|
move_line_id = fields.Many2one( |
||||
|
comodel_name='account.move.line', |
||||
|
string='Journal Item', |
||||
|
auto_join=True, |
||||
|
readonly=True, |
||||
|
) |
||||
|
company_id = fields.Many2one( |
||||
|
comodel_name='res.company', |
||||
|
string='Company', |
||||
|
auto_join=True, |
||||
|
readonly=True, |
||||
|
index=True, |
||||
|
) |
||||
|
credit = fields.Float( |
||||
|
readonly=True, |
||||
|
) |
||||
|
debit = fields.Float( |
||||
|
readonly=True, |
||||
|
) |
||||
|
date = fields.Date( |
||||
|
readonly=True, |
||||
|
index=True, |
||||
|
) |
||||
|
reconciled = fields.Boolean( |
||||
|
readonly=True, |
||||
|
) |
||||
|
full_reconcile_id = fields.Many2one( |
||||
|
'account.full.reconcile', |
||||
|
string="Matching Number", |
||||
|
readonly=True, |
||||
|
index=True, |
||||
|
) |
||||
|
user_type_id = fields.Many2one( |
||||
|
'account.account.type', |
||||
|
auto_join=True, |
||||
|
readonly=True, |
||||
|
index=True, |
||||
|
) |
||||
|
|
||||
|
@api.model_cr |
||||
|
def init(self): |
||||
|
query = """ |
||||
|
SELECT |
||||
|
-- we use negative id to avoid duplicates and we don't use |
||||
|
-- ROW_NUMBER() because the performance was very poor |
||||
|
-aml.id as id, |
||||
|
CAST('move_line' AS varchar) as line_type, |
||||
|
aml.id as move_line_id, |
||||
|
aml.account_id as account_id, |
||||
|
CASE |
||||
|
WHEN aml.amount_residual > 0 |
||||
|
THEN aml.amount_residual |
||||
|
ELSE 0.0 |
||||
|
END AS debit, |
||||
|
CASE |
||||
|
WHEN aml.amount_residual < 0 |
||||
|
THEN -aml.amount_residual |
||||
|
ELSE 0.0 |
||||
|
END AS credit, |
||||
|
aml.reconciled as reconciled, |
||||
|
aml.full_reconcile_id as full_reconcile_id, |
||||
|
aml.company_id as company_id, |
||||
|
aml.user_type_id as user_type_id, |
||||
|
aml.name as name, |
||||
|
aml.date_maturity as date |
||||
|
FROM account_move_line as aml |
||||
|
UNION ALL |
||||
|
SELECT |
||||
|
fl.id as id, |
||||
|
CAST('forecast_line' AS varchar) as line_type, |
||||
|
Null as move_line_id, |
||||
|
fl.account_id as account_id, |
||||
|
CASE |
||||
|
WHEN fl.balance > 0 |
||||
|
THEN fl.balance |
||||
|
ELSE 0.0 |
||||
|
END AS debit, |
||||
|
CASE |
||||
|
WHEN fl.balance < 0 |
||||
|
THEN -fl.balance |
||||
|
ELSE 0.0 |
||||
|
END AS credit, |
||||
|
Null as reconciled, |
||||
|
Null as full_reconcile_id, |
||||
|
fl.company_id as company_id, |
||||
|
-- we dont need this field on forecast lines |
||||
|
Null as user_type_id, |
||||
|
fl.name as name, |
||||
|
fl.date as date |
||||
|
FROM mis_cash_flow_forecast_line as fl |
||||
|
""" |
||||
|
tools.drop_view_if_exists(self.env.cr, self._table) |
||||
|
self._cr.execute( |
||||
|
'CREATE OR REPLACE VIEW %s AS %s', |
||||
|
(AsIs(self._table), AsIs(query)) |
||||
|
) |
||||
|
|
||||
|
@api.multi |
||||
|
def action_open_related_line(self): |
||||
|
self.ensure_one() |
||||
|
if self.line_type == 'move_line': |
||||
|
return self.move_line_id.get_formview_action() |
||||
|
else: |
||||
|
return self.env['mis.cash_flow.forecast_line'].browse( |
||||
|
self.id).get_formview_action() |
@ -0,0 +1,92 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2019 ADHOC SA |
||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record model="ir.ui.view" id="mis_cash_flow_tree_view"> |
||||
|
<field name="name">mis.cash_flow.tree</field> |
||||
|
<field name="model">mis.cash_flow</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree create="false" edit="false" delete="false"> |
||||
|
<field name="company_id" groups="base.group_multi_company"/> |
||||
|
<field name="line_type"/> |
||||
|
<field name="date"/> |
||||
|
<field name="name"/> |
||||
|
<field name="account_id"/> |
||||
|
<field name="debit" sum="Total"/> |
||||
|
<field name="credit" sum="Total"/> |
||||
|
<button type="object" string="Open Journal Item / Forecast Line" icon="fa-external-link" name="action_open_related_line"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.ui.view" id="mis_cash_flow_form_view"> |
||||
|
<field name="name">mis.cash_flow.form</field> |
||||
|
<field name="model">mis.cash_flow</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form create="false" edit="false" delete="false"> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="date"/> |
||||
|
<field name="name"/> |
||||
|
<field name="account_id"/> |
||||
|
<field name="move_line_id"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="debit" |
||||
|
sum="Total"/> |
||||
|
<field name="credit" |
||||
|
sum="Total"/> |
||||
|
<field name="company_id" |
||||
|
groups="base.group_multi_company"/> |
||||
|
<field name="line_type"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.ui.view" id="mis_cash_flow_search_view"> |
||||
|
<field name="name">mis.cash_flow.search</field> |
||||
|
<field name="model">mis.cash_flow</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search> |
||||
|
<field name="name"/> |
||||
|
<field name="date"/> |
||||
|
<separator/> |
||||
|
<field name="account_id"/> |
||||
|
<field name="company_id" |
||||
|
groups="base.group_multi_company"/> |
||||
|
<separator/> |
||||
|
<filter string="Unreconciled" |
||||
|
domain="[('full_reconcile_id', '=', False), ('balance','!=', 0), ('account_id.reconcile','=',True)]" |
||||
|
help="Journal items where matching number isn't set" |
||||
|
name="unreconciled"/> |
||||
|
<separator/> |
||||
|
<filter string="Journal Item" |
||||
|
name="move_line" |
||||
|
domain="[('line_type','=', 'move_line')]"/> |
||||
|
<filter string="Forecast Line" |
||||
|
name="forecast_line" |
||||
|
domain="[('line_type','=', 'forecast_line')]"/> |
||||
|
<group> |
||||
|
<filter string="Line Type" |
||||
|
name="group_by_line_type" |
||||
|
context="{'group_by':'line_type'}"/> |
||||
|
<filter string="Account" |
||||
|
name="group_by_account_id" |
||||
|
context="{'group_by':'account_id'}"/> |
||||
|
<filter string="Date" |
||||
|
name="group_by_date" |
||||
|
context="{'group_by':'date'}"/> |
||||
|
<filter string="Company" |
||||
|
name="group_by_company_id" |
||||
|
context="{'group_by':'company_id'}" |
||||
|
groups="base.group_multi_company"/> |
||||
|
</group> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,27 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2019 ADHOC SA |
||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record model="ir.model.access" id="mis_cash_flow_access_name"> |
||||
|
<field name="name">mis.cash_flow</field> |
||||
|
<field name="model_id" ref="model_mis_cash_flow"/> |
||||
|
<field name="group_id" ref="base.group_user"/> |
||||
|
<field name="perm_read" eval="1"/> |
||||
|
<field name="perm_create" eval="0"/> |
||||
|
<field name="perm_write" eval="0"/> |
||||
|
<field name="perm_unlink" eval="0"/> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.model.access" id="mis_cash_flow_forecast_line_access_name"> |
||||
|
<field name="name">mis.cash_flow.forecast_line</field> |
||||
|
<field name="model_id" ref="model_mis_cash_flow_forecast_line"/> |
||||
|
<field name="group_id" ref="base.group_user"/> |
||||
|
<field name="perm_read" eval="1"/> |
||||
|
<field name="perm_create" eval="1"/> |
||||
|
<field name="perm_write" eval="1"/> |
||||
|
<field name="perm_unlink" eval="1"/> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
After Width: 150 | Height: 150 | Size: 4.7 KiB |
@ -0,0 +1 @@ |
|||||
|
from . import test_cash_flow |
@ -0,0 +1,130 @@ |
|||||
|
# Copyright 2019 Creu Blanca |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from datetime import timedelta |
||||
|
|
||||
|
from odoo.exceptions import ValidationError |
||||
|
from odoo.fields import Date |
||||
|
from odoo.tools import mute_logger |
||||
|
from odoo.tests.common import TransactionCase, post_install, at_install |
||||
|
|
||||
|
|
||||
|
@at_install(False) |
||||
|
@post_install(True) |
||||
|
class TestCashFlow(TransactionCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
super().setUp() |
||||
|
self.company = self.env['res.company'].create({ |
||||
|
'name': 'TEST' |
||||
|
}) |
||||
|
self.report = self.browse_ref( |
||||
|
'mis_builder_cash_flow.mis_instance_cash_flow') |
||||
|
self.report.company_id = self.company |
||||
|
self.bank_account = self.env['account.account'].create({ |
||||
|
"company_id": self.company.id, |
||||
|
"code": "TEST1", |
||||
|
"name": "Bank account 01", |
||||
|
"user_type_id": self.browse_ref( |
||||
|
"account.data_account_type_liquidity" |
||||
|
).id, |
||||
|
}) |
||||
|
self.bank_account_hide = self.env['account.account'].create({ |
||||
|
"company_id": self.company.id, |
||||
|
"code": "TEST2", |
||||
|
"name": "Bank account 02", |
||||
|
"user_type_id": self.browse_ref( |
||||
|
"account.data_account_type_liquidity" |
||||
|
).id, |
||||
|
"hide_in_cash_flow": True, |
||||
|
}) |
||||
|
self.account = self.env['account.account'].create({ |
||||
|
"company_id": self.company.id, |
||||
|
"code": "TEST3", |
||||
|
"name": "Account", |
||||
|
"user_type_id": self.browse_ref( |
||||
|
"account.data_account_type_receivable" |
||||
|
).id, |
||||
|
"reconcile": True, |
||||
|
}) |
||||
|
self.journal = self.env["account.journal"].create({ |
||||
|
"name": "Journal", |
||||
|
"code": "JOURNAL", |
||||
|
"company_id": self.company.id, |
||||
|
"type": "general", |
||||
|
}) |
||||
|
|
||||
|
def test_company_constrain(self): |
||||
|
with self.assertRaises(ValidationError): |
||||
|
self.env['mis.cash_flow.forecast_line'].create({ |
||||
|
'account_id': self.account.id, |
||||
|
'date': Date.today(), |
||||
|
'balance': 1000, |
||||
|
}) |
||||
|
|
||||
|
def test_report_instance(self): |
||||
|
self.check_matrix() |
||||
|
move = self.env['account.move'].create({ |
||||
|
'name': 'Move', |
||||
|
'journal_id': self.journal.id, |
||||
|
'company_id': self.company.id, |
||||
|
'line_ids': [(0, 0, { |
||||
|
'account_id': self.bank_account.id, |
||||
|
'debit': 1500, |
||||
|
'credit': 0, |
||||
|
'company_id': self.company.id, |
||||
|
}), (0, 0, { |
||||
|
'account_id': self.bank_account_hide.id, |
||||
|
'debit': 500, |
||||
|
'credit': 0, |
||||
|
'company_id': self.company.id, |
||||
|
}), (0, 0, { |
||||
|
'account_id': self.account.id, |
||||
|
'debit': 0, |
||||
|
'credit': 2000, |
||||
|
'company_id': self.company.id, |
||||
|
})] |
||||
|
}) |
||||
|
move.post() |
||||
|
self.check_matrix(args=[ |
||||
|
('liquidity', 'Current', 1500), |
||||
|
('balance', 'Current', 1500), |
||||
|
('in_receivable', 'Current', -2000), |
||||
|
], ignore_rows=['balance', 'period_balance', 'in_total'], |
||||
|
) |
||||
|
date = Date.from_string(Date.today()) + timedelta(weeks=8) |
||||
|
self.env['mis.cash_flow.forecast_line'].create({ |
||||
|
'account_id': self.account.id, |
||||
|
'date': Date.to_string(date), |
||||
|
'balance': 1000, |
||||
|
'company_id': self.company.id, |
||||
|
}) |
||||
|
self.check_matrix([ |
||||
|
('liquidity', 'Current', 1500), |
||||
|
('balance', 'Current', 1500), |
||||
|
('in_receivable', 'Current', -2000), |
||||
|
('in_forecast', '+8w', 1000), |
||||
|
], ignore_rows=['balance', 'period_balance', 'in_total']) |
||||
|
|
||||
|
def check_matrix(self, args=False, ignore_rows=False): |
||||
|
if not args: |
||||
|
args = [] |
||||
|
if not ignore_rows: |
||||
|
ignore_rows = [] |
||||
|
with mute_logger('odoo.addons.mis_builder.models.kpimatrix'): |
||||
|
matrix = self.report._compute_matrix() |
||||
|
for row in matrix.iter_rows(): |
||||
|
if row.kpi.name in ignore_rows: |
||||
|
continue |
||||
|
for cell in row.iter_cells(): |
||||
|
if not cell: |
||||
|
continue |
||||
|
found = False |
||||
|
label = cell.subcol.col.label |
||||
|
for exp in args: |
||||
|
if exp[0] == row.kpi.name and exp[1] == label: |
||||
|
found = True |
||||
|
self.assertEqual(cell.val, exp[2]) |
||||
|
break |
||||
|
if not found: |
||||
|
self.assertEqual(cell.val, 0) |
@ -0,0 +1,14 @@ |
|||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_account_form" model="ir.ui.view"> |
||||
|
<field name="model">account.account</field> |
||||
|
<field name="name">account.account.form</field> |
||||
|
<field name="inherit_id" ref="account.view_account_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="deprecated" position="after"> |
||||
|
<field name="hide_in_cash_flow" attrs="{'invisible': [('internal_type', 'not in', ['receivable', 'payable', 'liquidity'])]}"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,81 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- Copyright 2019 ADHOC SA |
||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record model="ir.ui.view" id="mis_cash_flow_forecast_line_view_form"> |
||||
|
<field name="name">mis.cash_flow.forecast_line.tree</field> |
||||
|
<field name="model">mis.cash_flow.forecast_line</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="MIS Cash Flow Forecast Line"> |
||||
|
<sheet> |
||||
|
<group col="2"> |
||||
|
<field name="company_id" |
||||
|
groups="base.group_multi_company"/> |
||||
|
<field name="date"/> |
||||
|
<field name="account_id" |
||||
|
domain="[('company_id', '=', company_id)]"/> |
||||
|
<field name="name"/> |
||||
|
<field name="balance"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.ui.view" id="mis_cash_flow_forecast_line_view_search"> |
||||
|
<field name="name">mis.cash_flow.forecast_line.search</field> |
||||
|
<field name="model">mis.cash_flow.forecast_line</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search> |
||||
|
<field name="name"/> |
||||
|
<field name="date"/> |
||||
|
<separator/> |
||||
|
<field name="account_id"/> |
||||
|
<field name="company_id" |
||||
|
groups="base.group_multi_company"/> |
||||
|
<group> |
||||
|
<filter string="Account" |
||||
|
name="group_by_account_id" |
||||
|
context="{'group_by':'account_id'}"/> |
||||
|
<filter string="Date" |
||||
|
name="group_by_date" |
||||
|
context="{'group_by':'date'}"/> |
||||
|
<filter string="Company" |
||||
|
name="group_by_company_id" |
||||
|
context="{'group_by':'company_id'}" groups="base.group_multi_company"/> |
||||
|
</group> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.ui.view" id="mis_cash_flow_forecast_line_view_tree"> |
||||
|
<field name="name">mis.cash_flow.forecast_line.tree</field> |
||||
|
<field name="model">mis.cash_flow.forecast_line</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="MIS Cash Flow Forecast Line" editable="top"> |
||||
|
<field name="company_id" |
||||
|
groups="base.group_multi_company"/> |
||||
|
<field name="date"/> |
||||
|
<field name="name"/> |
||||
|
<field name="account_id" |
||||
|
domain="[('company_id', '=', company_id), ('deprecated', '=', False), ('hide_in_cash_flow', '=', False), ('internal_type', '=', ['receivable', 'payable', 'liquidity'])]"/> |
||||
|
<field name="balance"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="action_mis_cash_flow_forecast_line"> |
||||
|
<field name="name">Cash Flow Forecast Line</field> |
||||
|
<field name="view_id" ref="mis_cash_flow_forecast_line_view_tree"/> |
||||
|
<field name="res_model">mis.cash_flow.forecast_line</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="menu_mis_cash_flow_forecast_line" |
||||
|
parent="mis_builder.mis_report_finance_menu" |
||||
|
action="action_mis_cash_flow_forecast_line" |
||||
|
sequence="23"/> |
||||
|
|
||||
|
</odoo> |
@ -1,2 +1,3 @@ |
|||||
|
mis-builder |
||||
server-ux |
server-ux |
||||
reporting-engine |
reporting-engine |
Write
Preview
Loading…
Cancel
Save
Reference in new issue