diff --git a/dynamic_accounts_report/README.rst b/dynamic_accounts_report/README.rst new file mode 100644 index 000000000..8c08a7806 --- /dev/null +++ b/dynamic_accounts_report/README.rst @@ -0,0 +1,44 @@ +Dynamic Financial Reports +========================= +* Dynamic financial reports for Odoo 15 community editions + +Installation +============ + - www.odoo.com/documentation/15.0/setup/install.html + - Install our custom addon + +License +------- +General Public License, Version 3 (LGPL v3). +(https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html) + +Company +------- +* 'Cybrosys Techno Solutions `__ + +Credits +------- +* Developer: +(v15) Jibin @ Cybrosys +(v15) Mehjabin @ Cybrosys +(v15) Mily @ Cybrosys +(v15) Aneesh @ Cybrosys + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com + +Further information +=================== +HTML Description: ``__ + diff --git a/dynamic_accounts_report/__init__.py b/dynamic_accounts_report/__init__.py new file mode 100644 index 000000000..644a56f70 --- /dev/null +++ b/dynamic_accounts_report/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +from . import controllers +from . import wizard +from . import report + diff --git a/dynamic_accounts_report/__manifest__.py b/dynamic_accounts_report/__manifest__.py new file mode 100644 index 000000000..74dcc3e3b --- /dev/null +++ b/dynamic_accounts_report/__manifest__.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# + +{ + 'name': 'Dynamic Financial Reports', + 'version': '15.0.1.0.0', + 'category': 'Accounting', + 'live_test_url': 'https://www.youtube.com/watch?v=gVQi9q9Rs-E&t=5s', + 'summary': """Dynamic Financial Reports with drill + down and filters– Community Edition""", + 'description': "Dynamic Financial Reports, DynamicFinancialReports, FinancialReport, Accountingreports, odoo reports, odoo" + "This module creates dynamic Accounting General Ledger, Trial Balance, Balance Sheet " + "Proft and Loss, Cash Flow Statements, Partner Ledger," + "Partner Ageing, Day book" + "Bank book and Cash book reports in Odoo 14 community edition.", + 'author': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'depends': ['base', 'base_accounting_kit'], + 'data': [ + 'security/ir.model.access.csv', + 'views/templates.xml', + 'views/views.xml', + 'views/kit_menus.xml', + 'report/trial_balance.xml', + 'report/general_ledger.xml', + 'report/cash_flow_report.xml', + 'report/financial_report_template.xml', + 'report/partner_ledger.xml', + 'report/ageing.xml', + 'report/daybook.xml', + ], + + 'assets': { + 'web.assets_backend': [ + 'dynamic_accounts_report/static/src/css/report.css', + 'dynamic_accounts_report/static/src/js/action_manager.js', + 'dynamic_accounts_report/static/src/js/general_ledger.js', + 'dynamic_accounts_report/static/src/js/trial_balance.js', + 'dynamic_accounts_report/static/src/js/cash_flow.js', + 'dynamic_accounts_report/static/src/js/financial_reports.js', + 'dynamic_accounts_report/static/src/js/partner_ledger.js', + 'dynamic_accounts_report/static/src/js/ageing.js', + 'dynamic_accounts_report/static/src/js/daybook.js', + ], + 'web.assets_qweb': [ + 'dynamic_accounts_report/static/src/xml/general_ledger_view.xml', + 'dynamic_accounts_report/static/src/xml/trial_balance_view.xml', + 'dynamic_accounts_report/static/src/xml/cash_flow_view.xml', + 'dynamic_accounts_report/static/src/xml/financial_reports_view.xml', + 'dynamic_accounts_report/static/src/xml/partner_ledger_view.xml', + 'dynamic_accounts_report/static/src/xml/ageing.xml', + 'dynamic_accounts_report/static/src/xml/daybook.xml', + ], + }, + 'license': 'LGPL-3', + 'images': ['static/description/banner.png'], + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/dynamic_accounts_report/controllers/__init__.py b/dynamic_accounts_report/controllers/__init__.py new file mode 100644 index 000000000..457bae27e --- /dev/null +++ b/dynamic_accounts_report/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/dynamic_accounts_report/controllers/controllers.py b/dynamic_accounts_report/controllers/controllers.py new file mode 100644 index 000000000..b5bab0e9b --- /dev/null +++ b/dynamic_accounts_report/controllers/controllers.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +import json +from odoo import http +from odoo.http import content_disposition, request +from odoo.addons.web.controllers.main import _serialize_exception +from odoo.tools import html_escape + + +class TBXLSXReportController(http.Controller): + @http.route('/dynamic_xlsx_reports', type='http', auth='user', methods=['POST'], csrf=False) + def get_report_xlsx(self, model, options, output_format, report_data, report_name, dfr_data, **kw): + uid = request.session.uid + report_obj = request.env[model].with_user(uid) + dfr_data = dfr_data + options = options + token = 'dummy-because-api-expects-one' + try: + if output_format == 'xlsx': + response = request.make_response( + None, + headers=[ + ('Content-Type', 'application/vnd.ms-excel'), + ('Content-Disposition', content_disposition(report_name + '.xlsx')) + ] + ) + report_obj.get_dynamic_xlsx_report(options, response, report_data, dfr_data) + response.set_cookie('fileToken', token) + return response + except Exception as e: + se = _serialize_exception(e) + error = { + 'code': 200, + 'message': 'Odoo Server Error', + 'data': se + } + return request.make_response(html_escape(json.dumps(error))) diff --git a/dynamic_accounts_report/doc/RELEASE_NOTES.md b/dynamic_accounts_report/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..b26671140 --- /dev/null +++ b/dynamic_accounts_report/doc/RELEASE_NOTES.md @@ -0,0 +1,9 @@ +## Module + +#### 02.09.2021 +#### Version 15.0.1.0.0 +#### ADD +- Initial commit for Odoo 15 dynamic financial reports + + + diff --git a/dynamic_accounts_report/report/__init__.py b/dynamic_accounts_report/report/__init__.py new file mode 100644 index 000000000..5838e7a2f --- /dev/null +++ b/dynamic_accounts_report/report/__init__.py @@ -0,0 +1,7 @@ +from . import trial_balance +from . import general_ledger +from . import cash_flow_report +from . import financial_reports +from . import partner_ledger +from . import ageing +from . import daybook diff --git a/dynamic_accounts_report/report/ageing.py b/dynamic_accounts_report/report/ageing.py new file mode 100644 index 000000000..3764f7f73 --- /dev/null +++ b/dynamic_accounts_report/report/ageing.py @@ -0,0 +1,19 @@ +from odoo import api, models, _ + + +class PartnerAgeing(models.AbstractModel): + _name = 'report.dynamic_accounts_report.partner_ageing' + + @api.model + def _get_report_values(self, docids, data=None): + if self.env.context.get('ageing_pdf_report'): + + if data.get('report_data'): + data.update( + {'account_data': data.get('report_data')['report_lines'][0], + 'Filters': data.get('report_data')['filters'], + 'company': self.env.company, + + }) + + return data diff --git a/dynamic_accounts_report/report/ageing.xml b/dynamic_accounts_report/report/ageing.xml new file mode 100644 index 000000000..ae7084692 --- /dev/null +++ b/dynamic_accounts_report/report/ageing.xml @@ -0,0 +1,168 @@ + + + + + Partner Ageing + account.partner.ageing + qweb-pdf + dynamic_accounts_report.partner_ageing + dynamic_accounts_report.partner_ageing + + + \ No newline at end of file diff --git a/dynamic_accounts_report/report/cash_flow_report.py b/dynamic_accounts_report/report/cash_flow_report.py new file mode 100644 index 000000000..b8077ecd8 --- /dev/null +++ b/dynamic_accounts_report/report/cash_flow_report.py @@ -0,0 +1,16 @@ +from odoo import api, models, _ + + +class GeneralLedger(models.AbstractModel): + _name = 'report.dynamic_accounts_report.cash_flow' + + @api.model + def _get_report_values(self, docids, data=None): + + if self.env.context.get('trial_pdf_report'): + if data.get('report_data'): + data.update({'account_data': data.get('report_data')['report_lines'], + 'Filters': data.get('report_data')['filters'], + 'company': self.env.company, + }) + return data diff --git a/dynamic_accounts_report/report/cash_flow_report.xml b/dynamic_accounts_report/report/cash_flow_report.xml new file mode 100644 index 000000000..b9c6d36fe --- /dev/null +++ b/dynamic_accounts_report/report/cash_flow_report.xml @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + cash_flow + account.cash.flow + qweb-pdf + dynamic_accounts_report.cash_flow + dynamic_accounts_report.cash_flow + + \ No newline at end of file diff --git a/dynamic_accounts_report/report/daybook.py b/dynamic_accounts_report/report/daybook.py new file mode 100644 index 000000000..4af37cec4 --- /dev/null +++ b/dynamic_accounts_report/report/daybook.py @@ -0,0 +1,17 @@ +from odoo import api, models, _ + + +class DayBook(models.AbstractModel): + _name = 'report.dynamic_accounts_report.day_book' + + @api.model + def _get_report_values(self, docids, data=None): + + if self.env.context.get('daybook_pdf_report'): + + if data.get('report_data'): + data.update({'account_data': data.get('report_data')['report_lines'], + 'Filters': data.get('report_data')['filters'], + 'company': self.env.company, + }) + return data \ No newline at end of file diff --git a/dynamic_accounts_report/report/daybook.xml b/dynamic_accounts_report/report/daybook.xml new file mode 100644 index 000000000..c3593def8 --- /dev/null +++ b/dynamic_accounts_report/report/daybook.xml @@ -0,0 +1,121 @@ + + + + + Day Book + account.day.book + qweb-pdf + dynamic_accounts_report.day_book + dynamic_accounts_report.day_book + + + \ No newline at end of file diff --git a/dynamic_accounts_report/report/financial_report_template.xml b/dynamic_accounts_report/report/financial_report_template.xml new file mode 100644 index 000000000..6bd2608ee --- /dev/null +++ b/dynamic_accounts_report/report/financial_report_template.xml @@ -0,0 +1,165 @@ + + + + + + Financial Report + dynamic.balance.sheet.report + qweb-pdf + dynamic_accounts_report.balance_sheet + dynamic_accounts_report.balance_sheet + + + diff --git a/dynamic_accounts_report/report/financial_reports.py b/dynamic_accounts_report/report/financial_reports.py new file mode 100644 index 000000000..76c6bdd37 --- /dev/null +++ b/dynamic_accounts_report/report/financial_reports.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from odoo import api, models, _ + + +class InsReportBalanceSheet(models.AbstractModel): + _name = 'report.dynamic_accounts_report.balance_sheet' + + @api.model + def _get_report_values(self, docids, data=None): + if self.env.context.get('bs_report'): + if data.get('report_data'): + data.update({ + 'Filters': data.get('report_data')['filters'], + 'account_data': data.get('report_data')['report_lines'], + 'report_lines': data.get('report_data')['bs_lines'], + 'report_name': data.get('report_name'), + 'title': data.get('report_data')['name'], + 'company': self.env.company, + }) + return data diff --git a/dynamic_accounts_report/report/general_ledger.py b/dynamic_accounts_report/report/general_ledger.py new file mode 100644 index 000000000..2572b6a5e --- /dev/null +++ b/dynamic_accounts_report/report/general_ledger.py @@ -0,0 +1,20 @@ +from odoo import api, models, _ + + +class GeneralLedger(models.AbstractModel): + _name = 'report.dynamic_accounts_report.general_ledger' + + @api.model + def _get_report_values(self, docids, data=None): + + if self.env.context.get('trial_pdf_report'): + + if data.get('report_data'): + data.update({'account_data': data.get('report_data')['report_lines'], + 'Filters': data.get('report_data')['filters'], + 'debit_total': data.get('report_data')['debit_total'], + 'credit_total': data.get('report_data')['credit_total'], + 'title': data.get('report_data')['name'], + 'company': self.env.company, + }) + return data diff --git a/dynamic_accounts_report/report/general_ledger.xml b/dynamic_accounts_report/report/general_ledger.xml new file mode 100644 index 000000000..63f8b958c --- /dev/null +++ b/dynamic_accounts_report/report/general_ledger.xml @@ -0,0 +1,153 @@ + + + + + + Report + account.general.ledger + qweb-pdf + dynamic_accounts_report.general_ledger + dynamic_accounts_report.general_ledger + + + \ No newline at end of file diff --git a/dynamic_accounts_report/report/partner_ledger.py b/dynamic_accounts_report/report/partner_ledger.py new file mode 100644 index 000000000..fe97bcae5 --- /dev/null +++ b/dynamic_accounts_report/report/partner_ledger.py @@ -0,0 +1,16 @@ +from odoo import api, models, _ + + +class PartnerLedgerReport(models.AbstractModel): + _name = 'report.dynamic_accounts_report.partner_ledger' + + @api.model + def _get_report_values(self, docids, data=None): + if self.env.context.get('partner_ledger_pdf_report'): + + if data.get('report_data'): + data.update({'account_data': data.get('report_data')['report_lines'], + 'Filters': data.get('report_data')['filters'], + 'company': self.env.company, + }) + return data diff --git a/dynamic_accounts_report/report/partner_ledger.xml b/dynamic_accounts_report/report/partner_ledger.xml new file mode 100644 index 000000000..fff1ba5b9 --- /dev/null +++ b/dynamic_accounts_report/report/partner_ledger.xml @@ -0,0 +1,155 @@ + + + + + + Partner ledger + account.partner.ledger + qweb-pdf + dynamic_accounts_report.partner_ledger + dynamic_accounts_report.partner_ledger + + + \ No newline at end of file diff --git a/dynamic_accounts_report/report/trial_balance.py b/dynamic_accounts_report/report/trial_balance.py new file mode 100644 index 000000000..bc33bbc04 --- /dev/null +++ b/dynamic_accounts_report/report/trial_balance.py @@ -0,0 +1,18 @@ +from odoo import api, models, _ + + +class TrialBalance(models.AbstractModel): + _name = 'report.dynamic_accounts_report.trial_balance' + + @api.model + def _get_report_values(self, docids, data=None): + if self.env.context.get('trial_pdf_report'): + + if data.get('report_data'): + data.update({'account_data': data.get('report_data')['report_lines'], + 'Filters': data.get('report_data')['filters'], + 'debit_total': data.get('report_data')['debit_total'], + 'credit_total': data.get('report_data')['credit_total'], + 'company': self.env.company, + }) + return data diff --git a/dynamic_accounts_report/report/trial_balance.xml b/dynamic_accounts_report/report/trial_balance.xml new file mode 100644 index 000000000..b021220ac --- /dev/null +++ b/dynamic_accounts_report/report/trial_balance.xml @@ -0,0 +1,129 @@ + + + + + + + + Trial Balance + account.trial.balance + qweb-pdf + dynamic_accounts_report.trial_balance + dynamic_accounts_report.trial_balance + + + \ No newline at end of file diff --git a/dynamic_accounts_report/security/ir.model.access.csv b/dynamic_accounts_report/security/ir.model.access.csv new file mode 100644 index 000000000..2d589ffc2 --- /dev/null +++ b/dynamic_accounts_report/security/ir.model.access.csv @@ -0,0 +1,8 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_general_ledger,access.account.general.ledger,model_account_general_ledger,account.group_account_user,1,1,1,1 +access_account_trial_balance,access.account.trial.balance,model_account_trial_balance,account.group_account_user,1,1,1,1 +access_account_cash_flow,access.account.cash.flow,model_account_cash_flow,account.group_account_user,1,1,1,1 +access_dynamic_balance_sheet_report,access.dynamic.balance.sheet.report,model_dynamic_balance_sheet_report,account.group_account_user,1,1,1,1 +access_account_partner_ledger,access.account.partner.ledger,model_account_partner_ledger,account.group_account_user,1,1,1,1 +access_account_partner_ageing,account_partner_ageing.account_partner_ageing,model_account_partner_ageing,account.group_account_user,1,1,1,1 +access_account_day_book,account_day_book.account_day_book,model_account_day_book,account.group_account_user,1,1,1,1 diff --git a/dynamic_accounts_report/static/description/assets/icons/check.png b/dynamic_accounts_report/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/check.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/chevron.png b/dynamic_accounts_report/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/chevron.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/cogs.png b/dynamic_accounts_report/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/cogs.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/consultation.png b/dynamic_accounts_report/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/consultation.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/ecom-black.png b/dynamic_accounts_report/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/ecom-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/education-black.png b/dynamic_accounts_report/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/education-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/hotel-black.png b/dynamic_accounts_report/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/hotel-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/license.png b/dynamic_accounts_report/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/license.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/lifebuoy.png b/dynamic_accounts_report/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/lifebuoy.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/logo.png b/dynamic_accounts_report/static/description/assets/icons/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/logo.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/manufacturing-black.png b/dynamic_accounts_report/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/manufacturing-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/pos-black.png b/dynamic_accounts_report/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/pos-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/puzzle.png b/dynamic_accounts_report/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/puzzle.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/restaurant-black.png b/dynamic_accounts_report/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/restaurant-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/service-black.png b/dynamic_accounts_report/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/service-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/trading-black.png b/dynamic_accounts_report/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/trading-black.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/training.png b/dynamic_accounts_report/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/training.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/update.png b/dynamic_accounts_report/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/update.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/user.png b/dynamic_accounts_report/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/user.png differ diff --git a/dynamic_accounts_report/static/description/assets/icons/wrench.png b/dynamic_accounts_report/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/icons/wrench.png differ diff --git a/dynamic_accounts_report/static/description/assets/modules/approval_image.png b/dynamic_accounts_report/static/description/assets/modules/approval_image.png new file mode 100644 index 000000000..84fe94e80 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/modules/approval_image.png differ diff --git a/dynamic_accounts_report/static/description/assets/modules/budget_image.png b/dynamic_accounts_report/static/description/assets/modules/budget_image.png new file mode 100644 index 000000000..fe6aa6fe4 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/modules/budget_image.png differ diff --git a/dynamic_accounts_report/static/description/assets/modules/export_image.png b/dynamic_accounts_report/static/description/assets/modules/export_image.png new file mode 100644 index 000000000..4e4ea0e51 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/modules/export_image.png differ diff --git a/dynamic_accounts_report/static/description/assets/modules/magento_image.png b/dynamic_accounts_report/static/description/assets/modules/magento_image.png new file mode 100644 index 000000000..39de0820f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/modules/magento_image.png differ diff --git a/dynamic_accounts_report/static/description/assets/modules/pos_image.png b/dynamic_accounts_report/static/description/assets/modules/pos_image.png new file mode 100644 index 000000000..c5932894b Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/modules/pos_image.png differ diff --git a/dynamic_accounts_report/static/description/assets/modules/shopify_image.png b/dynamic_accounts_report/static/description/assets/modules/shopify_image.png new file mode 100644 index 000000000..c6d92c16d Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/modules/shopify_image.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/01_balance-sheet-report-1.png b/dynamic_accounts_report/static/description/assets/screenshots/01_balance-sheet-report-1.png new file mode 100644 index 000000000..2ccab9e77 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/01_balance-sheet-report-1.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/02_balance-sheet-report -2-PDF.png b/dynamic_accounts_report/static/description/assets/screenshots/02_balance-sheet-report -2-PDF.png new file mode 100644 index 000000000..8a093c9d9 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/02_balance-sheet-report -2-PDF.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/03_balance-sheet-report-3-xlsx.png b/dynamic_accounts_report/static/description/assets/screenshots/03_balance-sheet-report-3-xlsx.png new file mode 100644 index 000000000..2b5db9f36 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/03_balance-sheet-report-3-xlsx.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/04_balance-sheet-report-4-View-General-Ledger.png b/dynamic_accounts_report/static/description/assets/screenshots/04_balance-sheet-report-4-View-General-Ledger.png new file mode 100644 index 000000000..e76c9bf5b Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/04_balance-sheet-report-4-View-General-Ledger.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/05_balance-sheet report -5-View-source -move.png b/dynamic_accounts_report/static/description/assets/screenshots/05_balance-sheet report -5-View-source -move.png new file mode 100644 index 000000000..41edd62f0 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/05_balance-sheet report -5-View-source -move.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/06_bankbook-drill-down-1.png b/dynamic_accounts_report/static/description/assets/screenshots/06_bankbook-drill-down-1.png new file mode 100644 index 000000000..b1060ed83 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/06_bankbook-drill-down-1.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/07_bank-book-pdf -2.png b/dynamic_accounts_report/static/description/assets/screenshots/07_bank-book-pdf -2.png new file mode 100644 index 000000000..55371ebb8 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/07_bank-book-pdf -2.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/08_bank-book-xlsx-3.png b/dynamic_accounts_report/static/description/assets/screenshots/08_bank-book-xlsx-3.png new file mode 100644 index 000000000..8d3361fed Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/08_bank-book-xlsx-3.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/09_filter-applied-in-bank-book.png b/dynamic_accounts_report/static/description/assets/screenshots/09_filter-applied-in-bank-book.png new file mode 100644 index 000000000..89d395ff1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/09_filter-applied-in-bank-book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/10_cash-book-drill-down.png b/dynamic_accounts_report/static/description/assets/screenshots/10_cash-book-drill-down.png new file mode 100644 index 000000000..42da03134 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/10_cash-book-drill-down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/11_journal-entry-from-cash-book.png b/dynamic_accounts_report/static/description/assets/screenshots/11_journal-entry-from-cash-book.png new file mode 100644 index 000000000..26efc3400 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/11_journal-entry-from-cash-book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/12_cash-flow-statement-detailed-view.png b/dynamic_accounts_report/static/description/assets/screenshots/12_cash-flow-statement-detailed-view.png new file mode 100644 index 000000000..134bbd94f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/12_cash-flow-statement-detailed-view.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/13_detailed-pdf-report.png b/dynamic_accounts_report/static/description/assets/screenshots/13_detailed-pdf-report.png new file mode 100644 index 000000000..f412d5b80 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/13_detailed-pdf-report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/14_detailed-xlsx-report.png b/dynamic_accounts_report/static/description/assets/screenshots/14_detailed-xlsx-report.png new file mode 100644 index 000000000..1ee593ce1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/14_detailed-xlsx-report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/15_various-report-levels-in-cash-flow.png b/dynamic_accounts_report/static/description/assets/screenshots/15_various-report-levels-in-cash-flow.png new file mode 100644 index 000000000..cf93c6cd0 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/15_various-report-levels-in-cash-flow.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/16_daybook-drilldown.png b/dynamic_accounts_report/static/description/assets/screenshots/16_daybook-drilldown.png new file mode 100644 index 000000000..45ecdef16 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/16_daybook-drilldown.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/17_journal-entry-from-daybook.png b/dynamic_accounts_report/static/description/assets/screenshots/17_journal-entry-from-daybook.png new file mode 100644 index 000000000..1e5f7fd05 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/17_journal-entry-from-daybook.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/18_general_ledger_drilldown.png b/dynamic_accounts_report/static/description/assets/screenshots/18_general_ledger_drilldown.png new file mode 100644 index 000000000..9be1c18b1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/18_general_ledger_drilldown.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/19_general_ledger_report.png b/dynamic_accounts_report/static/description/assets/screenshots/19_general_ledger_report.png new file mode 100644 index 000000000..7c383b6d8 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/19_general_ledger_report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/20_partner-ageing-drill-down.png b/dynamic_accounts_report/static/description/assets/screenshots/20_partner-ageing-drill-down.png new file mode 100644 index 000000000..2b16257d5 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/20_partner-ageing-drill-down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/21_partner-ageing-with-filters-and-report-printing-option.png b/dynamic_accounts_report/static/description/assets/screenshots/21_partner-ageing-with-filters-and-report-printing-option.png new file mode 100644 index 000000000..65c656ef4 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/21_partner-ageing-with-filters-and-report-printing-option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/22_partner-ledger-drill-down.png b/dynamic_accounts_report/static/description/assets/screenshots/22_partner-ledger-drill-down.png new file mode 100644 index 000000000..9af397100 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/22_partner-ledger-drill-down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/23_partner-ledger-with-filters-and-report-printing-option.png b/dynamic_accounts_report/static/description/assets/screenshots/23_partner-ledger-with-filters-and-report-printing-option.png new file mode 100644 index 000000000..4b35df0e0 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/23_partner-ledger-with-filters-and-report-printing-option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/24_profit-and-loss-report-with-filters-and-report-printing-option.png b/dynamic_accounts_report/static/description/assets/screenshots/24_profit-and-loss-report-with-filters-and-report-printing-option.png new file mode 100644 index 000000000..f71306086 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/24_profit-and-loss-report-with-filters-and-report-printing-option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/25_journal-entry-view-from-general-ledger-wizard.png b/dynamic_accounts_report/static/description/assets/screenshots/25_journal-entry-view-from-general-ledger-wizard.png new file mode 100644 index 000000000..3f02fa278 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/25_journal-entry-view-from-general-ledger-wizard.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/26_general-ledger-wizard-with-drill-down-in-profit-and-loss.png b/dynamic_accounts_report/static/description/assets/screenshots/26_general-ledger-wizard-with-drill-down-in-profit-and-loss.png new file mode 100644 index 000000000..cd822324a Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/26_general-ledger-wizard-with-drill-down-in-profit-and-loss.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/27_view-source-move-from-general-ledger-wizard-in-profit-and-loss.png b/dynamic_accounts_report/static/description/assets/screenshots/27_view-source-move-from-general-ledger-wizard-in-profit-and-loss.png new file mode 100644 index 000000000..879a28ac2 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/27_view-source-move-from-general-ledger-wizard-in-profit-and-loss.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/28_trial-balance-report-with-filters-and-report-viewing-option.png b/dynamic_accounts_report/static/description/assets/screenshots/28_trial-balance-report-with-filters-and-report-viewing-option.png new file mode 100644 index 000000000..2e5d49827 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/28_trial-balance-report-with-filters-and-report-viewing-option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/29-general-ledger-wizard-with-drill-down- and-view-source-move-option.png b/dynamic_accounts_report/static/description/assets/screenshots/29-general-ledger-wizard-with-drill-down- and-view-source-move-option.png new file mode 100644 index 000000000..18d48dcde Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/29-general-ledger-wizard-with-drill-down- and-view-source-move-option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/30_Dynamic-Reports-Menu.png b/dynamic_accounts_report/static/description/assets/screenshots/30_Dynamic-Reports-Menu.png new file mode 100644 index 000000000..19c1cc85d Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/30_Dynamic-Reports-Menu.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/31_Financial-Report-Configuration-1.png b/dynamic_accounts_report/static/description/assets/screenshots/31_Financial-Report-Configuration-1.png new file mode 100644 index 000000000..41727497c Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/31_Financial-Report-Configuration-1.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/32_Financial-Report-Configuration-2.png b/dynamic_accounts_report/static/description/assets/screenshots/32_Financial-Report-Configuration-2.png new file mode 100644 index 000000000..2cdcbd1bf Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/32_Financial-Report-Configuration-2.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/ageing filters applied.png b/dynamic_accounts_report/static/description/assets/screenshots/ageing filters applied.png new file mode 100644 index 000000000..db523925a Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/ageing filters applied.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/ageing pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/ageing pdf report.png new file mode 100644 index 000000000..a2003e7d6 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/ageing pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/ageing source move.png b/dynamic_accounts_report/static/description/assets/screenshots/ageing source move.png new file mode 100644 index 000000000..81006b112 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/ageing source move.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/ageing xlsx report.png b/dynamic_accounts_report/static/description/assets/screenshots/ageing xlsx report.png new file mode 100644 index 000000000..a5507a4f7 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/ageing xlsx report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/balance sheet pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/balance sheet pdf report.png new file mode 100644 index 000000000..e15bedc7f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/balance sheet pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/balance sheet report.png b/dynamic_accounts_report/static/description/assets/screenshots/balance sheet report.png new file mode 100644 index 000000000..2ccab9e77 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/balance sheet report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/balance sheet xlsx report.png b/dynamic_accounts_report/static/description/assets/screenshots/balance sheet xlsx report.png new file mode 100644 index 000000000..2f663d968 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/balance sheet xlsx report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/bank book journal entry.png b/dynamic_accounts_report/static/description/assets/screenshots/bank book journal entry.png new file mode 100644 index 000000000..63e2709da Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/bank book journal entry.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/bank book pdf.png b/dynamic_accounts_report/static/description/assets/screenshots/bank book pdf.png new file mode 100644 index 000000000..9d61a8245 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/bank book pdf.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/bank book report with filters and report viewing option.png b/dynamic_accounts_report/static/description/assets/screenshots/bank book report with filters and report viewing option.png new file mode 100644 index 000000000..02eceada8 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/bank book report with filters and report viewing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/bank book xlsx.png b/dynamic_accounts_report/static/description/assets/screenshots/bank book xlsx.png new file mode 100644 index 000000000..8d3361fed Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/bank book xlsx.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/bankbook drill down.png b/dynamic_accounts_report/static/description/assets/screenshots/bankbook drill down.png new file mode 100644 index 000000000..b1060ed83 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/bankbook drill down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash book drill down.png b/dynamic_accounts_report/static/description/assets/screenshots/cash book drill down.png new file mode 100644 index 000000000..42da03134 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash book drill down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash book pdf.png b/dynamic_accounts_report/static/description/assets/screenshots/cash book pdf.png new file mode 100644 index 000000000..fe99b4ec2 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash book pdf.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash book xlsx.png b/dynamic_accounts_report/static/description/assets/screenshots/cash book xlsx.png new file mode 100644 index 000000000..48b1013ad Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash book xlsx.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement detailed view.png b/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement detailed view.png new file mode 100644 index 000000000..134bbd94f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement detailed view.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement summary.png b/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement summary.png new file mode 100644 index 000000000..081f7297f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement summary.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement with filters and report printing option.png b/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement with filters and report printing option.png new file mode 100644 index 000000000..dd897197b Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash flow statement with filters and report printing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cash flow very deatiled xlsx.png b/dynamic_accounts_report/static/description/assets/screenshots/cash flow very deatiled xlsx.png new file mode 100644 index 000000000..f42943297 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cash flow very deatiled xlsx.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/cashbook report with filters and report printing option.png b/dynamic_accounts_report/static/description/assets/screenshots/cashbook report with filters and report printing option.png new file mode 100644 index 000000000..336d8feb2 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/cashbook report with filters and report printing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/configurable financial reports.png b/dynamic_accounts_report/static/description/assets/screenshots/configurable financial reports.png new file mode 100644 index 000000000..41727497c Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/configurable financial reports.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/consolidated cash flow statement.png b/dynamic_accounts_report/static/description/assets/screenshots/consolidated cash flow statement.png new file mode 100644 index 000000000..3edb74579 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/consolidated cash flow statement.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/daybook drilldown.png b/dynamic_accounts_report/static/description/assets/screenshots/daybook drilldown.png new file mode 100644 index 000000000..45ecdef16 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/daybook drilldown.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/daybook pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/daybook pdf report.png new file mode 100644 index 000000000..2c23f8e3f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/daybook pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/daybook report.png b/dynamic_accounts_report/static/description/assets/screenshots/daybook report.png new file mode 100644 index 000000000..45e9c0578 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/daybook report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/daybook xlsx.png b/dynamic_accounts_report/static/description/assets/screenshots/daybook xlsx.png new file mode 100644 index 000000000..6ea714cdd Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/daybook xlsx.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/detailed pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/detailed pdf report.png new file mode 100644 index 000000000..13e49eede Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/detailed pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/drill down option in cash flow.png b/dynamic_accounts_report/static/description/assets/screenshots/drill down option in cash flow.png new file mode 100644 index 000000000..266ae2d28 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/drill down option in cash flow.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/drilldown in partner ageing.png b/dynamic_accounts_report/static/description/assets/screenshots/drilldown in partner ageing.png new file mode 100644 index 000000000..73367e2de Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/drilldown in partner ageing.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filter applied in balance sheet.png b/dynamic_accounts_report/static/description/assets/screenshots/filter applied in balance sheet.png new file mode 100644 index 000000000..7966f0fb1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filter applied in balance sheet.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filter applied in bank book.png b/dynamic_accounts_report/static/description/assets/screenshots/filter applied in bank book.png new file mode 100644 index 000000000..89d395ff1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filter applied in bank book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filter applied in cash book.png b/dynamic_accounts_report/static/description/assets/screenshots/filter applied in cash book.png new file mode 100644 index 000000000..6be802605 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filter applied in cash book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filters applied in cash flow.png b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in cash flow.png new file mode 100644 index 000000000..8bd2a793f Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in cash flow.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filters applied in daybook.png b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in daybook.png new file mode 100644 index 000000000..e956e9759 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in daybook.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filters applied in partner ledger.png b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in partner ledger.png new file mode 100644 index 000000000..e064fa293 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in partner ledger.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/filters applied in trial balance.png b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in trial balance.png new file mode 100644 index 000000000..197d42516 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/filters applied in trial balance.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/financial report configuration.png b/dynamic_accounts_report/static/description/assets/screenshots/financial report configuration.png new file mode 100644 index 000000000..59eec2ebd Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/financial report configuration.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with drill down and view source move option.png b/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with drill down and view source move option.png new file mode 100644 index 000000000..18d48dcde Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with drill down and view source move option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with drill down in profit and loss.png b/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with drill down in profit and loss.png new file mode 100644 index 000000000..cd822324a Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with drill down in profit and loss.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with view source move and drill down.png b/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with view source move and drill down.png new file mode 100644 index 000000000..41edd62f0 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general ledger wizard with view source move and drill down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_drilldown.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_drilldown.png new file mode 100644 index 000000000..9be1c18b1 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_drilldown.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_filters_applied.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_filters_applied.png new file mode 100644 index 000000000..7a69bd17a Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_filters_applied.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_journal_entry.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_journal_entry.png new file mode 100644 index 000000000..e4d861e4c Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_journal_entry.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_pdf_report.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_pdf_report.png new file mode 100644 index 000000000..1b9c1892c Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_pdf_report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_report.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_report.png new file mode 100644 index 000000000..7c383b6d8 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_view.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_view.png new file mode 100644 index 000000000..7a81d9de2 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_view.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_view_source_move.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_view_source_move.png new file mode 100644 index 000000000..e37ab0615 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_view_source_move.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_xlsx_report.png b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_xlsx_report.png new file mode 100644 index 000000000..7112a4b8b Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/general_ledger_xlsx_report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/hero.png b/dynamic_accounts_report/static/description/assets/screenshots/hero.png new file mode 100644 index 000000000..c723762c7 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/hero.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/image.png b/dynamic_accounts_report/static/description/assets/screenshots/image.png new file mode 100644 index 000000000..237d20bdc Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/image.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/journal entry from cash book.png b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from cash book.png new file mode 100644 index 000000000..26efc3400 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from cash book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/journal entry from daybook.png b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from daybook.png new file mode 100644 index 000000000..1e5f7fd05 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from daybook.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/journal entry from partner ageing.png b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from partner ageing.png new file mode 100644 index 000000000..b573ff83e Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from partner ageing.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/journal entry from trial balance.png b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from trial balance.png new file mode 100644 index 000000000..884382fd7 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/journal entry from trial balance.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/partner ageing with filters and report printing option.png b/dynamic_accounts_report/static/description/assets/screenshots/partner ageing with filters and report printing option.png new file mode 100644 index 000000000..3cc106e10 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/partner ageing with filters and report printing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/partner ledger drill down.png b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger drill down.png new file mode 100644 index 000000000..9af397100 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger drill down.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/partner ledger journal entry.png b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger journal entry.png new file mode 100644 index 000000000..953d4c986 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger journal entry.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/partner ledger pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger pdf report.png new file mode 100644 index 000000000..958d0b248 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/partner ledger with filters and report printing option.png b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger with filters and report printing option.png new file mode 100644 index 000000000..4b35df0e0 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger with filters and report printing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/partner ledger xlsx.png b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger xlsx.png new file mode 100644 index 000000000..507fdfc92 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/partner ledger xlsx.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/profit and loss filtes applied view.png b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss filtes applied view.png new file mode 100644 index 000000000..7474bd825 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss filtes applied view.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/profit and loss pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss pdf report.png new file mode 100644 index 000000000..72b050931 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/profit and loss reort with filters and report printing option.png b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss reort with filters and report printing option.png new file mode 100644 index 000000000..f71306086 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss reort with filters and report printing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/profit and loss xlsx report.png b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss xlsx report.png new file mode 100644 index 000000000..a77ebb5a7 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/profit and loss xlsx report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/trial balance pdf report.png b/dynamic_accounts_report/static/description/assets/screenshots/trial balance pdf report.png new file mode 100644 index 000000000..b275f86fa Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/trial balance pdf report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/trial balance repor with filters and report viewing option.png b/dynamic_accounts_report/static/description/assets/screenshots/trial balance repor with filters and report viewing option.png new file mode 100644 index 000000000..2e5d49827 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/trial balance repor with filters and report viewing option.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/trial balance xlsx report.png b/dynamic_accounts_report/static/description/assets/screenshots/trial balance xlsx report.png new file mode 100644 index 000000000..2a92f0981 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/trial balance xlsx report.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/various report levels in cash flow.png b/dynamic_accounts_report/static/description/assets/screenshots/various report levels in cash flow.png new file mode 100644 index 000000000..cf93c6cd0 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/various report levels in cash flow.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view general ledger from balance sheet.png b/dynamic_accounts_report/static/description/assets/screenshots/view general ledger from balance sheet.png new file mode 100644 index 000000000..e76c9bf5b Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view general ledger from balance sheet.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view general ledger from trial balance.png b/dynamic_accounts_report/static/description/assets/screenshots/view general ledger from trial balance.png new file mode 100644 index 000000000..b63ea9aba Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view general ledger from trial balance.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view general ledger in profit and loss.png b/dynamic_accounts_report/static/description/assets/screenshots/view general ledger in profit and loss.png new file mode 100644 index 000000000..89655a234 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view general ledger in profit and loss.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view journal entry from bank book.png b/dynamic_accounts_report/static/description/assets/screenshots/view journal entry from bank book.png new file mode 100644 index 000000000..59c46ac81 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view journal entry from bank book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view source move from cash book.png b/dynamic_accounts_report/static/description/assets/screenshots/view source move from cash book.png new file mode 100644 index 000000000..bbb746b89 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view source move from cash book.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view source move from daybook.png b/dynamic_accounts_report/static/description/assets/screenshots/view source move from daybook.png new file mode 100644 index 000000000..12ea8651c Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view source move from daybook.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view source move from general ledger wizard in profit and loss.png b/dynamic_accounts_report/static/description/assets/screenshots/view source move from general ledger wizard in profit and loss.png new file mode 100644 index 000000000..879a28ac2 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view source move from general ledger wizard in profit and loss.png differ diff --git a/dynamic_accounts_report/static/description/assets/screenshots/view source move from partner ledger.png b/dynamic_accounts_report/static/description/assets/screenshots/view source move from partner ledger.png new file mode 100644 index 000000000..fae789151 Binary files /dev/null and b/dynamic_accounts_report/static/description/assets/screenshots/view source move from partner ledger.png differ diff --git a/dynamic_accounts_report/static/description/banner.png b/dynamic_accounts_report/static/description/banner.png new file mode 100644 index 000000000..5238bdeab Binary files /dev/null and b/dynamic_accounts_report/static/description/banner.png differ diff --git a/dynamic_accounts_report/static/description/cybro_logo.png b/dynamic_accounts_report/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/dynamic_accounts_report/static/description/cybro_logo.png differ diff --git a/dynamic_accounts_report/static/description/icon.png b/dynamic_accounts_report/static/description/icon.png new file mode 100644 index 000000000..9a51c7604 Binary files /dev/null and b/dynamic_accounts_report/static/description/icon.png differ diff --git a/dynamic_accounts_report/static/description/images/logo.png b/dynamic_accounts_report/static/description/images/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/dynamic_accounts_report/static/description/images/logo.png differ diff --git a/dynamic_accounts_report/static/description/index.html b/dynamic_accounts_report/static/description/index.html new file mode 100644 index 000000000..a083cc987 --- /dev/null +++ b/dynamic_accounts_report/static/description/index.html @@ -0,0 +1,1694 @@ + +
+
+
+
+ +
+
+
+ Community +
+ + +
+
+
+
+ +
+
+
+

+ Odoo 15 Dynamic Financial Reports

+

+ A Module for accounting reports +

+ +
+
+ + + + +
+
+

+ Overview +

+
+ +
+

+ + The Financial Reports module helps in accessing the various reports in the Odoo Community edition, which supports a dynamic view. You can use the Filters and Group by tools to get the data according to your requirement. Moreover, the reports which can be accessed are Dynamic Accounting General Ledger, Trial Balance, Balance Sheet, Profit and Loss, Cash Flow Statements, Partner Ledger, Partner Ageing, Daybook, Bankbook, and Cashbook Reports in Odoo 14 community edition. Additionally, the users can also print the reports in PDF and XLSX Format. +

+ +
+
+ + +
+
+

+ Features +

+
+ +
+
+ +
+
+

+ Various Filters to Compare

+

+ Option to compare report values with various filtering tools available.

+
+
+
+
+ +
+
+

+ Print reports in PDF and XLSX Format

+

+ You can print the reports in both the PDF and XLSX format.

+
+
+ +
+
+ +
+
+

+ Access the Journal Entries

+

+ Easy access to the corresponding journal entries directly from the dynamic report view.

+
+
+ +
+
+ +
+
+

+ Drill-down Approach in Reports

+

+ The user can drill down from the main report to the journal entries. You can open the form view of each journal entry and view the complete details here.

+
+
+ +
+
+ +
+
+

+ Configurable Financial Reports

+

+ Backend configuration for financial reports, you can configure the hierarchy of financial reports.

+
+
+ + + +
+ +
+
+

+ Screenshots +

+
+
+

+ Dynamic Financial Reports Menu

+

+

+ +
+ +
+

+ Financial Reports Configuration

+

+ +

+ +
+ +
+

+ General Ledger

+

+

+ +
+ + +
+

+ General Ledger Drill-Down View

+

+

+ +
+ + +
+

+ Filters in General Ledger

+

+ (Custom Date Range, Journals, Accounts, Analytic Accounts, Analytic Tags & Target Move) +

+ +
+ + +
+

+ Option to view source move in General Ledger

+

+ +

+ +
+ +
+

+ General Ledger Journal Entry

+

+

+ +
+ +
+

+ Trial Balance Report

+

+

+ +
+ +
+

+ General Ledger view from Trial Balance

+

+

+ +
+ + +
+

+ General Ledger Wizard with Drill-down view

+

+ +

+ +
+ + +
+

+ Filters Applied in Trial Balance

+

+ (Custom Date Range, Journals & Target Move ) +

+ +
+ +
+

+ Journal Entry from Trial Balance

+

+ +

+ +
+ +
+

+ Trial Balance PDF Report

+

+ + +

+ +
+ + +
+

+ + Trial Balance XLSX Report

+

+ + +

+ +
+ +
+

+ Balance Sheet

+

+

+ +
+ +
+

+ View General Ledger from Balance Sheet

+

+

+ +
+ +
+

+ General Ledger Wizard with Drill down view

+

+

+ +
+ +
+

+ +Filters Applied in Balance Sheet

+

+ (Custom Date Range, Journals, Accounts, Account Tags, Analytic Accounts, Analytic Tags & Target Move) +

+ +
+ +
+

+ Balance Sheet PDF Report

+

+ +

+ +
+ +
+

+ Balance Sheet XLSX Report

+

+ +

+ +
+ +
+

+ Profit and Loss Account

+

+

+ +
+ + +
+

+ View General Ledger from Balance Sheet

+

+

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Filters Applied in Profit and Loss

+ +

+ (Custom Date Range, Journals, Accounts, Account Tags, Analytic Accounts, Analytic Tags & Target Move) +

+ +
+ +
+

+ View General Ledger from Profit and Loss

+

+

+ +
+ +
+

+ View Source Move from General Ledger Wizard

+

+

+ +
+ + +
+

+ Profit and Loss PDF Report

+

+ +

+ +
+ + +
+

+ Profit and Loss XLSX Report

+

+

+ +
+ +
+

+ Partner Ledger Report

+

+ +

+ +
+ +
+

+ Partner Ledger Drill Down view

+

+ + +

+ +
+ + +
+

+ + Filters in Partner Ledger

+

+ (Custom Date Range, Partner, Accounts, Account Tags, Analytic Accounts, Analytic Tags & Target Move) + +

+ +
+ +
+

+ View Source move from Partner Ledger

+

+

+ +
+ +
+

+ Journal Entry from Partner Ledger

+

+

+ +
+ +
+

+ Partner Ledger PDF Report

+

+

+ +
+ +
+

+ + Partner Ledger XLSX Report

+

+

+ +
+ +
+

+ Aged Partner Balance Report

+

+ +

+ +
+ +
+

+ Aged Partner Balance Drill Down

+

+ +

+ +
+ +
+

+ Filters in Partner Ageing Report

+

+ (Custom Date Range, Partners, Partner Tags, Account Type, & Target Move) +

+ +
+ + +
+

+ View source move from Partner Ageing

+

+

+ +
+ + + + + + + + + + + + + + + + +
+

+ Partner Ageing PDF Report

+

+

+ +
+ +
+

+ + Partner Ageing XLSX Report

+

+

+ +
+ +
+

+ Cash Flow Statements Report

+

+

+ +
+ + +
+

+ Cash Flow Statements Drill Down view

+

+

+ +
+ + +
+

+ Filters in Cash Flow Statement

+

+ (Custom Date Range, Level & Target Move) +

+ +
+ + +
+

+ Different Levels in Cash Flow Statement

+

+ +

+ +
+ +
+

+ Cash Flow Statement Summary

+ +

+

+ +
+ +
+

+ Consolidated Cash Flow Statement

+

+

+ +
+ + +
+

+ Cash Flow Statement Detailed View

+

+ +

+ +
+ + +
+

+ Cash Flow Statement PDF Report

+

+ +

+ +
+ + +
+

+ Cash Flow Statement XLSX Report

+

+

+ +
+ +
+

+ Cash Book Report

+

+ +

+ +
+ +
+

+ +Filters in Cash Book Report

+

+ (Custom Date Range, Accounts, Journals, Analytic Accounts, Anlaytic Tags & Target Move) + +

+ +
+ + +
+

+ + Cash Book Report Drill Down view

+

+ +

+ +
+ +
+

+ View Source move from Cash Book Report

+

+

+ +
+ +
+

+ Journal Entry from Cash Book Report

+

+

+ +
+ +
+

+ Cash Book PDF Report

+

+

+ +
+ +
+

+ + Cash Book XLSX Report

+

+

+ +
+ +
+

+ Bank Book Report

+

+ +

+ +
+ +
+

+ Filters in Bank Book Report

+

+ (Custom Date Range, Accounts, Journals, Analytic Accounts, Anlaytic Tags & Target Move) +

+ +
+ +
+

+ Bank Book Report Drill Down view

+

+

+ +
+ + +
+

+ View Source move from Bank Book Report

+

+

+ +
+ + + + + + + + + + + + +
+

+ Journal Entry from Bank Book Report

+

+

+ +
+ +
+

+ + Bank Book PDF Report

+

+

+ +
+ +
+

+ Bank Book XLSX Report

+

+

+ +
+ + +
+

+ Day Book Report

+

+

+ +
+ + +
+

+ Filters in Day Book Report

+

+ (Custom Date Range, Accounts, Journals & Target Move) +

+ +
+ + +
+

+ Day Book Report Drill Down view

+

+ +

+ +
+ +
+

+ View Source move from Day Book Report

+ +

+

+ +
+ +
+

+ Journal Entry from Day Book Report

+

+

+ +
+ +
+

+ Day Book PDF Report

+

+

+ +
+ + +
+

+ Day Book XLSX Report

+

+ +

+ +
+ + + + +
+ + + + +
+
+

Suggested Products

+
+ + +
+
+ + + +
+
+
+

Our Services

+
+
+ +
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+
+ + + +
+
+
+

Our Industries

+
+
+ +
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+ +
+
+ + + + + +
+
+
+

Need Help?

+
+
+
+ + +
+ +
+ +
+ +
+ WhatsApp +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ + +
diff --git a/dynamic_accounts_report/static/src/css/report.css b/dynamic_accounts_report/static/src/css/report.css new file mode 100644 index 000000000..a1f6e984c --- /dev/null +++ b/dynamic_accounts_report/static/src/css/report.css @@ -0,0 +1,9 @@ +.mon_fld{ +text-align: right; + +} + +.cf_fld{ +text-align: right; +width: 300px !important; +} \ No newline at end of file diff --git a/dynamic_accounts_report/static/src/js/action_manager.js b/dynamic_accounts_report/static/src/js/action_manager.js new file mode 100644 index 000000000..2017a4bb7 --- /dev/null +++ b/dynamic_accounts_report/static/src/js/action_manager.js @@ -0,0 +1,63 @@ + + + + +// +//import { registry } from "@web/core/registry"; +//import { download } from "@web/core/network/download"; +//import framework from 'web.framework'; +//import session from 'web.session'; +//async function dynamicXlsxDownload({ env, action }) { +// +// framework.blockUI(); +// var def = $.Deferred(); +// download._download({ +// url: '/dynamic_xlsx_reports', +// data: action.data, +// success: def.resolve.bind(def), +// error: (error) => this.call('crash_manager', 'rpc_error', error), +//// complete: framework.unblockUI, +// }); +// framework.unblockUI(); +// return def; +// +//} +// +//registry.category("action_handlers") +// .add('ir_actions_dynamic_xlsx_download', dynamicXlsxDownload); + + +//odoo.define('dynamic_accounts_report.action_manager', function (require) { +// 'use strict'; +// +// downloadXlsx: function (action){ +// framework.blockUI(); +// download._download({ +// url: '/dynamic_xlsx_reports', +// data: action.data, +// complete: framework.unblockUI, +// error: (error) => this.call('crash_manager', 'rpc_error', error), +// }); +// framework.unblockUI(); +// }, +// +// +// }); + + +//odoo.define('dynamic_accounts_report.action_manager', function (require) { +// 'use strict'; +// +// downloadXlsx: function (action){ +// framework.blockUI(); +// session.get_file({ +// url: '/dynamic_xlsx_reports', +// data: action.data, +// complete: framework.unblockUI, +// error: (error) => this.call('crash_manager', 'rpc_error', error), +// }); +//// framework.unblockUI(); +// }, +// +// +// }); \ No newline at end of file diff --git a/dynamic_accounts_report/static/src/js/ageing.js b/dynamic_accounts_report/static/src/js/ageing.js new file mode 100644 index 000000000..195b7b4fb --- /dev/null +++ b/dynamic_accounts_report/static/src/js/ageing.js @@ -0,0 +1,406 @@ +odoo.define('dynamic_accounts_report.ageing', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + + window.click_num = 0; + var PartnerAgeing = AbstractAction.extend({ + template: 'AgeingTemp', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .gl-line': 'show_drop_down', + 'click .view-account-move': 'view_acc_move', + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + + this.wizard_id = action.context.wizard | null; + + }, + + + start: function() { + var self = this; + self.initial_render = true; + rpc.query({ + model: 'account.partner.ageing', + method: 'create', + args: [{ + + }] + }).then(function(t_res) { + self.wizard_id = t_res; + + self.load_data(self.initial_render); + }) + }, + + + load_data: function (initial_render = true) { + + var self = this; + + self.$(".categ").empty(); + try{ + var self = this; + self._rpc({ + model: 'account.partner.ageing', + method: 'view_report', + args: [[this.wizard_id]], + }).then(function(datas) { + _.each(datas['report_lines'][0], function(rep_lines) { + rep_lines.total = self.format_currency(datas['currency'],rep_lines.total); + rep_lines[4] = self.format_currency(datas['currency'],rep_lines[4]); + rep_lines[3] = self.format_currency(datas['currency'],rep_lines[3]); + rep_lines[2] = self.format_currency(datas['currency'],rep_lines[2]); + rep_lines[1] = self.format_currency(datas['currency'],rep_lines[1]); + rep_lines[0] = self.format_currency(datas['currency'],rep_lines[0]); + + rep_lines['direction'] = self.format_currency(datas['currency'],rep_lines['direction']); + + }); + + if (initial_render) { + self.$('.filter_view_tb').html(QWeb.render('AgeingFilterView', { + filter_data: datas['filters'], + })); + self.$el.find('.partners').select2({ + placeholder: ' Partners...', + }); + self.$el.find('.category').select2({ + placeholder: ' Partner Category...', + }); + self.$el.find('.target_move').select2({ + placeholder: ' Target Move...', + }); + self.$el.find('.result_selection').select2({ + placeholder: ' Account Type...', + }); + + } + var child=[]; + + self.$('.table_view_tb').html(QWeb.render('Ageingtable', { + + report_lines : datas['report_lines'], + move_lines :datas['report_lines'][2], + filter : datas['filters'], + currency : datas['currency'], + })); + + }); + + } + catch (el) { + window.location.href + } + }, + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + print_pdf: function(e) { + e.preventDefault(); + + var self = this; + self._rpc({ + model: 'account.partner.ageing', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.partner_ageing', + 'report_file': 'dynamic_accounts_report.partner_ageing', + 'data': { + 'report_data': data + }, + 'context': { + 'active_model': 'account.partner.ageing', + 'landscape': 1, + 'ageing_pdf_report': true + + }, + 'display_name': 'Partner Ageing', + }; + + return self.do_action(action); + }); + }, + + + + print_xlsx: function() { + var self = this; + self._rpc({ + model: 'account.partner.ageing', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'account.partner.ageing', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': JSON.stringify(data['report_lines']), + 'report_name': 'Partner Ageing', + 'dfr_data': JSON.stringify(data), + }, + }; +// return self.do_action(action); + core.action_registry.map.t_b.prototype.downloadXlsx(action) + }); + }, + + + + + + create_lines_with_style: function(rec, attr, datas) { + var temp_str = ""; + var style_name = "border-bottom: 1px solid #e6e6e6;"; + var attr_name = attr + " style="+style_name; + + + + temp_str += ""+rec['code'] +rec['name'] +""; + if(datas.currency[1]=='after'){ + temp_str += ""+rec['debit'].toFixed(2)+datas.currency[0]+""; + temp_str += ""+rec['credit'].toFixed(2) +datas.currency[0]+ ""; + + } + else{ + temp_str += ""+datas.currency[0]+rec['debit'].toFixed(2) + ""; + temp_str += ""+datas.currency[0]+rec['credit'].toFixed(2) + ""; + + } + return temp_str; + }, + + + journal_line_click: function (el){ + + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + + }, + + show_drop_down: function(event) { + event.preventDefault(); + var self = this; + var account_id = $(event.currentTarget).data('account-id'); + + var partner_id = $(event.currentTarget)[0].cells[0].innerText; + + var offset = 0; + var td = $(event.currentTarget).next('tr').find('td'); + if (td.length == 1) { + + self._rpc({ + model: 'account.partner.ageing', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + + + _.each(data['report_lines'][0], function(rep_lines) { + _.each(rep_lines['child_lines'], function(child_line) { + child_line.amount = self.format_currency(data['currency'],child_line.amount); + + }); + }); + + + for (var i = 0; i < data['report_lines'][0].length; i++) { + if (account_id == data['report_lines'][0][i]['partner_id'] ){ + $(event.currentTarget).next('tr').find('td .gl-table-div').remove(); + $(event.currentTarget).next('tr').find('td ul').after( + QWeb.render('SubSectional', { + account_data: data['report_lines'][0][i]['child_lines'], + })) + $(event.currentTarget).next('tr').find('td ul li:first a').css({ + 'background-color': '#00ede8', + 'font-weight': 'bold', + }); + } + } + + }); + } + }, + + view_acc_move: function(event) { + event.preventDefault(); + var self = this; + var context = {}; + var show_acc_move = function(res_model, res_id, view_id) { + var action = { + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: res_model, + views: [ + [view_id || false, 'form'] + ], + res_id: res_id, + target: 'current', + context: context, + }; + return self.do_action(action); + }; + rpc.query({ + model: 'account.move', + method: 'search_read', + domain: [ + ['id', '=', $(event.currentTarget).data('move-id')] + ], + fields: ['id'], + limit: 1, + }) + .then(function(record) { + if (record.length > 0) { + show_acc_move('account.move', record[0].id); + } else { + show_acc_move('account.move', $(event.currentTarget).data('move-id')); + } + }); + }, + + + apply_filter: function(event) { + + event.preventDefault(); + var self = this; + self.initial_render = false; + + var filter_data_selected = {}; + + if ($("#date_from").val()) { + var dateString = $("#date_from").val(); + + filter_data_selected.date_from= dateString; + } + var partner_ids = []; + var partner_text = []; + var span_res = document.getElementById("partner_res") + var partner_list = $(".partners").select2('data') + for (var i = 0; i < partner_list.length; i++) { + if(partner_list[i].element[0].selected === true) + {partner_ids.push(parseInt(partner_list[i].id)) + if(partner_text.includes(partner_list[i].text) === false) + {partner_text.push(partner_list[i].text) + } + span_res.value = partner_text + span_res.innerHTML=span_res.value; + } + } + if (partner_list.length == 0){ + span_res.value = "" + span_res.innerHTML=""; + } + filter_data_selected.partner_ids = partner_ids + + var partner_category_ids = []; + var partner_category_text = []; + var span_res = document.getElementById("category_res") + var category_list = $(".category").select2('data') + + for (var i = 0; i < category_list.length; i++) { + if(category_list[i].element[0].selected === true) + {partner_category_ids.push(parseInt(category_list[i].id)) + if(partner_category_text.includes(category_list[i].text) === false) + {partner_category_text.push(category_list[i].text) + } + span_res.value = partner_category_text + span_res.innerHTML=span_res.value; + } + } + if (category_list.length == 0){ + span_res.value = "" + span_res.innerHTML=""; + } + filter_data_selected.partner_category_ids = partner_category_ids + + + if ($(".target_move").length) { + + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + + if ($(".result_selection").length) { + var account_res = document.getElementById("account_res") + filter_data_selected.result_selection = $(".result_selection")[1].value + account_res.value = $(".result_selection")[1].value + account_res.innerHTML=account_res.value; + if ($(".result_selection")[1].value == "") { + account_res.innerHTML="customer"; + + } + } + + + rpc.query({ + model: 'account.partner.ageing', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("p_a", PartnerAgeing); + return PartnerAgeing; +}); \ No newline at end of file diff --git a/dynamic_accounts_report/static/src/js/cash_flow.js b/dynamic_accounts_report/static/src/js/cash_flow.js new file mode 100644 index 000000000..4e9cba889 --- /dev/null +++ b/dynamic_accounts_report/static/src/js/cash_flow.js @@ -0,0 +1,336 @@ +odoo.define('dynamic_cash_flow_statements.cash_flow', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + + window.click_num = 0; + var CashFlow = AbstractAction.extend({ + template: 'CFTemp', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .cf-line': 'get_move_lines', + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + this.wizard_id = action.context.wizard | null; + }, + + + start: function() { + var self = this; + self.initial_render = true; + rpc.query({ + model: 'account.cash.flow', + method: 'create', + args: [{ + + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + }, + + get_move_lines: function(event) { + event.preventDefault(); + var self = this; + var account_id = $(event.currentTarget).data('account-id'); + var offset = 0; + var td = $(event.currentTarget).next('tr').find('td'); + if (td.length == 1) { + self._rpc({ + model: 'account.cash.flow', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(datas) { + _.each(datas['journal_res'], function(journal_lines) { + _.each(journal_lines['journal_lines'], function(rep_lines) { + rep_lines.total_debit = self.format_currency(datas['currency'],rep_lines.total_debit); + rep_lines.total_credit = self.format_currency(datas['currency'],rep_lines.total_credit); + rep_lines.balance = self.format_currency(datas['currency'],rep_lines.balance); + + + + + }); + + }); + _.each(datas['account_res'], function(journal_lines) { + _.each(journal_lines['journal_lines'], function(rep_lines) { + rep_lines.total_debit = self.format_currency(datas['currency'],rep_lines.total_debit); + rep_lines.total_credit = self.format_currency(datas['currency'],rep_lines.total_credit); + rep_lines.total_balance = self.format_currency(datas['currency'],rep_lines.total_balance); + + + }); + _.each(journal_lines['move_lines'], function(move_lines) { + move_lines.total_debit = self.format_currency(datas['currency'],move_lines.total_debit); + move_lines.total_credit = self.format_currency(datas['currency'],move_lines.total_credit); + move_lines.balance = self.format_currency(datas['currency'],move_lines.balance); + + + + + }); + }); + + + if(datas['levels']== 'detailed'){ + $(event.currentTarget).next('tr').find('td ul').after( + QWeb.render('SubSectionCF', { + count: 3, + offset: 0, + account_data: datas['journal_res'], + level:datas['levels'], + currency : datas['currency'], + line_id:parseInt(event.currentTarget.attributes[3].value), + })) + }else if(datas['levels']== 'very' || datas['levels']== false){ + $(event.currentTarget).next('tr').find('td ul').after( + QWeb.render('ChildSubSectionCF', { + count: 3, + offset: 0, + account_data: datas['account_res'], + level:datas['levels'], + currency : datas['currency'], + line_id:parseInt(event.currentTarget.attributes[3].value), + })) + } + + $(event.currentTarget).next('tr').find('td ul li:first a').css({ + 'background-color': '#00ede8', + 'font-weight': 'bold', + }); + }) + } + }, + + + load_data: function (initial_render = true) { + var self = this; + self.$(".categ").empty(); + try{ + var self = this; + self._rpc({ + model: 'account.cash.flow', + method: 'view_report', + args: [[this.wizard_id]], + }).then(function(datas) { + + + _.each(datas['fetched_data'], function(rep_lines) { + rep_lines.total_debit = self.format_currency(datas['currency'],rep_lines.total_debit); + rep_lines.total_credit = self.format_currency(datas['currency'],rep_lines.total_credit); + rep_lines.total_balance = self.format_currency(datas['currency'],rep_lines.total_balance); + + + + + }); + if (initial_render) { + self.$('.filter_view_tb').html(QWeb.render('CashFilterView', { + filter_data: datas['filters'], + })); + self.$el.find('.journals').select2({ + placeholder: 'Select Journals...', + }); + self.$el.find('.target_move').select2({ + placeholder: 'Target Move...', + }); + self.$el.find('.levels').select2({ + placeholder: 'Levels...', + }); + } + var child=[]; + + self.$('.table_view_tb').html(QWeb.render('CashTable', { + + account_data: datas['fetched_data'], + level:datas['levels'], + currency : datas['currency'], + })); + + }); + + } + catch (el) { + window.location.href + } + }, + + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + show_gl: function(e) { + var self = this; + var account_id = $(e.target).attr('data-account-id'); + var options = { + account_ids: [account_id], + } + + var action = { + type: 'ir.actions.client', + name: 'GL View', + tag: 'g_l', + target: 'new', + + domain: [['account_ids','=', account_id]], + + + } + return this.do_action(action); + + }, + print_pdf: function(e) { + e.preventDefault(); + var self = this; + self._rpc({ + model: 'account.cash.flow', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.cash_flow', + 'report_file': 'dynamic_accounts_report.cash_flow', + 'data': { + 'report_data': data + }, + 'context': { + 'active_model': 'account.cash.flow', + 'landscape': 1, + 'trial_pdf_report': true + }, + 'display_name': 'Cash Flow Statements', + }; + return self.do_action(action); + }); + }, + + + + print_xlsx: function() { + var self = this; + self._rpc({ + model: 'account.cash.flow', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'account.cash.flow', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': JSON.stringify(data['report_lines']), + 'report_name': 'Cash Flow Statements', + 'dfr_data': JSON.stringify(data), + }, + }; +// return self.do_action(action); + core.action_registry.map.t_b.prototype.downloadXlsx(action) + }); + }, + + journal_line_click: function (el){ + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + + }, + + + apply_filter: function(event) { + + event.preventDefault(); + var self = this; + self.initial_render = false; + + var filter_data_selected = {}; + + + + if ($(".levels").length){ + var level_res = document.getElementById("level_res") + filter_data_selected.levels = $(".levels")[1].value + level_res.value = $(".levels")[1].value + level_res.innerHTML=level_res.value; + if ($(".levels").value==""){ + type_res.innerHTML="summary"; + filter_data_selected.type = "Summary" + } + } + + if ($("#date_from").val()) { + var dateString = $("#date_from").val(); + filter_data_selected.date_from = dateString; + } + if ($("#date_to").val()) { + var dateString = $("#date_to").val(); + filter_data_selected.date_to = dateString; + } + + if ($(".target_move").length) { + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + rpc.query({ + model: 'account.cash.flow', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("c_f", CashFlow); + return CashFlow; +}); \ No newline at end of file diff --git a/dynamic_accounts_report/static/src/js/daybook.js b/dynamic_accounts_report/static/src/js/daybook.js new file mode 100644 index 000000000..e292c9de5 --- /dev/null +++ b/dynamic_accounts_report/static/src/js/daybook.js @@ -0,0 +1,388 @@ +odoo.define('dynamic_partner_daybook.daybook', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + + window.click_num = 0; + var DayBook = AbstractAction.extend({ + template: 'DaybookTemp', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .db-line': 'show_drop_down', + 'click .view-account-move': 'view_acc_move', + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + this.wizard_id = action.context.wizard | null; + }, + + + start: function() { + var self = this; + self.initial_render = true; + rpc.query({ + model: 'account.day.book', + method: 'create', + args: [{ + + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + }, + + + load_data: function (initial_render = true) { + var self = this; + self.$(".categ").empty(); + try{ + var self = this; + self._rpc({ + model: 'account.day.book', + method: 'view_report', + args: [[this.wizard_id]], + }).then(function(datas) { + _.each(datas['report_lines'], function(rep_lines) { + rep_lines.debit = self.format_currency(datas['currency'],rep_lines.debit); + rep_lines.credit = self.format_currency(datas['currency'],rep_lines.credit); + rep_lines.balance = self.format_currency(datas['currency'],rep_lines.balance); + + }); + + if (initial_render) { + + self.$('.filter_view_db').html(QWeb.render('DayFilterView', { + filter_data: datas['filters'], + })); + self.$el.find('.journals').select2({ + placeholder: ' Journals...', + }); + self.$el.find('.account').select2({ + placeholder: ' Accounts...', + }); + self.$el.find('.target_move').select2({ + placeholder: 'Target Move...', + }); + + + } + var child=[]; + + self.$('.table_view_db').html(QWeb.render('Daytable', { + + report_lines : datas['report_lines'], + filter : datas['filters'], + currency : datas['currency'], + })); + + }); + + } + catch (el) { + window.location.href + } + }, + + + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + print_pdf: function(e) { + e.preventDefault(); + + var self = this; + self._rpc({ + model: 'account.day.book', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.day_book', + 'report_file': 'dynamic_accounts_report.day_book', + 'data': { + 'report_data': data + }, + 'context': { + 'active_model': 'account.day.book', + 'landscape': 1, + 'daybook_pdf_report': true + }, + 'display_name': 'Day Book', + }; + + return self.do_action(action); + }); + }, + + print_xlsx: function() { + var self = this; + self._rpc({ + model: 'account.day.book', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'account.day.book', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': JSON.stringify(data['report_lines']), + 'report_name': 'Day Book', + 'dfr_data': JSON.stringify(data), + }, + }; +// return self.do_action(action); + core.action_registry.map.t_b.prototype.downloadXlsx(action) + }); + }, + + create_lines_with_style: function(rec, attr, datas) { + + var temp_str = ""; + var style_name = "border-bottom: 1px solid #e6e6e6;"; + var attr_name = attr + " style="+style_name; + temp_str += ""+rec['code'] +rec['name'] +""; + if(datas.currency[1]=='after'){ + temp_str += ""+rec['debit'].toFixed(2)+datas.currency[0]+""; + temp_str += ""+rec['credit'].toFixed(2) +datas.currency[0]+ ""; + } + else{ + temp_str += ""+datas.currency[0]+rec['debit'].toFixed(2) + ""; + temp_str += ""+datas.currency[0]+rec['credit'].toFixed(2) + ""; + } + return temp_str; + }, + + + journal_line_click: function (el){ + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + + }, + + show_drop_down: function(event) { + event.preventDefault(); + var self = this; + var account_id = $(event.currentTarget).data('account-id'); + var offset = 0; + var td = $(event.currentTarget).next('tr').find('td'); + if (td.length == 1) { + + self._rpc({ + model: 'account.day.book', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + _.each(data['report_lines'], function(rep_lines) { + _.each(rep_lines['child_lines'], function(move_line) { + + move_line.debit = self.format_currency(data['currency'],move_line.debit); + move_line.credit = self.format_currency(data['currency'],move_line.credit); + move_line.balance = self.format_currency(data['currency'],move_line.balance); + + + }); + }); + for (var i = 0; i < data['report_lines'].length; i++) { + + if (account_id == data['report_lines'][i]['id'] ){ + $(event.currentTarget).next('tr').find('td .db-table-div').remove(); + $(event.currentTarget).next('tr').find('td ul').after( + QWeb.render('SubSectiondb', { + + account_data: data['report_lines'][i]['child_lines'], + currency_symbol : data.currency[0], + currency_position : data.currency[1], + })) + + $(event.currentTarget).next('tr').find('td ul li:first a').css({ + 'background-color': '#00ede8', + 'font-weight': 'bold', + }); + } + } + + }); + } + }, + + view_acc_move: function(event) { + + event.preventDefault(); + var self = this; + var context = {}; + var show_acc_move = function(res_model, res_id, view_id) { + var action = { + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: res_model, + views: [ + [view_id || false, 'form'] + ], + res_id: res_id, + target: 'current', + context: context, + }; + return self.do_action(action); + }; + rpc.query({ + model: 'account.move', + method: 'search_read', + domain: [ + ['id', '=', $(event.currentTarget).data('move-id')] + ], + fields: ['id'], + limit: 1, + }) + .then(function(record) { + + if (record.length > 0) { + show_acc_move('account.move', record[0].id); + } else { + show_acc_move('account.move', $(event.currentTarget).data('move-id')); + } + }); + }, + + + apply_filter: function(event) { + + event.preventDefault(); + var self = this; + self.initial_render = false; + + var filter_data_selected = {}; + + + var account_ids = []; + var account_text = []; + + var account_res = document.getElementById("acc_res") + + var account_list = $(".account").select2('data') + for (var i = 0; i < account_list.length; i++) { + if(account_list[i].element[0].selected === true){ + + account_ids.push(parseInt(account_list[i].id)) + if(account_text.includes(account_list[i].text) === false){ + account_text.push(account_list[i].text) + } + account_res.value = account_text + account_res.innerHTML=account_res.value; + } + } + if (account_list.length == 0){ + account_res.value = "" + account_res.innerHTML=""; + + } + + filter_data_selected.account_ids = account_ids + + + + var journal_ids = []; + var journal_text = []; + var journal_res = document.getElementById("journal_res") + var journal_list = $(".journals").select2('data') + for (var i = 0; i < journal_list.length; i++) { + if(journal_list[i].element[0].selected === true){ + + journal_ids.push(parseInt(journal_list[i].id)) + if(journal_text.includes(journal_list[i].text) === false){ + journal_text.push(journal_list[i].text) + } + journal_res.value = journal_text + journal_res.innerHTML=journal_res.value; + } + } + if (journal_list.length == 0){ + journal_res.value = "" + journal_res.innerHTML=""; + + } + filter_data_selected.journal_ids = journal_ids + + if ($("#date_from").val()) { + var dateString = $("#date_from").val(); + + filter_data_selected.date_from = dateString; + } + if ($("#date_to").val()) { + var dateString = $("#date_to").val(); + filter_data_selected.date_to = dateString; + } + + if ($(".target_move").length) { + + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + + rpc.query({ + model: 'account.day.book', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("d_b", DayBook); + return DayBook; +}); diff --git a/dynamic_accounts_report/static/src/js/financial_reports.js b/dynamic_accounts_report/static/src/js/financial_reports.js new file mode 100644 index 000000000..bf30549ab --- /dev/null +++ b/dynamic_accounts_report/static/src/js/financial_reports.js @@ -0,0 +1,358 @@ +odoo.define('dynamic_accounts_report.financial_reports', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + + window.click_num = 0; + var ProfitAndLoss = AbstractAction.extend({ + template: 'dfr_template_new', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .show-gl': 'show_gl', + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + this.wizard_id = action.context.wizard | null; + }, + start: function() { + var self = this; + self.initial_render = true; + rpc.query({ + model: 'dynamic.balance.sheet.report', + method: 'create', + args: [{ + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + }, + + load_data: function (initial_render = true) { + var self = this; + var action_title = self._title; + self.$(".categ").empty(); + try{ + var self = this; + self._rpc({ + model: 'dynamic.balance.sheet.report', + method: 'view_report', + args: [[this.wizard_id], action_title], + }).then(function(datas) { + + if (initial_render) { + self.$('.filter_view_dfr').html(QWeb.render('DfrFilterView', { + filter_data: datas['filters'], + title : datas['name'], + })); + self.$el.find('.journals').select2({ + placeholder: ' Journals...', + }); + self.$el.find('.account').select2({ + placeholder: ' Accounts...', + }); + self.$el.find('.account-tag').select2({ + placeholder: 'Account Tag...', + }); + self.$el.find('.analytics').select2({ + placeholder: 'Analytic Accounts...', + }); + self.$el.find('.analytic-tag').select2({ + placeholder: 'Analytic Tag...', + }); + self.$el.find('.target_move').select2({ + placeholder: 'Target Move...', + }); + + } + var child=[]; + self.$('.table_view_dfr').html(QWeb.render('dfr_table', { + + report_lines : datas['report_lines'], + filter : datas['filters'], + currency : datas['currency'], + credit_total : datas['credit_total'], + debit_total : datas['debit_total'], + debit_balance : datas['debit_balance'], + bs_lines : datas['bs_lines'], + })); + }); + } + catch (el) { + window.location.href + } + }, + + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + show_gl: function(e) { + var self = this; + var account_id = $(e.target).attr('data-account-id'); + var options = { + account_ids: [account_id], + } + var action = { + type: 'ir.actions.client', + name: 'GL View', + tag: 'g_l', + target: 'new', + domain: [['account_ids','=', account_id]], + + } + return this.do_action(action); + }, + + print_pdf: function(e) { + e.preventDefault(); + var self = this; + var action_title = self._title; + self._rpc({ + model: 'dynamic.balance.sheet.report', + method: 'view_report', + args: [ + [self.wizard_id], action_title + ], + }).then(function(data) { + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.balance_sheet', + 'report_file': 'dynamic_accounts_report.balance_sheet', + 'data': { + 'report_data': data, + 'report_name': action_title + }, + 'context': { + 'active_model': 'dynamic.balance.sheet.report', + 'landscape': 1, + 'bs_report': true + }, + 'display_name': action_title, + }; + return self.do_action(action); + }); + }, + + print_xlsx: function() { + var self = this; + var action_title = self._title; + self._rpc({ + model: 'dynamic.balance.sheet.report', + method: 'view_report', + args: [ + [self.wizard_id], action_title + ], + }).then(function(data) { + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'dynamic.balance.sheet.report', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': action_title, + 'report_name': action_title, + 'dfr_data': JSON.stringify(data['bs_lines']), + }, + }; +// return self.do_action(action); + core.action_registry.map.t_b.prototype.downloadXlsx(action) + }); + }, + + journal_line_click: function (el){ + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + + }, + + apply_filter: function(event) { + + event.preventDefault(); + var self = this; + self.initial_render = false; + var filter_data_selected = {}; + var account_ids = []; + var account_text = []; + var account_res = document.getElementById("acc_res") + var account_list = $(".account").select2('data') + for (var i = 0; i < account_list.length; i++) { + if(account_list[i].element[0].selected === true){ + + account_ids.push(parseInt(account_list[i].id)) + if(account_text.includes(account_list[i].text) === false){ + account_text.push(account_list[i].text) + } + account_res.value = account_text + account_res.innerHTML=account_res.value; + } + } + if (account_list.length == 0){ + account_res.value = "" + account_res.innerHTML=""; + + } + filter_data_selected.account_ids = account_ids + + + var journal_ids = []; + var journal_text = []; + var journal_res = document.getElementById("journal_res") + var journal_list = $(".journals").select2('data') + for (var i = 0; i < journal_list.length; i++) { + if(journal_list[i].element[0].selected === true){ + + journal_ids.push(parseInt(journal_list[i].id)) + if(journal_text.includes(journal_list[i].text) === false){ + journal_text.push(journal_list[i].text) + } + journal_res.value = journal_text + journal_res.innerHTML=journal_res.value; + } + } + if (journal_list.length == 0){ + journal_res.value = "" + journal_res.innerHTML=""; + + } + filter_data_selected.journal_ids = journal_ids + + var account_tag_ids = []; + var account_tag_text = []; + var account_tag_res = document.getElementById("acc_tag_res") + + var account_tag_list = $(".account-tag").select2('data') + for (var i = 0; i < account_tag_list.length; i++) { + if(account_tag_list[i].element[0].selected === true){ + + account_tag_ids.push(parseInt(account_tag_list[i].id)) + if(account_tag_text.includes(account_tag_list[i].text) === false){ + account_tag_text.push(account_tag_list[i].text) + } + + account_tag_res.value = account_tag_text + account_tag_res.innerHTML=account_tag_res.value; + } + } + if (account_tag_list.length == 0){ + account_tag_res.value = "" + account_tag_res.innerHTML=""; + + } + filter_data_selected.account_tag_ids = account_tag_ids + + var analytic_ids = [] + var analytic_text = []; + var analytic_res = document.getElementById("analytic_res") + var analytic_list = $(".analytics").select2('data') + + for (var i = 0; i < analytic_list.length; i++) { + if(analytic_list[i].element[0].selected === true){ + + analytic_ids.push(parseInt(analytic_list[i].id)) + if(analytic_text.includes(analytic_list[i].text) === false){ + analytic_text.push(analytic_list[i].text) + } + analytic_res.value = analytic_text + analytic_res.innerHTML=analytic_res.value; + } + } + if (analytic_list.length == 0){ + analytic_res.value = "" + analytic_res.innerHTML=""; + + } + filter_data_selected.analytic_ids = analytic_ids + + var analytic_tag_ids = []; + var analytic_tag_text = []; + var analytic_tag_res = document.getElementById("analic_tag_res") + var analytic_tag_list = $(".analytic-tag").select2('data') + for (var i = 0; i < analytic_tag_list.length; i++) { + if(analytic_tag_list[i].element[0].selected === true){ + + analytic_tag_ids.push(parseInt(analytic_tag_list[i].id)) + if(analytic_tag_text.includes(analytic_tag_list[i].text) === false){ + analytic_tag_text.push(analytic_tag_list[i].text) + + } + + analytic_tag_res.value = analytic_tag_text + analytic_tag_res.innerHTML=analytic_tag_res.value; + } + } + if (analytic_tag_list.length == 0){ + analytic_tag_res.value = "" + analytic_tag_res.innerHTML=""; + + } + filter_data_selected.analytic_tag_ids = analytic_tag_ids + + + if ($("#date_from").val()) { + var dateString = $("#date_from").val(); + filter_data_selected.date_from = dateString; + } + if ($("#date_to").val()) { + var dateString = $("#date_to").val(); + filter_data_selected.date_to = dateString; + } + + if ($(".target_move").length) { + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + rpc.query({ + model: 'dynamic.balance.sheet.report', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("dfr_n", ProfitAndLoss); + return ProfitAndLoss; +}); diff --git a/dynamic_accounts_report/static/src/js/general_ledger.js b/dynamic_accounts_report/static/src/js/general_ledger.js new file mode 100644 index 000000000..292a734ae --- /dev/null +++ b/dynamic_accounts_report/static/src/js/general_ledger.js @@ -0,0 +1,460 @@ +odoo.define('dynamic_accounts_report.general_ledger', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + var trial = require('dynamic_accounts_report.trial_balance'); + + window.click_num = 0; + var GeneralLedger = AbstractAction.extend({ + template: 'GeneralTemp', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .gl-line': 'show_drop_down', + 'click .view-account-move': 'view_acc_move', + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + this.wizard_id = action.context.wizard | null; + }, + + + start: function() { + var self = this; + self.initial_render = true; + if (this.searchModel.config.domain.length != 0) { + rpc.query({ + model: 'account.general.ledger', + method: 'create', + args: [{ + account_ids : [this.searchModel.config.domain[0][2]] + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + }else{ + rpc.query({ + model: 'account.general.ledger', + method: 'create', + args: [{ + + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + } + }, + + + load_data: function (initial_render = true) { + var self = this; + self.$(".categ").empty(); + try{ + var self = this; + var action_title = self._title + self._rpc({ + model: 'account.general.ledger', + method: 'view_report', + args: [[this.wizard_id], action_title], + }).then(function(datas) { + _.each(datas['report_lines'], function(rep_lines) { + rep_lines.debit = self.format_currency(datas['currency'],rep_lines.debit); + rep_lines.credit = self.format_currency(datas['currency'],rep_lines.credit); + rep_lines.balance = self.format_currency(datas['currency'],rep_lines.balance); + + + + + }); + + if (initial_render) { + self.$('.filter_view_tb').html(QWeb.render('GLFilterView', { + filter_data: datas['filters'], + title : datas['name'], + })); + self.$el.find('.journals').select2({ + placeholder: ' Journals...', + }); + self.$el.find('.account').select2({ + placeholder: ' Accounts...', + }); + self.$el.find('.analytics').select2({ + placeholder: 'Analytic Accounts...', + }); + self.$el.find('.analytic_tags').select2({ + placeholder: 'Analytic Tags...', + }); + self.$el.find('.target_move').select2({ + placeholder: 'Target Move...', + }); + + } + var child=[]; + + self.$('.table_view_tb').html(QWeb.render('GLTable', { + + report_lines : datas['report_lines'], + filter : datas['filters'], + currency : datas['currency'], + credit_total : datas['credit_total'], + debit_total : datas['debit_total'], + debit_balance : datas['debit_balance'] + })); + + }); + + } + catch (el) { + window.location.href + } + }, + + print_pdf: function(e) { + e.preventDefault(); + var self = this; + var action_title = self._title + self._rpc({ + model: 'account.general.ledger', + method: 'view_report', + args: [ + [self.wizard_id], action_title + ], + }).then(function(data) { + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.general_ledger', + 'report_file': 'dynamic_accounts_report.general_ledger', + 'data': { + 'report_data': data + }, + 'context': { + 'active_model': 'account.general.ledger', + 'landscape': 1, + 'trial_pdf_report': true + }, + 'display_name': action_title, + }; + return self.do_action(action); + }); + }, + + print_xlsx: function() { + var self = this; + var action_title = self._title + self._rpc({ + model: 'account.general.ledger', + method: 'view_report', + args: [ + [self.wizard_id], action_title + ], + }).then(function(data) { + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'account.general.ledger', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': JSON.stringify(data['report_lines']), + 'report_name': action_title, + 'dfr_data': JSON.stringify(data), + }, + }; +// return self.do_action(action); + core.action_registry.map.t_b.prototype.downloadXlsx(action) + }); + }, + + + + + + create_lines_with_style: function(rec, attr, datas) { + var temp_str = ""; + var style_name = "border-bottom: 1px solid #e6e6e6;"; + var attr_name = attr + " style="+style_name; + + temp_str += ""+rec['code'] +rec['name'] +""; + if(datas.currency[1]=='after'){ + temp_str += ""+rec['debit'].toFixed(2)+datas.currency[0]+""; + temp_str += ""+rec['credit'].toFixed(2) +datas.currency[0]+ ""; + } + else{ + temp_str += ""+datas.currency[0]+rec['debit'].toFixed(2) + ""; + temp_str += ""+datas.currency[0]+rec['credit'].toFixed(2) + ""; + + } + return temp_str; + }, + + + journal_line_click: function (el){ + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + + }, + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + show_drop_down: function(event) { + event.preventDefault(); + var self = this; + var account_id = $(event.currentTarget).data('account-id'); + var offset = 0; + var td = $(event.currentTarget).next('tr').find('td'); + if (td.length == 1) { + var action_title = self._title + self._rpc({ + model: 'account.general.ledger', + method: 'view_report', + args: [ + [self.wizard_id], action_title + ], + }).then(function(data) { + _.each(data['report_lines'], function(rep_lines) { + _.each(rep_lines['move_lines'], function(move_line) { + + move_line.debit = self.format_currency(data['currency'],move_line.debit); + move_line.credit = self.format_currency(data['currency'],move_line.credit); + move_line.balance = self.format_currency(data['currency'],move_line.balance); + + + }); + }); + + for (var i = 0; i < data['report_lines'].length; i++) { + + if (account_id == data['report_lines'][i]['id'] ){ + + $(event.currentTarget).next('tr').find('td .gl-table-div').remove(); + $(event.currentTarget).next('tr').find('td ul').after( + QWeb.render('SubSection', { + account_data: data['report_lines'][i]['move_lines'], + currency_symbol : data.currency[0], + currency_position : data.currency[1], + + })) + $(event.currentTarget).next('tr').find('td ul li:first a').css({ + 'background-color': '#00ede8', + 'font-weight': 'bold', + }); + } + } + + }); + } + }, + + view_acc_move: function(event) { + event.preventDefault(); + var self = this; + var context = {}; + var show_acc_move = function(res_model, res_id, view_id) { + var action = { + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: res_model, + views: [ + [view_id || false, 'form'] + ], + res_id: res_id, + target: 'current', + context: context, + }; + return self.do_action(action); + }; + rpc.query({ + model: 'account.move', + method: 'search_read', + domain: [ + ['id', '=', $(event.currentTarget).data('move-id')] + ], + fields: ['id'], + limit: 1, + }) + .then(function(record) { + if (record.length > 0) { + show_acc_move('account.move', record[0].id); + } else { + show_acc_move('account.move', $(event.currentTarget).data('move-id')); + } + }); + }, + + apply_filter: function(event) { + + event.preventDefault(); + var self = this; + self.initial_render = false; + + var filter_data_selected = {}; + + + var account_ids = []; + var account_text = []; + + var account_res = document.getElementById("acc_res") + var account_list = $(".account").select2('data') + for (var i = 0; i < account_list.length; i++) { + if(account_list[i].element[0].selected === true){ + + account_ids.push(parseInt(account_list[i].id)) + if(account_text.includes(account_list[i].text) === false){ + account_text.push(account_list[i].text) + } + account_res.value = account_text + account_res.innerHTML=account_res.value; + } + } + if (account_list.length == 0){ + account_res.value = "" + account_res.innerHTML=""; + + } + filter_data_selected.account_ids = account_ids + + + if(!(this._title == 'Bank Book' || this._title == 'Cash Book')){ + + var journal_ids = []; + var journal_text = []; + var journal_res = document.getElementById("journal_res") + var journal_list = $(".journals").select2('data') + + for (var i = 0; i < journal_list.length; i++) { + if(journal_list[i].element[0].selected === true){ + + journal_ids.push(parseInt(journal_list[i].id)) + if(journal_text.includes(journal_list[i].text) === false){ + journal_text.push(journal_list[i].text) + } + journal_res.value = journal_text + journal_res.innerHTML=journal_res.value; + } + } + if (journal_list.length == 0){ + journal_res.value = "" + journal_res.innerHTML=""; + + } + filter_data_selected.journal_ids = journal_ids + + } + + + + var analytic_ids = [] + var analytic_text = []; + var analytic_res = document.getElementById("analytic_res") + var analytic_list = $(".analytics").select2('data') + + for (var i = 0; i < analytic_list.length; i++) { + if(analytic_list[i].element[0].selected === true){ + + analytic_ids.push(parseInt(analytic_list[i].id)) + if(analytic_text.includes(analytic_list[i].text) === false){ + analytic_text.push(analytic_list[i].text) + } + analytic_res.value = analytic_text + analytic_res.innerHTML=analytic_res.value; + } + } + if (analytic_list.length == 0){ + analytic_res.value = "" + analytic_res.innerHTML=""; + + } + filter_data_selected.analytic_ids = analytic_ids + + var analytic_tag_ids = [] + var analytic_tag_text = []; + var analytic_tag_res = document.getElementById("analytic_tag_res") + var analytic_tag_list = $(".analytic_tags").select2('data') + for (var i = 0; i < analytic_tag_list.length; i++) { + if(analytic_tag_list[i].element[0].selected === true){ + + analytic_tag_ids.push(parseInt(analytic_tag_list[i].id)) + if(analytic_tag_text.includes(analytic_tag_list[i].text) === false){ + analytic_tag_text.push(analytic_tag_list[i].text) + } + analytic_tag_res.value = analytic_tag_text + analytic_tag_res.innerHTML=analytic_tag_res.value; + } + } + if (analytic_tag_list.length == 0){ + analytic_tag_res.value = "" + analytic_tag_res.innerHTML=""; + + } + filter_data_selected.analytic_tag_ids = analytic_tag_ids + + if ($("#date_from").val()) { + + var dateString = $("#date_from").val(); + filter_data_selected.date_from = dateString; + } + if ($("#date_to").val()) { + var dateString = $("#date_to").val(); + filter_data_selected.date_to = dateString; + } + + if ($(".target_move").length) { + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + rpc.query({ + model: 'account.general.ledger', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("g_l", GeneralLedger); + return GeneralLedger; +}); \ No newline at end of file diff --git a/dynamic_accounts_report/static/src/js/partner_ledger.js b/dynamic_accounts_report/static/src/js/partner_ledger.js new file mode 100644 index 000000000..a72ca44ee --- /dev/null +++ b/dynamic_accounts_report/static/src/js/partner_ledger.js @@ -0,0 +1,432 @@ +odoo.define('dynamic_accounts_report.partner_ledger', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + + window.click_num = 0; + var PartnerLedger = AbstractAction.extend({ + template: 'PartnerTemp', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .pl-line': 'show_drop_down', + 'click .view-account-move': 'view_acc_move', + + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + this.wizard_id = action.context.wizard | null; + }, + + start: function() { + var self = this; + self.initial_render = true; + rpc.query({ + model: 'account.partner.ledger', + method: 'create', + args: [{ + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + }, + + load_data: function (initial_render = true) { + var self = this; + self.$(".categ").empty(); + try{ + var self = this; + self._rpc({ + model: 'account.partner.ledger', + method: 'view_report', + args: [[this.wizard_id]], + }).then(function(datas) { + _.each(datas['report_lines'], function(rep_lines) { + rep_lines.debit = self.format_currency(datas['currency'],rep_lines.debit); + rep_lines.credit = self.format_currency(datas['currency'],rep_lines.credit); + rep_lines.balance = self.format_currency(datas['currency'],rep_lines.balance); + + + + + }); + + + + if (initial_render) { + self.$('.filter_view_tb').html(QWeb.render('PLFilterView', { + filter_data: datas['filters'], + })); + self.$el.find('.journals').select2({ + placeholder: ' Journals...', + }); + + self.$el.find('.account').select2({ + placeholder: ' Accounts...', + }); + self.$el.find('.partners').select2({ + placeholder: 'Partners...', + }); + self.$el.find('.reconciled').select2({ + placeholder: 'Reconciled status...', + }); + self.$el.find('.type').select2({ + placeholder: 'Account Type...', + }); + self.$el.find('.category').select2({ + placeholder: 'Partner Tag...', + }); + self.$el.find('.acc').select2({ + placeholder: 'Select Acc...', + }); + self.$el.find('.target_move').select2({ + placeholder: 'Target Move...', + }); + } + var child=[]; + + self.$('.table_view_tb').html(QWeb.render('PLTable', { + report_lines : datas['report_lines'], + filter : datas['filters'], + currency : datas['currency'], + credit_total : datas['credit_total'], + debit_total : datas['debit_total'], + debit_balance : datas['debit_balance'] + })); + }); + + } + catch (el) { + window.location.href + } + }, + + + + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + print_pdf: function(e) { + e.preventDefault(); + var self = this; + self._rpc({ + model: 'account.partner.ledger', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.partner_ledger', + 'report_file': 'dynamic_accounts_report.partner_ledger', + 'data': { + 'report_data': data + }, + 'context': { + 'active_model': 'account.partner.ledger', + 'landscape': 1, + 'partner_ledger_pdf_report': true + }, + 'display_name': 'Partner Ledger', + }; + return self.do_action(action); + }); + }, + + + + print_xlsx: function() { + var self = this; + self._rpc({ + model: 'account.partner.ledger', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'account.partner.ledger', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': JSON.stringify(data['report_lines']), + 'report_name': 'Partner Ledger', + 'dfr_data': JSON.stringify(data), + }, + }; +// return self.do_action(action); + core.action_registry.map.t_b.prototype.downloadXlsx(action) + }); + }, + + journal_line_click: function (el){ + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + }, + + show_drop_down: function(event) { + event.preventDefault(); + var self = this; + var account_id = $(event.currentTarget).data('account-id'); + var offset = 0; + var td = $(event.currentTarget).next('tr').find('td'); + if (td.length == 1) { + self._rpc({ + model: 'account.partner.ledger', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + _.each(data['report_lines'], function(rep_lines) { + _.each(rep_lines['move_lines'], function(move_line) { + + move_line.debit = self.format_currency(data['currency'],move_line.debit); + move_line.credit = self.format_currency(data['currency'],move_line.credit); + move_line.balance = self.format_currency(data['currency'],move_line.balance); + + + }); + }); + for (var i = 0; i < data['report_lines'].length; i++) { + + if (account_id == data['report_lines'][i]['id'] ){ + $(event.currentTarget).next('tr').find('td .pl-table-div').remove(); + $(event.currentTarget).next('tr').find('td ul').after( + QWeb.render('SubSectionPL', { + account_data: data['report_lines'][i]['move_lines'], + })) + $(event.currentTarget).next('tr').find('td ul li:first a').css({ + 'background-color': '#00ede8', + 'font-weight': 'bold', + }); + } + } + }); + } + }, + + view_acc_move: function(event) { + event.preventDefault(); + var self = this; + var context = {}; + var show_acc_move = function(res_model, res_id, view_id) { + var action = { + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: res_model, + views: [ + [view_id || false, 'form'] + ], + res_id: res_id, + target: 'current', + context: context, + }; + return self.do_action(action); + }; + rpc.query({ + model: 'account.move', + method: 'search_read', + domain: [ + ['id', '=', $(event.currentTarget).data('move-id')] + ], + fields: ['id'], + limit: 1, + }) + .then(function(record) { + if (record.length > 0) { + show_acc_move('account.move', record[0].id); + } else { + show_acc_move('account.move', $(event.currentTarget).data('move-id')); + } + }); + }, + + apply_filter: function(event) { + event.preventDefault(); + var self = this; + self.initial_render = false; + var filter_data_selected = {}; + + var account_ids = []; + var account_text = []; + var span_res = document.getElementById("account_res") + var account_list = $(".account").select2('data') + for (var i = 0; i < account_list.length; i++) { + if(account_list[i].element[0].selected === true) + {account_ids.push(parseInt(account_list[i].id)) + if(account_text.includes(account_list[i].text) === false) + {account_text.push(account_list[i].text) + } + span_res.value = account_text + span_res.innerHTML=span_res.value; + } + } + if (account_list.length == 0){ + span_res.value = "" + span_res.innerHTML=""; } + filter_data_selected.account_ids = account_ids + + + var journal_ids = []; + var journal_text = []; + var journal_res = document.getElementById("journal_res") + var journal_list = $(".journals").select2('data') + for (var i = 0; i < journal_list.length; i++) { + if(journal_list[i].element[0].selected === true){ + journal_ids.push(parseInt(journal_list[i].id)) + if(journal_text.includes(journal_list[i].text) === false){ + journal_text.push(journal_list[i].text) + } + journal_res.value = journal_text + journal_res.innerHTML=journal_res.value; + } + } + if (journal_list.length == 0){ + journal_res.value = "" + journal_res.innerHTML=""; + } + filter_data_selected.journal_ids = journal_ids + + var partner_ids = []; + var partner_text = []; + var span_res = document.getElementById("partner_res") + var partner_list = $(".partners").select2('data') + for (var i = 0; i < partner_list.length; i++) { + if(partner_list[i].element[0].selected === true) + {partner_ids.push(parseInt(partner_list[i].id)) + if(partner_text.includes(partner_list[i].text) === false) + {partner_text.push(partner_list[i].text) + } + span_res.value = partner_text + span_res.innerHTML=span_res.value; + } + } + if (partner_list.length == 0){ + span_res.value = "" + span_res.innerHTML=""; + } + filter_data_selected.partner_ids = partner_ids + + var account_type_ids = []; + var account_type_ids_text = []; + var span_res = document.getElementById("type_res") + var type_list = $(".type").select2('data') + for (var i = 0; i < type_list.length; i++) { + if(type_list[i].element[0].selected === true) + {account_type_ids.push(parseInt(type_list[i].id)) + if(account_type_ids_text.includes(type_list[i].text) === false) + {account_type_ids_text.push(type_list[i].text) + } + span_res.value = account_type_ids_text + span_res.innerHTML=span_res.value; + } + } + if (type_list.length == 0){ + span_res.value = "" + span_res.innerHTML=""; + } + filter_data_selected.account_type_ids = account_type_ids + + var partner_category_ids = []; + var partner_category_text = []; + var span_res = document.getElementById("category_res") + var category_list = $(".category").select2('data') + for (var i = 0; i < category_list.length; i++) { + if(category_list[i].element[0].selected === true) + {partner_category_ids.push(parseInt(category_list[i].id)) + if(partner_category_text.includes(category_list[i].text) === false) + {partner_category_text.push(category_list[i].text) + } + span_res.value = partner_category_text + span_res.innerHTML=span_res.value; + } + } + if (category_list.length == 0){ + span_res.value = "" + span_res.innerHTML=""; + } + filter_data_selected.partner_category_ids = partner_category_ids + + if ($("#date_from").val()) { + var dateString = $("#date_from").val(); + filter_data_selected.date_from = dateString; + } + if ($("#date_to").val()) { + var dateString = $("#date_to").val(); + filter_data_selected.date_to = dateString; + } + + if ($(".reconciled").length){ + var reconciled_res = document.getElementById("reconciled_res") + filter_data_selected.reconciled = $(".reconciled")[0].value + reconciled_res.value = $(".reconciled")[0].value + reconciled_res.innerHTML=reconciled_res.value; + if ($(".reconciled").value==""){ + reconciled_res.innerHTML="unreconciled"; + filter_data_selected.reconciled = "unreconciled" + } + } + + if ($(".target_move").length) { + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + rpc.query({ + model: 'account.partner.ledger', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("p_l", PartnerLedger); + return PartnerLedger; +}); diff --git a/dynamic_accounts_report/static/src/js/trial_balance.js b/dynamic_accounts_report/static/src/js/trial_balance.js new file mode 100644 index 000000000..b31c3ff22 --- /dev/null +++ b/dynamic_accounts_report/static/src/js/trial_balance.js @@ -0,0 +1,283 @@ +odoo.define('dynamic_accounts_report.trial_balance', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var core = require('web.core'); + var field_utils = require('web.field_utils'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var utils = require('web.utils'); + var QWeb = core.qweb; + var _t = core._t; + var framework = require('web.framework'); + +// import framework from 'web.framework'; +// import { download } from "@web/core/network/download"; + + +// import { registry } from "@web/core/registry"; +// const serviceRegistry = registry.category("services"); + + window.click_num = 0; + var TrialBalance = AbstractAction.extend({ + template: 'TrialTemp', + events: { + 'click .parent-line': 'journal_line_click', + 'click .child_col1': 'journal_line_click', + 'click #apply_filter': 'apply_filter', + 'click #pdf': 'print_pdf', + 'click #xlsx': 'print_xlsx', + 'click .show-gl': 'show_gl', + }, + + init: function(parent, action) { + this._super(parent, action); + this.currency=action.currency; + this.report_lines = action.report_lines; + this.wizard_id = action.context.wizard | null; + }, + + + start: function() { + var self = this; + self.initial_render = true; + rpc.query({ + model: 'account.trial.balance', + method: 'create', + args: [{ + + }] + }).then(function(t_res) { + self.wizard_id = t_res; + self.load_data(self.initial_render); + }) + }, + + + load_data: function (initial_render = true) { + var self = this; + self.$(".categ").empty(); + try{ + var self = this; + self._rpc({ + model: 'account.trial.balance', + method: 'view_report', + args: [[this.wizard_id]], + }).then(function(datas) { + _.each(datas['report_lines'], function(rep_lines) { + rep_lines.debit = self.format_currency(datas['currency'],rep_lines.debit); + rep_lines.credit = self.format_currency(datas['currency'],rep_lines.credit); + rep_lines.balance = self.format_currency(datas['currency'],rep_lines.balance); + + + + }); + if (initial_render) { + self.$('.filter_view_tb').html(QWeb.render('TrialFilterView', { + filter_data: datas['filters'], + })); + self.$el.find('.journals').select2({ + placeholder: 'Select Journals...', + }); + self.$el.find('.target_move').select2({ + placeholder: 'Target Move...', + }); + } + var child=[]; + + self.$('.table_view_tb').html(QWeb.render('TrialTable', { + + report_lines : datas['report_lines'], + filter : datas['filters'], + currency : datas['currency'], + credit_total : self.format_currency(datas['currency'],datas['debit_total']), + debit_total : self.format_currency(datas['currency'],datas['debit_total']), + })); + }); + + } + catch (el) { + window.location.href + } + }, + + show_gl: function(e) { + var self = this; + var account_id = $(e.target).attr('data-account-id'); + var options = { + account_ids: [account_id], + } + + var action = { + type: 'ir.actions.client', + name: 'GL View', + tag: 'g_l', + target: 'new', + + domain: [['account_ids','=', account_id]], + + + } + return this.do_action(action); + + }, + + print_pdf: function(e) { + e.preventDefault(); + var self = this; + self._rpc({ + model: 'account.trial.balance', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { + 'type': 'ir.actions.report', + 'report_type': 'qweb-pdf', + 'report_name': 'dynamic_accounts_report.trial_balance', + 'report_file': 'dynamic_accounts_report.trial_balance', + 'data': { + 'report_data': data + }, + 'context': { + 'active_model': 'account.trial.balance', + 'landscape': 1, + 'trial_pdf_report': true + }, + 'display_name': 'Trial Balance', + }; + return self.do_action(action); + }); + }, + + + format_currency: function(currency, amount) { + if (typeof(amount) != 'number') { + amount = parseFloat(amount); + } + var formatted_value = (parseInt(amount)).toLocaleString(currency[2],{ + minimumFractionDigits: 2 + }) + return formatted_value + }, + + print_xlsx: function() { + var self = this; + self._rpc({ + model: 'account.trial.balance', + method: 'view_report', + args: [ + [self.wizard_id] + ], + }).then(function(data) { + var action = { +// 'type': 'ir_actions_dynamic_xlsx_download', + 'data': { + 'model': 'account.trial.balance', + 'options': JSON.stringify(data['filters']), + 'output_format': 'xlsx', + 'report_data': JSON.stringify(data['report_lines']), + 'report_name': 'Trial Balance', + 'dfr_data': JSON.stringify(data), + }, + }; + +// return self.do_action(action); + self.downloadXlsx(action); + }); + }, + + downloadXlsx: function (action){ + framework.blockUI(); + session.get_file({ + url: '/dynamic_xlsx_reports', + data: action.data, + complete: framework.unblockUI, + error: (error) => this.call('crash_manager', 'rpc_error', error), + }); + }, + + journal_line_click: function (el){ + click_num++; + var self = this; + var line = $(el.target).parent().data('id'); + return self.do_action({ + type: 'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: 'account.move', + views: [ + [false, 'form'] + ], + res_id: line, + target: 'current', + }); + + }, + + + apply_filter: function(event) { + + event.preventDefault(); + var self = this; + self.initial_render = false; + + var filter_data_selected = {}; + var journal_ids = []; + var journal_text = []; + var journal_res = document.getElementById("journal_res") + var journal_list = $(".journals").select2('data') + + for (var i = 0; i < journal_list.length; i++) { + if(journal_list[i].element[0].selected === true){ + + journal_ids.push(parseInt(journal_list[i].id)) + if(journal_text.includes(journal_list[i].text) === false){ + journal_text.push(journal_list[i].text) + } + journal_res.value = journal_text + journal_res.innerHTML=journal_res.value; + } + } + if (journal_list.length == 0){ + journal_res.value = "" + journal_res.innerHTML=""; + + } + filter_data_selected.journal_ids = journal_ids + + if ($("#date_from").val()) { + var dateString = $("#date_from").val(); + filter_data_selected.date_from = dateString; + } + if ($("#date_to").val()) { + var dateString = $("#date_to").val(); + filter_data_selected.date_to = dateString; + } + + if ($(".target_move").length) { + var post_res = document.getElementById("post_res") + filter_data_selected.target_move = $(".target_move")[1].value + post_res.value = $(".target_move")[1].value + post_res.innerHTML=post_res.value; + if ($(".target_move")[1].value == "") { + post_res.innerHTML="posted"; + + } + } + rpc.query({ + model: 'account.trial.balance', + method: 'write', + args: [ + self.wizard_id, filter_data_selected + ], + }).then(function(res) { + self.initial_render = false; + self.load_data(self.initial_render); + }); + }, + + }); + core.action_registry.add("t_b", TrialBalance); + return TrialBalance; +}); \ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/ageing.xml b/dynamic_accounts_report/static/src/xml/ageing.xml new file mode 100644 index 000000000..aa63e8800 --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/ageing.xml @@ -0,0 +1,580 @@ + + +
+
+

+ Partner Ageing +

+ +
+ +
+
+
+

+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PartnerNot Due0-3030-6060-9090-120120+Total
+ + + + + + + + + + - + + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + +
+
    + +
+
+
+
+
+ + + +
+
+
+ + +
+
+

+
+
+ +

+
+
+ + +
+
+ + + Account Type: + + + +
+
+ + + Partners: + + + +
+
+ + + Partner tag: + + + + +
+ + +
+ + + Target Move: + + + +
+
+ +
+
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Entry LabelDueDateJRNLAccountNot Due0-3030-6060-9090-120120+
+ + + + + + + + + + + - + + + + + + - + + + + + + + + + + - + + + + + - + + + + + + + + + + - + + + + + - + + + + + + + + + + + - + + + + + - + + + + + + + + + + + - + + + + + - + + + + + + + + + + - + + + + + - + + + + + + + + + - + + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + +
+
+
+ +
\ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/cash_flow_view.xml b/dynamic_accounts_report/static/src/xml/cash_flow_view.xml new file mode 100644 index 000000000..00b447d15 --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/cash_flow_view.xml @@ -0,0 +1,351 @@ + + + +
+
+

+ Cash Flow Statement +

+ +
+ +
+
+
+

+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCash InCash OutBalance
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+
    + +
+
+
+
+
+ + + + + + +
+
+
+ + +
+
+

+
+
+ +

+
+
+ + +
+ + +
+ + +Target Move: + + + +
+ +
+ + +Level: + + + +
+ + +
+ +
+
+ + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCash InCash OutBalance
+ + + + + + + + + + + + + +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
\ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/daybook.xml b/dynamic_accounts_report/static/src/xml/daybook.xml new file mode 100644 index 000000000..0501d3e8a --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/daybook.xml @@ -0,0 +1,341 @@ + + +
+
+

+ Day Book +

+ +
+ +
+
+
+

+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateDebitCreditBalance
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
    +
+
+
+
+
+ + + +
+
+
+ + +
+
+

+
+ +
+ +

+
+
+ + +
+
+ + + Journals: + + + +
+
+ + + Accounts: + + + +
+ + +
+ + + Target Move: + + + +
+
+ +
+
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateJRNLPartnerMoveEntry LabelDebitCreditBalance
+ + + + + + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + +
+
+
+ +
\ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/financial_reports_view.xml b/dynamic_accounts_report/static/src/xml/financial_reports_view.xml new file mode 100644 index 000000000..6c329f135 --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/financial_reports_view.xml @@ -0,0 +1,266 @@ + + + +
+
+
+
+

+
+
+
+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DebitCreditBalance
+ + + - + + +
+ + +
+
+ +
+ +
+
+
+ +
+

+ +

+ +
+
+ +
+
+ + +
+
+

+
+
+ +

+
+
+ + +
+
+ + +Journals: + + + +
+ +
+ + + Accounts: + + + +
+ + + +
+ + + Analytic Accounts: + + + +
+ +
+ + + Analytic Tags: + + + +
+ + +
+ + +Target Move: + + + +
+
+ +
+
+ + +
+
+
+
+ +
\ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/general_ledger_view.xml b/dynamic_accounts_report/static/src/xml/general_ledger_view.xml new file mode 100644 index 000000000..77e130fe2 --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/general_ledger_view.xml @@ -0,0 +1,386 @@ + + +
+
+
+
+

+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AccountDebitCreditBalance
+ + + + - + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + +
+
    +
+
+
+
+
+ + + +
+

+ +

+ +
+
+
+
+ + +
+
+

+
+
+ +

+
+
+ + +
+ +
+ + + Journals: + + + +
+
+ +
+ + + Accounts: + + + +
+ +
+ + + Analytic Accounts: + + + +
+ +
+ + + Analytic Tags: + + + +
+ + +
+ + + Target Move: + + + +
+
+ +
+
+ + +
+
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateJRNLPartnerMoveEntry LabelDebitCreditBalance
+ + + + + + + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + + + + - + + + + + +
+
+
+ + +
\ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/partner_ledger_view.xml b/dynamic_accounts_report/static/src/xml/partner_ledger_view.xml new file mode 100644 index 000000000..6f75333ae --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/partner_ledger_view.xml @@ -0,0 +1,340 @@ + + +
+
+

+ Partner Ledger +

+
+ +
+
+
+

+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PartnerDebitCreditBalance
+ + + + + + + + + + + + + + + + + + + + + + +
+
    +
+
+
+
+
+ + +
+
+
+ + +
+
+

+
+
+ +

+
+
+ + +
+
+ + + Partners: + + + + +
+ +
+ + + Account Type + + + + +
+
+ + + Partner tag: + + + + +
+ +
+ + + Journals: + + + +
+
+ + + Accounts: + + + + + +
+ + +
+ + + Target Move: + + + +
+
+ +
+
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateJRNLAccountMoveEntry LabelDebitCreditBalance
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
\ No newline at end of file diff --git a/dynamic_accounts_report/static/src/xml/trial_balance_view.xml b/dynamic_accounts_report/static/src/xml/trial_balance_view.xml new file mode 100644 index 000000000..42b71f960 --- /dev/null +++ b/dynamic_accounts_report/static/src/xml/trial_balance_view.xml @@ -0,0 +1,283 @@ + + +
+
+

+ Trial Balance +

+ +
+ +
+
+
+

+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AccountInitial DebitInitial CreditDebitCredit
+ + + - + + + + + + + + + + + + + + + + + 0 + + 0 + + 0 + + + 0 + + + + + + + + + + + + + +
+ Total + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + +
+
+
+ + +
+
+

+
+
+ +

+
+
+ + +
+
+ + + Journals: + + + +
+ +
+ + + Target Move: + + + +
+
+ +
+
+ + +
+
+
+
+ +
\ No newline at end of file diff --git a/dynamic_accounts_report/views/kit_menus.xml b/dynamic_accounts_report/views/kit_menus.xml new file mode 100644 index 000000000..14c4fa630 --- /dev/null +++ b/dynamic_accounts_report/views/kit_menus.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynamic_accounts_report/views/templates.xml b/dynamic_accounts_report/views/templates.xml new file mode 100644 index 000000000..7efb839c6 --- /dev/null +++ b/dynamic_accounts_report/views/templates.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dynamic_accounts_report/views/views.xml b/dynamic_accounts_report/views/views.xml new file mode 100644 index 000000000..0046e0b45 --- /dev/null +++ b/dynamic_accounts_report/views/views.xml @@ -0,0 +1,80 @@ + + + + + + General Ledger + g_l + + + + + Trial Balance + t_b + + + + + + Partner Ledger + p_l + + + + + Partner Ageing + p_a + + + + + Day Book + d_b + + + + + Bank Book + g_l + + + + + Cash Book + g_l + + + + + Balance Sheet + dfr_n + + + + Profit and Loss + dfr_n + + + + + + + + Cash Flow Statements + c_f + + + + + \ No newline at end of file diff --git a/dynamic_accounts_report/wizard/__init__.py b/dynamic_accounts_report/wizard/__init__.py new file mode 100644 index 000000000..2f21060fe --- /dev/null +++ b/dynamic_accounts_report/wizard/__init__.py @@ -0,0 +1,8 @@ +from . import general_ledger +from . import trial_balance +from . import cash_flow +from . import balance_sheet +from . import balance_sheet_config +from . import partner_leadger +from . import ageing +from . import daybook diff --git a/dynamic_accounts_report/wizard/ageing.py b/dynamic_accounts_report/wizard/ageing.py new file mode 100644 index 000000000..5010ea7d3 --- /dev/null +++ b/dynamic_accounts_report/wizard/ageing.py @@ -0,0 +1,705 @@ +import time +from datetime import datetime + +from dateutil.relativedelta import relativedelta +from odoo import fields, models, api, _ +from odoo.tools import float_is_zero +from odoo.http import request +import io +import json + +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class AgeingView(models.TransientModel): + _inherit = "account.common.report" + _name = 'account.partner.ageing' + + period_length = fields.Integer(string='Period Length (days)', + required=True, default=30) + date_from = fields.Date(default=lambda *a: time.strftime('%Y-%m-%d')) + result_selection = fields.Selection([('customer', 'Receivable Accounts'), + ('supplier', 'Payable Accounts'), + ('customer_supplier', + 'Receivable and Payable Accounts') + ], string="Partner's", required=True, + default='customer') + + partner_ids = fields.Many2many( + 'res.partner', string='Partner' + ) + partner_category_ids = fields.Many2many( + 'res.partner.category', string='Partner Tag', + ) + + @api.model + def view_report(self, option): + r = self.env['account.partner.ageing'].search([('id', '=', option[0])]) + + data = { + 'result_selection': r.result_selection, + 'model': self, + 'journals': r.journal_ids, + 'target_move': r.target_move, + 'period_length': r.period_length, + 'partners': r.partner_ids, + 'partner_tags': r.partner_category_ids, + + } + if r.date_from: + data.update({ + 'date_from': r.date_from, + }) + + filters = self.get_filter(option) + + records = self._get_report_values(data) + + currency = self._get_currency() + + return { + 'name': "Partner Ageing", + 'type': 'ir.actions.client', + 'tag': 'p_a', + 'filters': filters, + 'report_lines': records['Partners'], + 'currency': currency, + } + + def get_filter(self, option): + data = self.get_filter_data(option) + filters = {} + + if data.get('target_move'): + filters['target_move'] = data.get('target_move') + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + if data.get('result_selection') == 'customer': + filters['result_selection'] = 'Receivable' + elif data.get('result_selection') == 'supplier': + filters['result_selection'] = 'Payable' + else: + filters['result_selection'] = 'Receivable and Payable' + + if data.get('partners'): + filters['partners'] = self.env['res.partner'].browse( + data.get('partners')).mapped('name') + else: + filters['partners'] = ['All'] + + if data.get('partner_tags', []): + filters['partner_tags'] = self.env['res.partner.category'].browse( + data.get('partner_tags', [])).mapped('name') + else: + filters['partner_tags'] = ['All'] + + filters['company_id'] = '' + filters['company_name'] = data.get('company_name') + filters['partners_list'] = data.get('partners_list') + filters['category_list'] = data.get('category_list') + filters['company_name'] = data.get('company_name') + filters['target_move'] = data.get('target_move').capitalize() + + + return filters + + def get_filter_data(self, option): + r = self.env['account.partner.ageing'].search([('id', '=', option[0])]) + default_filters = {} + company = self.get_current_company_value() + company_id = self.env['res.company'].search([('id', 'in', company)]) + # company_id = self.env.company + company_domain = [('company_id', 'in', company_id.ids)] + partner = r.partner_ids if r.partner_ids else self.env[ + 'res.partner'].search([]) + categories = r.partner_category_ids if r.partner_category_ids \ + else self.env['res.partner.category'].search([]) + + filter_dict = { + 'partners': r.partner_ids.ids, + 'partner_tags': r.partner_category_ids.ids, + 'company_id': company_id[0].id, + 'date_from': r.date_from, + + 'target_move': r.target_move, + 'result_selection': r.result_selection, + 'partners_list': [(p.id, p.name) for p in partner], + 'category_list': [(c.id, c.name) for c in categories], + 'company_name': company_id and company_id[0].name, + } + filter_dict.update(default_filters) + return filter_dict + + def _get_report_values(self, data): + docs = data['model'] + date_from = data.get('date_from').strftime('%Y-%m-%d') + if data['result_selection'] == 'customer': + account_type = ['receivable'] + elif data['result_selection'] == 'supplier': + account_type = ['payable'] + else: + account_type = ['payable', 'receivable'] + target_move = data['target_move'] + partners = data.get('partners') + if data['partner_tags']: + partners = self.env['res.partner'].search( + [('category_id', 'in', data['partner_tags'].ids)]) + + account_res = self._get_partner_move_lines(data, partners, date_from, + target_move, + account_type, + data['period_length']) + + return { + 'doc_ids': self.ids, + 'docs': docs, + 'time': time, + 'Partners': account_res, + + } + + def get_current_company_value(self): + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(AgeingView, self).create(vals) + return res + + def write(self, vals): + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + + if vals.get('partner_ids'): + vals.update( + {'partner_ids': [(4, j) for j in vals.get('partner_ids')]}) + if not vals.get('partner_ids'): + vals.update({'partner_ids': [(5,)]}) + if vals.get('partner_category_ids'): + vals.update({'partner_category_ids': [(4, j) for j in vals.get( + 'partner_category_ids')]}) + if not vals.get('partner_category_ids'): + vals.update({'partner_category_ids': [(5,)]}) + + res = super(AgeingView, self).write(vals) + return res + + def _get_partner_move_lines(self, data, partners, date_from, target_move, + account_type, + period_length): + + periods = {} + start = datetime.strptime(date_from, "%Y-%m-%d") + date_from = datetime.strptime(date_from, "%Y-%m-%d").date() + for i in range(5)[::-1]: + stop = start - relativedelta(days=period_length) + period_name = str((5 - (i + 1)) * period_length + 1) + '-' + str( + (5 - i) * period_length) + period_stop = (start - relativedelta(days=1)).strftime('%Y-%m-%d') + if i == 0: + period_name = '+' + str(4 * period_length) + periods[str(i)] = { + 'name': period_name, + 'stop': period_stop, + 'start': (i != 0 and stop.strftime('%Y-%m-%d') or False), + } + start = stop + res = [] + total = [] + cr = self.env.cr + company = self.get_current_company_value()[0] + user_company = self.env['res.company'].search([('id', '=', int(company))]) + # user_company = self.env.company + + user_currency = user_company.currency_id + ResCurrency = self.env['res.currency'].with_context(date=date_from) + # company_ids = self._context.get('company_ids') or [user_company.id] + company_ids = self._context.get('company_ids') or [user_company.id] + move_state = ['draft', 'posted'] + if target_move == 'posted': + move_state = ['posted'] + arg_list = (tuple(move_state), tuple(account_type)) + + reconciliation_clause = '(l.reconciled IS FALSE)' + cr.execute( + 'SELECT debit_move_id, credit_move_id FROM account_partial_reconcile where max_date > %s', + (date_from,)) + reconciled_after_date = [] + for row in cr.fetchall(): + reconciled_after_date += [row[0], row[1]] + if reconciled_after_date: + reconciliation_clause = '(l.reconciled IS FALSE OR l.id IN %s)' + arg_list += (tuple(reconciled_after_date),) + + arg_list += (date_from, tuple(company_ids),) + partner_list = '(l.partner_id IS NOT NULL)' + if partners: + list = tuple(partners.ids) + tuple([0]) + if list: + partner_list = '(l.partner_id IS NULL OR l.partner_id IN %s)' + arg_list += (tuple(list),) + query = ''' + SELECT DISTINCT l.partner_id, UPPER(res_partner.name) + FROM account_move_line AS l left join res_partner on l.partner_id = res_partner.id, account_account, account_move am + WHERE (l.account_id = account_account.id) + AND (l.move_id = am.id) + AND (am.state IN %s) + AND (account_account.internal_type IN %s) + + AND ''' + reconciliation_clause + ''' + AND (l.date <= %s) + AND l.company_id IN %s + AND ''' + partner_list + ''' + + ORDER BY UPPER(res_partner.name)''' + cr.execute(query, arg_list) + + + partners = cr.dictfetchall() + + # put a total of 0 + for i in range(7): + total.append(0) + + # Build a string like (1,2,3) for easy use in SQL query + partner_ids = [partner['partner_id'] for partner in partners if + partner['partner_id']] + + lines = dict( + (partner['partner_id'] or False, []) for partner in partners) + if not partner_ids: + return [], [], {} + + # This dictionary will store the not due amount of all partners + undue_amounts = {} + query = '''SELECT l.id + FROM account_move_line AS l, account_account, account_move am + WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) + AND (am.state IN %s) + AND (account_account.internal_type IN %s) + AND (COALESCE(l.date_maturity,l.date) >= %s)\ + AND ((l.partner_id IN %s) OR (l.partner_id IS NULL)) + AND (l.date <= %s) + AND l.company_id IN %s''' + cr.execute(query, ( + tuple(move_state), tuple(account_type), date_from, + tuple(partner_ids), date_from, tuple(company_ids))) + aml_ids = cr.fetchall() + aml_ids = aml_ids and [x[0] for x in aml_ids] or [] + for line in self.env['account.move.line'].browse(aml_ids): + partner_id = line.partner_id.id or False + move_id = line.move_id.id + move_name = line.move_id.name + date_maturity = line.date_maturity + account_id = line.account_id.name + account_code = line.account_id.code + jrnl_id = line.journal_id.name + currency_id = line.company_id.currency_id.position + currency_symbol = line.company_id.currency_id.symbol + + if partner_id not in undue_amounts: + undue_amounts[partner_id] = 0.0 + line_amount = ResCurrency._compute(line.company_id.currency_id, + user_currency, line.balance) + if user_currency.is_zero(line_amount): + continue + for partial_line in line.matched_debit_ids: + if partial_line.max_date <= date_from: + line_amount += ResCurrency._compute( + partial_line.company_id.currency_id, user_currency, + partial_line.amount) + for partial_line in line.matched_credit_ids: + if partial_line.max_date <= date_from: + line_amount -= ResCurrency._compute( + partial_line.company_id.currency_id, user_currency, + partial_line.amount) + if not self.env.company.currency_id.is_zero(line_amount): + undue_amounts[partner_id] += line_amount + lines[partner_id].append({ + 'line': line, + 'partner_id': partner_id, + 'move': move_name, + 'jrnl': jrnl_id, + 'currency': currency_id, + 'symbol': currency_symbol, + 'acc_name': account_id, + 'mov_id': move_id, + 'acc_code': account_code, + 'date': date_maturity, + 'amount': line_amount, + 'period6': 6, + }) + + # Use one query per period and store results in history (a list variable) + # Each history will contain: history[1] = {'': } + history = [] + for i in range(5): + args_list = ( + tuple(move_state), tuple(account_type), tuple(partner_ids),) + dates_query = '(COALESCE(l.date_maturity,l.date)' + + if periods[str(i)]['start'] and periods[str(i)]['stop']: + dates_query += ' BETWEEN %s AND %s)' + + args_list += ( + periods[str(i)]['start'], periods[str(i)]['stop']) + elif periods[str(i)]['start']: + dates_query += ' >= %s)' + + args_list += (periods[str(i)]['start'],) + else: + dates_query += ' <= %s)' + args_list += (periods[str(i)]['stop'],) + + args_list += (date_from, tuple(company_ids)) + + query = '''SELECT l.id + FROM account_move_line AS l, account_account, account_move am + WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) + AND (am.state IN %s) + AND (account_account.internal_type IN %s) + AND ((l.partner_id IN %s) OR (l.partner_id IS NULL)) + AND ''' + dates_query + ''' + + + AND (l.date <= %s) + AND l.company_id IN %s''' + cr.execute(query, args_list) + + partners_amount = {} + aml_ids = cr.fetchall() + aml_ids = aml_ids and [x[0] for x in aml_ids] or [] + for line in self.env['account.move.line'].browse(aml_ids): + partner_id = line.partner_id.id or False + move_id = line.move_id.id + move_name = line.move_id.name + date_maturity = line.date_maturity + account_id = line.account_id.name + account_code = line.account_id.code + jrnl_id = line.journal_id.name + currency_id = line.company_id.currency_id.position + currency_symbol = line.company_id.currency_id.symbol + if partner_id not in partners_amount: + partners_amount[partner_id] = 0.0 + line_amount = ResCurrency._compute(line.company_id.currency_id, + user_currency, line.balance) + if user_currency.is_zero(line_amount): + continue + for partial_line in line.matched_debit_ids: + if partial_line.max_date <= date_from: + line_amount += ResCurrency._compute( + partial_line.company_id.currency_id, user_currency, + partial_line.amount) + for partial_line in line.matched_credit_ids: + if partial_line.max_date <= date_from: + line_amount -= ResCurrency._compute( + partial_line.company_id.currency_id, user_currency, + partial_line.amount) + + if not self.env.company.currency_id.is_zero( + line_amount): + partners_amount[partner_id] += line_amount + if i + 1 == 5: + period5 = i + 1 + lines[partner_id].append({ + 'period5': period5, + 'line': line, + 'partner_id': partner_id, + 'move': move_name, + 'currency': currency_id, + 'symbol': currency_symbol, + 'jrnl': jrnl_id, + 'acc_name': account_id, + 'mov_id': move_id, + 'acc_code': account_code, + 'date': date_maturity, + 'amount': line_amount, + }) + elif i + 1 == 4: + period4 = i + 1 + lines[partner_id].append({ + + 'period4': period4, + 'line': line, + 'partner_id': partner_id, + 'move': move_name, + 'jrnl': jrnl_id, + 'acc_name': account_id, + 'currency': currency_id, + 'symbol': currency_symbol, + 'mov_id': move_id, + 'acc_code': account_code, + 'date': date_maturity, + 'amount': line_amount, + }) + elif i + 1 == 3: + period3 = i + 1 + lines[partner_id].append({ + + 'period3': period3, + 'line': line, + 'partner_id': partner_id, + 'move': move_name, + 'jrnl': jrnl_id, + 'acc_name': account_id, + 'currency': currency_id, + 'symbol': currency_symbol, + 'mov_id': move_id, + 'acc_code': account_code, + 'date': date_maturity, + 'amount': line_amount, + }) + elif i + 1 == 2: + period2 = i + 1 + lines[partner_id].append({ + + 'period2': period2, + 'line': line, + 'partner_id': partner_id, + 'move': move_name, + 'jrnl': jrnl_id, + 'acc_name': account_id, + 'currency': currency_id, + 'symbol': currency_symbol, + 'mov_id': move_id, + 'acc_code': account_code, + 'date': date_maturity, + 'amount': line_amount, + }) + else: + period1 = i + 1 + lines[partner_id].append({ + + 'period1': period1, + 'line': line, + 'partner_id': partner_id, + 'move': move_name, + 'jrnl': jrnl_id, + 'acc_name': account_id, + 'currency': currency_id, + 'symbol': currency_symbol, + 'mov_id': move_id, + 'acc_code': account_code, + 'date': date_maturity, + 'amount': line_amount, + }) + + history.append(partners_amount) + + for partner in partners: + if partner['partner_id'] is None: + partner['partner_id'] = False + at_least_one_amount = False + values = {} + undue_amt = 0.0 + if partner[ + 'partner_id'] in undue_amounts: # Making sure this partner actually was found by the query + undue_amt = undue_amounts[partner['partner_id']] + + total[6] = total[6] + undue_amt + values['direction'] = undue_amt + for rec in lines: + if partner['partner_id'] == rec: + child_lines = lines[rec] + values['child_lines'] = child_lines + if not float_is_zero(values['direction'], + precision_rounding=self.env.company.currency_id.rounding): + at_least_one_amount = True + + for i in range(5): + during = False + if partner['partner_id'] in history[i]: + during = [history[i][partner['partner_id']]] + # Adding counter + total[(i)] = total[(i)] + (during and during[0] or 0) + values[str(i)] = during and during[0] or 0.0 + if not float_is_zero(values[str(i)], + precision_rounding=self.env.company.currency_id.rounding): + at_least_one_amount = True + values['total'] = sum( + [values['direction']] + [values[str(i)] for i in range(5)]) + ## Add for total + total[(i + 1)] += values['total'] + values['partner_id'] = partner['partner_id'] + if partner['partner_id']: + browsed_partner = self.env['res.partner'].browse( + partner['partner_id']) + values['name'] = browsed_partner.name and len( + browsed_partner.name) >= 45 and browsed_partner.name[ + 0:40] + '...' or browsed_partner.name + values['trust'] = browsed_partner.trust + else: + values['name'] = _('Unknown Partner') + values['trust'] = False + + if at_least_one_amount or ( + self._context.get('include_nullified_amount') and lines[ + partner['partner_id']]): + res.append(values) + + return res, total, lines + + @api.model + def _get_currency(self): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position, lang] + currency_array = [company_id.currency_id.symbol, + company_id.currency_id.position, lang] + + return currency_array + + def get_dynamic_xlsx_report(self, data, response, report_data, dfr_data ): + + report_data_main = json.loads(report_data) + output = io.BytesIO() + + filters = json.loads(data) + + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + sheet = workbook.add_worksheet() + head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '20px'}) + sub_heading = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + heading = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 2, + 'border_color': 'black'}) + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + txt_l = workbook.add_format( + {'font_size': '10px', 'border': 1, 'bold': True}) + txt_v = workbook.add_format( + {'align': 'right', 'font_size': '10px', 'border': 1}) + sheet.merge_range('A2:H3', + filters.get('company_name') + ':' + ' Partner Ageing', + head) + date_head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '10px'}) + date_style = workbook.add_format({'align': 'center', + 'font_size': '10px'}) + if filters.get('date_from'): + sheet.merge_range('A4:B4', + 'As On Date: ' + filters.get('date_from'), + date_head) + sheet.merge_range('C4:E4', + 'Account Type: ' + filters.get('result_selection'), + date_head) + sheet.merge_range('A5:B5', + 'Target Moves: ' + filters.get('target_move'), + date_head) + sheet.merge_range('D5:F5', ' Partners: ' + ', '.join( + [lt or '' for lt in + filters['partners']]), date_head) + sheet.merge_range('G5:H5', ' Partner Type: ' + ', '.join( + [lt or '' for lt in + filters['partner_tags']]), + date_head) + + sheet.merge_range('A7:C7', 'Partner', heading) + sheet.write('D7', 'Total', heading) + sheet.write('E7', 'Not Due', heading) + sheet.write('F7', '0-30', heading) + sheet.write('G7', '30-60', heading) + sheet.write('H7', '60-90', heading) + sheet.write('I7', '90-120', heading) + sheet.write('J7', '120+', heading) + + lst = [] + for rec in report_data_main[0]: + lst.append(rec) + row = 6 + col = 0 + sheet.set_column(5, 0, 15) + sheet.set_column(6, 1, 15) + sheet.set_column(7, 2, 15) + sheet.set_column(8, 3, 15) + sheet.set_column(9, 4, 15) + sheet.set_column(10, 5, 15) + sheet.set_column(11, 6, 15) + + for rec_data in report_data_main[0]: + one_lst = [] + two_lst = [] + + row += 1 + sheet.merge_range(row, col, row, col + 2, rec_data['name'], txt_l) + sheet.write(row, col + 3, rec_data['total'], txt_l) + sheet.write(row, col + 4, rec_data['direction'], txt_l) + sheet.write(row, col + 5, rec_data['4'], txt_l) + sheet.write(row, col + 6, rec_data['3'], txt_l) + sheet.write(row, col + 7, rec_data['2'], txt_l) + sheet.write(row, col + 8, rec_data['1'], txt_l) + sheet.write(row, col + 9, rec_data['0'], txt_l) + row += 1 + sheet.write(row, col, 'Entry Label', sub_heading) + sheet.write(row, col + 1, 'Due Date', sub_heading) + sheet.write(row, col + 2, 'Journal', sub_heading) + sheet.write(row, col + 3, 'Account', sub_heading) + sheet.write(row, col + 4, 'Not Due', sub_heading) + sheet.write(row, col + 5, '0 - 30', sub_heading) + sheet.write(row, col + 6, '30 - 60', sub_heading) + sheet.write(row, col + 7, '60 - 90', sub_heading) + sheet.write(row, col + 8, '90 - 120', sub_heading) + sheet.write(row, col + 9, '120 +', sub_heading) + + for line_data in rec_data['child_lines']: + row += 1 + sheet.write(row, col, line_data.get('move'), txt) + sheet.write(row, col + 1, line_data.get('date'), txt) + sheet.write(row, col + 2, line_data.get('jrnl'), txt) + sheet.write(row, col + 3, line_data.get('acc_code'), txt) + if line_data.get('period6'): + sheet.write(row, col + 4, line_data.get('amount'), txt) + else: + sheet.write(row, col + 4, "0", txt_v) + if line_data.get('period5'): + sheet.write(row, col + 5, line_data.get('amount'), txt) + else: + sheet.write(row, col + 5, "0", txt_v) + if line_data.get('period4'): + sheet.write(row, col + 6, line_data.get('amount'), txt) + else: + sheet.write(row, col + 6, "0", txt_v) + if line_data.get('period3'): + sheet.write(row, col + 7, line_data.get('amount'), txt) + else: + sheet.write(row, col + 7, "0", txt_v) + if line_data.get('period2'): + sheet.write(row, col + 8, line_data.get('amount'), txt) + else: + sheet.write(row, col + 8, "0", txt_v) + if line_data.get('period1'): + sheet.write(row, col + 9, line_data.get('amount'), txt) + else: + sheet.write(row, col + 9, "0", txt_v) + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() diff --git a/dynamic_accounts_report/wizard/balance_sheet.py b/dynamic_accounts_report/wizard/balance_sheet.py new file mode 100644 index 000000000..df74a02ac --- /dev/null +++ b/dynamic_accounts_report/wizard/balance_sheet.py @@ -0,0 +1,657 @@ +import time +from odoo import fields, models, api, _ + +import io +import json +from odoo.exceptions import AccessError, UserError, AccessDenied +from odoo.http import request +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class BalanceSheetView(models.TransientModel): + _name = 'dynamic.balance.sheet.report' + + company_id = fields.Many2one('res.company', required=True, + default=lambda self: self.env.company) + journal_ids = fields.Many2many('account.journal', + string='Journals', required=True, + default=[]) + account_ids = fields.Many2many("account.account", string="Accounts") + account_tag_ids = fields.Many2many("account.account.tag", + string="Account Tags") + analytic_ids = fields.Many2many( + "account.analytic.account", string="Analytic Accounts") + analytic_tag_ids = fields.Many2many("account.analytic.tag", + string="Analytic Tags") + display_account = fields.Selection( + [('all', 'All'), ('movement', 'With movements'), + ('not_zero', 'With balance is not equal to 0')], + string='Display Accounts', required=True, default='movement') + target_move = fields.Selection( + [('all', 'All'), ('posted', 'Posted')], + string='Target Move', required=True, default='posted') + date_from = fields.Date(string="Start date") + date_to = fields.Date(string="End date") + + @api.model + def view_report(self, option, tag): + r = self.env['dynamic.balance.sheet.report'].search( + [('id', '=', option[0])]) + data = { + 'display_account': r.display_account, + 'model': self, + 'journals': r.journal_ids, + 'target_move': r.target_move, + 'accounts': r.account_ids, + 'account_tags': r.account_tag_ids, + 'analytics': r.analytic_ids, + 'analytic_tags': r.analytic_tag_ids, + } + if r.date_from: + data.update({ + 'date_from': r.date_from, + }) + if r.date_to: + data.update({ + 'date_to': r.date_to, + }) + + # company_id = self.env.company + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + company_domain = [('company_id', '=', company_id.id)] + if r.account_tag_ids: + company_domain.append( + ('tag_ids', 'in', r.account_tag_ids.ids)) + if r.account_ids: + company_domain.append(('id', 'in', r.account_ids.ids)) + + new_account_ids = self.env['account.account'].search(company_domain) + data.update({'accounts': new_account_ids,}) + filters = self.get_filter(option) + records = self._get_report_values(data) + + if filters['account_tags'] != ['All']: + tag_accounts = list(map(lambda x: x.code, new_account_ids)) + + def filter_code(rec_dict): + if rec_dict['code'] in tag_accounts: + return True + else: + return False + + new_records = list(filter(filter_code, records['Accounts'])) + records['Accounts'] = new_records + + account_report_id = self.env['account.financial.report'].search([ + ('name', 'ilike', tag)]) + + new_data = {'id': self.id, 'date_from': False, + 'enable_filter': True, + 'debit_credit': True, + 'date_to': False, 'account_report_id': account_report_id, + 'target_move': filters['target_move'], + 'view_format': 'vertical', + 'company_id': company_id.id, + 'used_context': {'journal_ids': False, + 'state': filters['target_move'].lower(), + 'date_from': filters['date_from'], + 'date_to': filters['date_to'], + 'strict_range': False, + 'company_id': company_id.id, + 'lang': 'en_US'}} + + account_lines = self.get_account_lines(new_data) + report_lines = self.view_report_pdf(account_lines, new_data)[ + 'report_lines'] + move_line_accounts = [] + move_lines_dict = {} + + for rec in records['Accounts']: + move_line_accounts.append(rec['code']) + move_lines_dict[rec['code']] = {} + move_lines_dict[rec['code']]['debit'] = rec['debit'] + move_lines_dict[rec['code']]['credit'] = rec['credit'] + move_lines_dict[rec['code']]['balance'] = rec['balance'] + + report_lines_move = [] + parent_list = [] + + def filter_movelines_parents(obj): + for each in obj: + if each['report_type'] == 'accounts': + if each['code'] in move_line_accounts: + report_lines_move.append(each) + parent_list.append(each['p_id']) + + elif each['report_type'] == 'account_report': + report_lines_move.append(each) + else: + report_lines_move.append(each) + + filter_movelines_parents(report_lines) + + for rec in report_lines_move: + if rec['report_type'] == 'accounts': + if rec['code'] in move_line_accounts: + rec['debit'] = move_lines_dict[rec['code']]['debit'] + rec['credit'] = move_lines_dict[rec['code']]['credit'] + rec['balance'] = move_lines_dict[rec['code']]['balance'] + + parent_list = list(set(parent_list)) + max_level = 0 + for rep in report_lines_move: + if rep['level'] > max_level: + max_level = rep['level'] + + def get_parents(obj): + for item in report_lines_move: + for each in obj: + if item['report_type'] != 'account_type' and \ + each in item['c_ids']: + obj.append(item['r_id']) + if item['report_type'] == 'account_report': + obj.append(item['r_id']) + break + + get_parents(parent_list) + for i in range(max_level): + get_parents(parent_list) + + parent_list = list(set(parent_list)) + final_report_lines = [] + + for rec in report_lines_move: + if rec['report_type'] != 'accounts': + if rec['r_id'] in parent_list: + final_report_lines.append(rec) + else: + final_report_lines.append(rec) + + def filter_sum(obj): + sum_list = {} + for pl in parent_list: + sum_list[pl] = {} + sum_list[pl]['s_debit'] = 0 + sum_list[pl]['s_credit'] = 0 + sum_list[pl]['s_balance'] = 0 + + for each in obj: + if each['p_id'] and each['p_id'] in parent_list: + sum_list[each['p_id']]['s_debit'] += each['debit'] + sum_list[each['p_id']]['s_credit'] += each['credit'] + sum_list[each['p_id']]['s_balance'] += each['balance'] + return sum_list + + def assign_sum(obj): + for each in obj: + if each['r_id'] in parent_list and \ + each['report_type'] != 'account_report': + each['debit'] = sum_list_new[each['r_id']]['s_debit'] + each['credit'] = sum_list_new[each['r_id']]['s_credit'] + + for p in range(max_level): + sum_list_new = filter_sum(final_report_lines) + assign_sum(final_report_lines) + + # company_id = self.env.company + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + currency = company_id.currency_id + symbol = currency.symbol + rounding = currency.rounding + position = currency.position + + for rec in final_report_lines: + rec['debit'] = round(rec['debit'], 2) + rec['credit'] = round(rec['credit'], 2) + rec['balance'] = rec['debit'] - rec['credit'] + rec['balance'] = round(rec['balance'], 2) + if (rec['balance_cmp'] < 0 and rec['balance'] > 0) or ( + rec['balance_cmp'] > 0 and rec['balance'] < 0): + rec['balance'] = rec['balance'] * -1 + + if position == "before": + rec['m_debit'] = symbol + " " + "{:,.2f}".format(rec['debit']) + rec['m_credit'] = symbol + " " + "{:,.2f}".format(rec['credit']) + rec['m_balance'] = symbol + " " + "{:,.2f}".format( + rec['balance']) + else: + rec['m_debit'] = "{:,.2f}".format(rec['debit']) + " " + symbol + rec['m_credit'] = "{:,.2f}".format(rec['credit']) + " " + symbol + rec['m_balance'] = "{:,.2f}".format( + rec['balance']) + " " + symbol + + return { + 'name': tag, + 'type': 'ir.actions.client', + 'tag': tag, + 'filters': filters, + 'report_lines': records['Accounts'], + 'debit_total': records['debit_total'], + 'credit_total': records['credit_total'], + 'debit_balance': records['debit_balance'], + 'currency': currency, + 'bs_lines': final_report_lines, + } + + def get_filter(self, option): + data = self.get_filter_data(option) + filters = {} + if data.get('journal_ids'): + filters['journals'] = self.env['account.journal'].browse( + data.get('journal_ids')).mapped('code') + else: + filters['journals'] = ['All'] + if data.get('account_ids', []): + filters['accounts'] = self.env['account.account'].browse( + data.get('account_ids', [])).mapped('code') + else: + filters['accounts'] = ['All'] + if data.get('target_move'): + filters['target_move'] = data.get('target_move') + else: + filters['target_move'] = 'posted' + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + else: + filters['date_from'] = False + if data.get('date_to'): + filters['date_to'] = data.get('date_to') + else: + filters['date_to'] = False + if data.get('analytic_ids', []): + filters['analytics'] = self.env['account.analytic.account'].browse( + data.get('analytic_ids', [])).mapped('name') + else: + filters['analytics'] = ['All'] + + if data.get('account_tag_ids'): + filters['account_tags'] = self.env['account.account.tag'].browse( + data.get('account_tag_ids', [])).mapped('name') + else: + filters['account_tags'] = ['All'] + + if data.get('analytic_tag_ids', []): + filters['analytic_tags'] = self.env['account.analytic.tag'].browse( + data.get('analytic_tag_ids', [])).mapped('name') + else: + filters['analytic_tags'] = ['All'] + + filters['company_id'] = '' + filters['accounts_list'] = data.get('accounts_list') + filters['journals_list'] = data.get('journals_list') + filters['analytic_list'] = data.get('analytic_list') + filters['account_tag_list'] = data.get('account_tag_list') + filters['analytic_tag_list'] = data.get('analytic_tag_list') + filters['company_name'] = data.get('company_name') + filters['target_move'] = data.get('target_move').capitalize() + return filters + + def get_filter_data(self, option): + r = self.env['dynamic.balance.sheet.report'].search( + [('id', '=', option[0])]) + default_filters = {} + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # company_id = self.env.company + company_domain = [('company_id', '=', company_id.id)] + journals = r.journal_ids if r.journal_ids else self.env[ + 'account.journal'].search(company_domain) + analytics = self.analytic_ids if self.analytic_ids else self.env[ + 'account.analytic.account'].search( + company_domain) + account_tags = self.account_tag_ids if self.account_tag_ids else \ + self.env[ + 'account.account.tag'].search([]) + analytic_tags = self.analytic_tag_ids if self.analytic_tag_ids else \ + self.env[ + 'account.analytic.tag'].sudo().search( + ['|', ('company_id', '=', company_id.id), + ('company_id', '=', False)]) + + if r.account_tag_ids: + company_domain.append( + ('tag_ids', 'in', r.account_tag_ids.ids)) + + accounts = self.account_ids if self.account_ids else self.env[ + 'account.account'].search(company_domain) + filter_dict = { + 'journal_ids': r.journal_ids.ids, + 'account_ids': r.account_ids.ids, + 'analytic_ids': r.analytic_ids.ids, + 'company_id': company_id.id, + 'date_from': r.date_from, + 'date_to': r.date_to, + 'target_move': r.target_move, + 'journals_list': [(j.id, j.name, j.code) for j in journals], + 'accounts_list': [(a.id, a.name) for a in accounts], + 'analytic_list': [(anl.id, anl.name) for anl in analytics], + 'company_name': company_id and company_id.name, + 'analytic_tag_ids': r.analytic_tag_ids.ids, + 'analytic_tag_list': [(anltag.id, anltag.name) for anltag in + analytic_tags], + 'account_tag_ids': r.account_tag_ids.ids, + 'account_tag_list': [(a.id, a.name) for a in account_tags], + } + filter_dict.update(default_filters) + return filter_dict + + def _get_report_values(self, data): + docs = data['model'] + display_account = data['display_account'] + init_balance = True + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + company_domain = [('company_id', '=', company_id.id)] + journals = data['journals'] + accounts = self.env['account.account'].search(company_domain) + if not accounts: + raise UserError(_("No Accounts Found! Please Add One")) + account_res = self._get_accounts(accounts, init_balance, + display_account, data) + debit_total = 0 + debit_total = sum(x['debit'] for x in account_res) + credit_total = sum(x['credit'] for x in account_res) + debit_balance = round(debit_total, 2) - round(credit_total, 2) + return { + 'doc_ids': self.ids, + 'debit_total': debit_total, + 'credit_total': credit_total, + 'debit_balance': debit_balance, + 'docs': docs, + 'time': time, + 'Accounts': account_res, + } + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(BalanceSheetView, self).create(vals) + return res + + def write(self, vals): + + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + if vals.get('journal_ids'): + vals.update({'journal_ids': [(6, 0, vals.get('journal_ids'))]}) + if not vals.get('journal_ids'): + vals.update({'journal_ids': [(5,)]}) + if vals.get('account_ids'): + vals.update( + {'account_ids': [(4, j) for j in vals.get('account_ids')]}) + if not vals.get('account_ids'): + vals.update({'account_ids': [(5,)]}) + if vals.get('analytic_ids'): + vals.update( + {'analytic_ids': [(4, j) for j in vals.get('analytic_ids')]}) + if not vals.get('analytic_ids'): + vals.update({'analytic_ids': [(5,)]}) + + if vals.get('account_tag_ids'): + vals.update({'account_tag_ids': [(4, j) for j in + vals.get('account_tag_ids')]}) + if not vals.get('account_tag_ids'): + vals.update({'account_tag_ids': [(5,)]}) + + if vals.get('analytic_tag_ids'): + vals.update({'analytic_tag_ids': [(4, j) for j in + vals.get('analytic_tag_ids')]}) + if not vals.get('analytic_tag_ids'): + vals.update({'analytic_tag_ids': [(5,)]}) + + res = super(BalanceSheetView, self).write(vals) + return res + + def _get_accounts(self, accounts, init_balance, display_account, data): + cr = self.env.cr + MoveLine = self.env['account.move.line'] + move_lines = {x: [] for x in accounts.ids} + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # currency_id = self.env.company.currency_id + currency_id = company_id.currency_id + + # Prepare sql query base on selected parameters from wizard + tables, where_clause, where_params = MoveLine._query_get() + wheres = [""] + where_params[0] = int(company_id.id) + if where_clause.strip(): + wheres.append(where_clause.strip()) + final_filters = " AND ".join(wheres) + final_filters = final_filters.replace('account_move_line__move_id', + 'm').replace( + 'account_move_line', 'l') + new_final_filter = final_filters + + if data['target_move'] == 'posted': + new_final_filter += " AND m.state = 'posted'" + else: + new_final_filter += " AND m.state in ('draft','posted')" + + if data.get('date_from'): + new_final_filter += " AND l.date >= '%s'" % data.get('date_from') + if data.get('date_to'): + new_final_filter += " AND l.date <= '%s'" % data.get('date_to') + + if data['journals']: + new_final_filter += ' AND j.id IN %s' % str( + tuple(data['journals'].ids) + tuple([0])) + + if data.get('accounts'): + WHERE = "WHERE l.account_id IN %s" % str( + tuple(data.get('accounts').ids) + tuple([0])) + else: + WHERE = "WHERE l.account_id IN %s" + + if data['analytics']: + WHERE += ' AND anl.id IN %s' % str( + tuple(data.get('analytics').ids) + tuple([0])) + + if data['analytic_tags']: + WHERE += ' AND anltag.account_analytic_tag_id IN %s' % str( + tuple(data.get('analytic_tags').ids) + tuple([0])) + + # Get move lines base on sql query and Calculate the total balance of move lines + sql = ('''SELECT l.id AS lid,m.id AS move_id, l.account_id AS account_id, + l.date AS ldate, j.code AS lcode, l.currency_id, l.amount_currency, l.ref AS lref, + l.name AS lname, COALESCE(l.debit,0) AS debit, COALESCE(l.credit,0) AS credit, + COALESCE(SUM(l.balance),0) AS balance,\ + m.name AS move_name, c.symbol AS currency_code,c.position AS currency_position, p.name AS partner_name\ + FROM account_move_line l\ + JOIN account_move m ON (l.move_id=m.id)\ + LEFT JOIN res_currency c ON (l.currency_id=c.id)\ + LEFT JOIN res_partner p ON (l.partner_id=p.id)\ + LEFT JOIN account_analytic_account anl ON (l.analytic_account_id=anl.id)\ + LEFT JOIN account_analytic_tag_account_move_line_rel anltag ON (anltag.account_move_line_id = l.id)\ + JOIN account_journal j ON (l.journal_id=j.id)\ + JOIN account_account acc ON (l.account_id = acc.id) ''' + + WHERE + new_final_filter + ''' GROUP BY l.id, m.id, l.account_id, l.date, j.code, l.currency_id, l.amount_currency, l.ref, l.name, m.name, c.symbol, c.position, p.name''') + if data.get('accounts'): + params = tuple(where_params) + else: + params = (tuple(accounts.ids),) + tuple(where_params) + + cr.execute(sql, params) + + for row in cr.dictfetchall(): + balance = 0 + for line in move_lines.get(row['account_id']): + balance += round(line['debit'], 2) - round(line['credit'], 2) + row['balance'] += (round(balance, 2)) + row['m_id'] = row['account_id'] + move_lines[row.pop('account_id')].append(row) + # Calculate the debit, credit and balance for Accounts + account_res = [] + for account in accounts: + currency = account.currency_id and account.currency_id or account.company_id.currency_id + res = dict((fn, 0.0) for fn in ['credit', 'debit', 'balance']) + res['code'] = account.code + res['name'] = account.name + res['id'] = account.id + res['move_lines'] = move_lines[account.id] + for line in res.get('move_lines'): + res['debit'] += round(line['debit'], 2) + res['credit'] += round(line['credit'], 2) + res['balance'] = round(line['balance'], 2) + if display_account == 'all': + account_res.append(res) + if display_account == 'movement' and res.get('move_lines'): + account_res.append(res) + if display_account == 'not_zero' and not currency.is_zero( + res['balance']): + account_res.append(res) + + return account_res + + # @api.model + # def _get_currency(self): + # journal = self.env['account.journal'].browse( + # self.env.context.get('default_journal_id', False)) + # if journal.currency_id: + # return journal.currency_id.id + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position] + # return currency_array + + @api.model + def _get_currency(self): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position, lang] + currency_array = [company_id.currency_id.symbol, + company_id.currency_id.position, lang] + + return currency_array + def get_current_company_value(self): + + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + def get_dynamic_xlsx_report(self, options, response, report_data, dfr_data): + i_data = str(report_data) + filters = json.loads(options) + j_data = dfr_data + rl_data = json.loads(j_data) + + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + sheet = workbook.add_worksheet() + head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '20px'}) + sub_heading = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + side_heading_main = workbook.add_format( + {'align': 'left', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + + side_heading_sub = workbook.add_format( + {'align': 'left', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + + side_heading_sub.set_indent(1) + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + txt_name = workbook.add_format({'font_size': '10px', 'border': 1}) + txt_name_bold = workbook.add_format({'font_size': '10px', 'border': 1, + 'bold': True}) + txt_name.set_indent(2) + txt_name_bold.set_indent(2) + + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + + sheet.merge_range('A2:D3', + filters.get('company_name') + ' : ' + i_data, + head) + date_head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '10px'}) + + date_head.set_align('vcenter') + date_head.set_text_wrap() + date_head.set_shrink() + date_head_left = workbook.add_format({'align': 'left', 'bold': True, + 'font_size': '10px'}) + + date_head_right = workbook.add_format({'align': 'right', 'bold': True, + 'font_size': '10px'}) + + date_head_left.set_indent(1) + date_head_right.set_indent(1) + + if filters.get('date_from'): + sheet.merge_range('A4:B4', 'From: ' + filters.get('date_from'), + date_head_left) + if filters.get('date_to'): + sheet.merge_range('C4:D4', 'To: ' + filters.get('date_to'), + date_head_right) + + sheet.merge_range('A5:D6', ' Accounts: ' + ', '.join( + [lt or '' for lt in + filters['accounts']]) + '; Journals: ' + ', '.join( + [lt or '' for lt in + filters['journals']]) + '; Account Tags: ' + ', '.join( + [lt or '' for lt in + filters['account_tags']]) + '; Analytic Tags: ' + ', '.join( + [lt or '' for lt in + filters['analytic_tags']]) + '; Analytic: ' + ', '.join( + [at or '' for at in + filters['analytics']]) + '; Target Moves: ' + filters.get( + 'target_move').capitalize(), date_head) + + sheet.set_column(0, 0, 30) + sheet.set_column(1, 1, 20) + sheet.set_column(2, 2, 15) + sheet.set_column(3, 3, 15) + + row = 5 + col = 0 + + row += 2 + sheet.write(row, col, '', sub_heading) + sheet.write(row, col + 1, 'Debit', sub_heading) + sheet.write(row, col + 2, 'Credit', sub_heading) + sheet.write(row, col + 3, 'Balance', sub_heading) + + if rl_data: + for fr in rl_data: + + row += 1 + if fr['level'] == 1: + sheet.write(row, col, fr['name'], side_heading_main) + elif fr['level'] == 2: + sheet.write(row, col, fr['name'], side_heading_sub) + else: + sheet.write(row, col, fr['name'], txt_name) + sheet.write(row, col + 1, fr['debit'], txt) + sheet.write(row, col + 2, fr['credit'], txt) + sheet.write(row, col + 3, fr['balance'], txt) + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() \ No newline at end of file diff --git a/dynamic_accounts_report/wizard/balance_sheet_config.py b/dynamic_accounts_report/wizard/balance_sheet_config.py new file mode 100644 index 000000000..6643ad25d --- /dev/null +++ b/dynamic_accounts_report/wizard/balance_sheet_config.py @@ -0,0 +1,305 @@ +import re +from odoo import models, fields, api + + +class BalanceSheet(models.TransientModel): + _inherit = "dynamic.balance.sheet.report" + + def view_report_pdf(self, acc, form): + data = dict() + report_lines = acc + data['form'] = form + + # find the journal items of these accounts + journal_items = self.find_journal_items(report_lines, data['form']) + + def set_report_level(rec): + """This function is used to set the level of each item. + This level will be used to set the alignment in the dynamic reports.""" + + level = 1 + if not rec['parent']: + return level + else: + for line in report_lines: + key = 'a_id' if line['type'] == 'account' else 'id' + if line[key] == rec['parent']: + return level + set_report_level(line) + + # finding the root + for item in report_lines: + item['balance'] = round(item['balance'], 2) + if not item['parent']: + item['level'] = 1 + parent = item + report_name = item['name'] + item_id = item['id'] + report_id = item['r_id'] + else: + item['level'] = set_report_level(item) + data['journal_items'] = journal_items + data['report_lines'] = report_lines + + return data + + def _compute_account_balance(self, accounts): + """ compute the balance, debit + and credit for the provided accounts + """ + + mapping = { + 'balance': + "COALESCE(SUM(debit),0) - COALESCE(SUM(credit), 0)" + " as balance", + 'debit': "COALESCE(SUM(debit), 0) as debit", + 'credit': "COALESCE(SUM(credit), 0) as credit", + } + + res = {} + for account in accounts: + res[account.id] = dict((fn, 0.0) + for fn in mapping.keys()) + if accounts: + tables, where_clause, where_params = ( + self.env['account.move.line']._query_get()) + tables = tables.replace( + '"', '') if tables else "account_move_line" + wheres = [""] + if where_clause.strip(): + wheres.append(where_clause.strip()) + filters = " AND ".join(wheres) + request = ("SELECT account_id as id, " + + ', '.join(mapping.values()) + + " FROM " + tables + + " WHERE account_id IN %s " + + filters + + " GROUP BY account_id") + params = (tuple(accounts._ids),) + tuple(where_params) + + self.env.cr.execute(request, params) + for row in self.env.cr.dictfetchall(): + res[row['id']] = row + + return res + + def _compute_report_balance(self, reports): + """returns a dictionary with key=the ID of a record and + value=the credit, debit and balance amount + computed for this record. If the record is of type : + 'accounts' : it's the sum of the linked accounts + 'account_type' : it's the sum of leaf accounts with + such an account_type + 'account_report' : it's the amount of the related report + 'sum' : it's the sum of the children of this record + (aka a 'view' record)""" + + + res = {} + fields = ['credit', 'debit', 'balance'] + for report in reports: + if report.id in res: + continue + res[report.id] = dict((fn, 0.0) for fn in fields) + if report.type == 'accounts': + # it's the sum of the linked accounts + res[report.id]['account'] = self._compute_account_balance( + report.account_ids + ) + for value in \ + res[report.id]['account'].values(): + for field in fields: + res[report.id][field] += value.get(field) + elif report.type == 'account_type': + # it's the sum the leaf accounts + # with such an account type + accounts = self.env['account.account'].search([ + ('user_type_id', 'in', report.account_type_ids.ids) + ]) + res[report.id]['account'] = self._compute_account_balance( + accounts) + for value in res[report.id]['account'].values(): + for field in fields: + res[report.id][field] += value.get(field) + elif report.type == 'account_report' and report.account_report_id: + # it's the amount of the linked report + res2 = self._compute_report_balance(report.account_report_id) + for key, value in res2.items(): + for field in fields: + res[report.id][field] += value[field] + elif report.type == 'sum': + # it's the sum of the children of this account.report + res2 = self._compute_report_balance(report.children_ids) + for key, value in res2.items(): + for field in fields: + res[report.id][field] += value[field] + return res + + def get_account_lines(self, data): + + lines = [] + account_report = data['account_report_id'] + child_reports = account_report._get_children_by_order() + res = self.with_context( + data.get('used_context'))._compute_report_balance(child_reports) + if data['enable_filter']: + comparison_res = self._compute_report_balance(child_reports) + for report_id, value in comparison_res.items(): + res[report_id]['comp_bal'] = value['balance'] + report_acc = res[report_id].get('account') + if report_acc: + for account_id, val in \ + comparison_res[report_id].get('account').items(): + report_acc[account_id]['comp_bal'] = val['balance'] + + for report in child_reports: + r_name = str(report.name) + r_name = re.sub('[^0-9a-zA-Z]+', '', r_name) + if report.parent_id: + p_name = str(report.parent_id.name) + p_name = re.sub('[^0-9a-zA-Z]+', '', p_name) + str( + report.parent_id.id) + else: + p_name = False + + child_ids = [] + for chd in report.children_ids: + child_ids.append(chd.id) + + vals = { + 'r_id': report.id, + 'p_id': report.parent_id.id, + 'report_type': report.type, + 'c_ids': child_ids, + 'id': r_name + str(report.id), + 'sequence': report.sequence, + 'parent': p_name, + 'name': report.name, + 'balance': res[report.id]['balance'] * int(report.sign), + 'type': 'report', + 'level': bool( + report.style_overwrite) and report.style_overwrite or + report.level, + 'account_type': report.type or False, + 'is_present': False, + # used to underline the financial report balances + } + if data['debit_credit']: + vals['debit'] = res[report.id]['debit'] + vals['credit'] = res[report.id]['credit'] + + if data['enable_filter']: + vals['balance_cmp'] = res[report.id]['comp_bal'] * int( + report.sign) + + lines.append(vals) + if report.display_detail == 'no_detail': + # the rest of the loop is + # used to display the details of the + # financial report, so it's not needed here. + continue + + if res[report.id].get('account'): + sub_lines = [] + for account_id, value \ + in res[report.id]['account'].items(): + # if there are accounts to display, + # we add them to the lines with a level equals + # to their level in + # the COA + 1 (to avoid having them with a too low level + # that would conflicts with the level of data + # financial reports for Assets, liabilities...) + flag = False + account = self.env['account.account'].browse(account_id) + vals = { + 'r_id': False, + 'p_id': report.id, + 'report_type': 'accounts', + 'c_ids': [], + 'account': account.id, + 'code': account.code, + 'a_id': account.code + re.sub('[^0-9a-zA-Z]+', 'acnt', + account.name) + str( + account.id), + 'name': account.code + '-' + account.name, + 'balance': value['balance'] * int(report.sign) or 0.0, + 'type': 'account', + 'parent': r_name + str(report.id), + 'level': ( + report.display_detail == 'detail_with_hierarchy' and + 4), + 'account_type': account.internal_type, + } + if data['debit_credit']: + vals['debit'] = value['debit'] + vals['credit'] = value['credit'] + if not account.company_id.currency_id.is_zero( + vals['debit']) or \ + not account.company_id.currency_id.is_zero( + vals['credit']): + flag = True + if not account.company_id.currency_id.is_zero( + vals['balance']): + flag = True + if data['enable_filter']: + vals['balance_cmp'] = value['comp_bal'] * int( + report.sign) + if not account.company_id.currency_id.is_zero( + vals['balance_cmp']): + flag = True + if flag: + sub_lines.append(vals) + lines += sorted(sub_lines, + key=lambda sub_line: sub_line['name']) + + return lines + + def find_journal_items(self, report_lines, form): + cr = self.env.cr + journal_items = [] + for i in report_lines: + if i['type'] == 'account': + account = i['account'] + if form['target_move'] == 'posted': + search_query = "select aml.id, am.id as j_id, aml.account_id, aml.date," \ + " aml.name as label, am.name, " \ + + "(aml.debit-aml.credit) as balance, aml.debit, aml.credit, aml.partner_id " \ + + " from account_move_line aml join account_move am " \ + "on (aml.move_id=am.id and am.state=%s) " \ + + " where aml.account_id=%s" + vals = [form['target_move']] + else: + search_query = "select aml.id, am.id as j_id, aml.account_id, aml.date, " \ + "aml.name as label, am.name, " \ + + "(aml.debit-aml.credit) as balance, aml.debit, aml.credit, aml.partner_id " \ + + " from account_move_line aml join account_move am on (aml.move_id=am.id) " \ + + " where aml.account_id=%s" + vals = [] + if form['date_from'] and form['date_to']: + search_query += " and aml.date>=%s and aml.date<=%s" + vals += [account, form['date_from'], form['date_to']] + elif form['date_from']: + search_query += " and aml.date>=%s" + vals += [account, form['date_from']] + elif form['date_to']: + search_query += " and aml.date<=%s" + vals += [account, form['date_to']] + else: + vals += [account] + + cr.execute(search_query, tuple(vals)) + items = cr.dictfetchall() + + for j in items: + temp = j['id'] + j['id'] = re.sub('[^0-9a-zA-Z]+', '', i['name']) + str( + temp) + j['p_id'] = str(i['a_id']) + j['type'] = 'journal_item' + journal_items.append(j) + return journal_items + + + + + + diff --git a/dynamic_accounts_report/wizard/cash_flow.py b/dynamic_accounts_report/wizard/cash_flow.py new file mode 100644 index 000000000..a7424a2f5 --- /dev/null +++ b/dynamic_accounts_report/wizard/cash_flow.py @@ -0,0 +1,643 @@ +import time +from datetime import datetime + +from odoo import models, api, fields +from odoo.http import request +FETCH_RANGE = 2000 +import io +import json +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter +year = datetime.now().year + + +class AccountCasgFlow(models.TransientModel): + _name = "account.cash.flow" + _inherit = "account.common.report" + + date_from = fields.Date(string="Start Date", default=str(year)+'-01-01') + date_to = fields.Date(string="End Date", default=fields.Date.today) + today = fields.Date("Report Date", default=fields.Date.today) + levels = fields.Selection([('summary', 'Summary'), + ('consolidated', 'Consolidated'), + ('detailed', 'Detailed'), + ('very', 'Very Detailed')], + string='Levels', required=True, default='summary', + help='Different levels for cash flow statements \n' + 'Summary: Month wise report.\n' + 'Consolidated: Based on account types.\n' + 'Detailed: Based on accounts.\n' + 'Very Detailed: Accounts with their move lines') + + account_ids = fields.Many2many( + "account.account", + string="Accounts", + ) + + @api.model + def view_report(self, option): + r = self.env['account.cash.flow'].search([('id', '=', option[0])]) + data = { + 'model': self, + 'journals': r.journal_ids, + 'target_move': r.target_move, + 'levels': r.levels, + } + if r.date_from: + data.update({ + 'date_from': r.date_from, + }) + if r.date_to: + data.update({ + 'date_to': r.date_to, + }) + + filters = self.get_filter(option) + report_lines = self._get_report_values(data, option) + fetched_data = report_lines['fetched_data'] + fetched = report_lines['fetched'] + account_res = report_lines['account_res'] + journal_res = report_lines['journal_res'] + levels = report_lines['levels'] + currency = self._get_currency() + + return { + 'name': "Cash Flow Statements", + 'type': 'ir.actions.client', + 'tag': 'c_f', + 'report_lines': report_lines, + 'fetched_data': fetched_data, + 'fetched': fetched, + 'account_res': account_res, + 'journal_res': journal_res, + 'levels': r.levels, + 'filters': filters, + 'currency': currency, + } + + def get_current_company_value(self): + + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + def get_filter(self, option): + data = self.get_filter_data(option) + filters = {} + if data.get('journal_ids'): + filters['journals'] = self.env['account.journal'].browse(data.get('journal_ids')).mapped('code') + else: + filters['journals'] = ['All'] + if data.get('account_ids', []): + filters['accounts'] = self.env['account.account'].browse(data.get('account_ids', [])).mapped('code') + else: + filters['accounts'] = ['All'] + if data.get('target_move'): + filters['target_move'] = data.get('target_move') + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + if data.get('date_to'): + filters['date_to'] = data.get('date_to') + if data.get('levels'): + filters['levels'] = data.get('levels') + + filters['company_id'] = '' + filters['accounts_list'] = data.get('accounts_list') + filters['journals_list'] = data.get('journals_list') + filters['company_name'] = data.get('company_name') + filters['target_move'] = data.get('target_move').capitalize() + + return filters + + def get_filter_data(self, option): + r = self.env['account.cash.flow'].search([('id', '=', option[0])]) + default_filters = {} + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # company_id = self.env.company + company_domain = [('company_id', '=', company_id.id)] + journals = r.journal_ids if r.journal_ids else self.env['account.journal'].search(company_domain) + accounts = self.account_ids if self.account_ids else self.env['account.account'].search(company_domain) + + filter_dict = { + 'journal_ids': r.journal_ids.ids, + 'account_ids': self.account_ids.ids, + 'company_id': company_id.id, + 'date_from': r.date_from, + 'date_to': r.date_to, + 'levels': r.levels, + 'target_move': r.target_move, + 'journals_list': [(j.id, j.name, j.code) for j in journals], + 'accounts_list': [(a.id, a.name) for a in accounts], + 'company_name': company_id and company_id.name, + } + filter_dict.update(default_filters) + return filter_dict + + def _get_report_values(self, data, option): + cr = self.env.cr + data = self.get_filter(option) + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # company_id = self.env.company + currency = company_id.currency_id + symbol = company_id.currency_id.symbol + rounding = company_id.currency_id.rounding + position = company_id.currency_id.position + + fetched_data = [] + account_res = [] + journal_res = [] + fetched = [] + + account_type_id = self.env.ref('account.data_account_type_liquidity').id + model = self.env.context.get('active_model') + if data.get('levels') == 'summary': + state = """ WHERE am.state = 'posted' """ if data.get('target_move') == 'posted' else '' + query3 = """SELECT to_char(am.date, 'Month') as month_part, extract(YEAR from am.date) as year_part, + sum(aml.debit) AS total_debit, sum(aml.credit) AS total_credit, + sum(aml.balance) AS total_balance FROM (SELECT am.date, am.id, am.state FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' ) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + """ + state + """GROUP BY month_part,year_part""" + cr = self._cr + cr.execute(query3) + fetched_data = cr.dictfetchall() + elif data.get('date_from') is False: + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + state = """AND am.state = 'posted' """ if data.get( + 'target_move') == 'posted' else '' + sql = """SELECT DISTINCT aa.id, aa.name,aa.code, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit,sum(aml.balance) AS total_balance + FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + GROUP BY aa.name, aa.code,aa.id""" + cr = self._cr + cr.execute(sql) + fetched_data = cr.dictfetchall() + elif data.get('date_from') is False and data.get('date_from') != False: + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + state = """AND am.state = 'posted' """ if data.get( + 'target_move') == 'posted' else '' + sql = """SELECT DISTINCT aa.id, aa.name,aa.code, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit,sum(aml.balance) AS total_balance + FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + GROUP BY aa.name, aa.code,aa.id""" + cr = self._cr + cr.execute(sql) + fetched_data = cr.dictfetchall() + elif data.get('date_from') is False and data.get('date_from') != False: + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + state = """AND am.state = 'posted' """ if data.get( + 'target_move') == 'posted' else '' + sql = """SELECT DISTINCT aa.id, aa.name,aa.code, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit,sum(aml.balance) AS total_balance + FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + GROUP BY aa.name, aa.code,aa.id""" + cr = self._cr + cr.execute(sql) + fetched_data = cr.dictfetchall() + + elif data.get('date_to') == " ": + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + state = """AND am.state = 'posted' """ if data.get( + 'target_move') == 'posted' else '' + sql = """SELECT DISTINCT aa.id, aa.name,aa.code, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit,sum(aml.balance) AS total_balance + FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + GROUP BY aa.name, aa.code,aa.id""" + cr = self._cr + cr.execute(sql) + fetched_data = cr.dictfetchall() + + elif data.get('levels') == 'consolidated': + state = """ WHERE am.state = 'posted' """ if data.get('target_move') == 'posted' else '' + query2 = """SELECT aat.name, sum(aml.debit) AS total_debit, sum(aml.credit) AS total_credit, + sum(aml.balance) AS total_balance FROM ( SELECT am.id, am.state FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str(data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' ) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + """ + state + """GROUP BY aat.name""" + cr = self._cr + cr.execute(query2) + fetched_data = cr.dictfetchall() + elif data.get('levels') == 'detailed': + state = """ WHERE am.state = 'posted' """ if data.get('target_move') == 'posted' else '' + query1 = """SELECT aa.id,aa.name,aa.code, sum(aml.debit) AS total_debit, sum(aml.credit) AS total_credit, + sum(aml.balance) AS total_balance FROM (SELECT am.id, am.state FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' ) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + """ + state + """GROUP BY aa.name, aa.code, aa.id""" + cr = self._cr + cr.execute(query1) + fetched_data = cr.dictfetchall() + for account in self.env['account.account'].search([]): + child_lines = self.get_journal_lines(account, data) + if child_lines: + journal_res.append(child_lines) + + else: + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + state = """AND am.state = 'posted' """ if data.get('target_move') == 'posted' else '' + sql = """SELECT DISTINCT aa.id, aa.name,aa.code, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit,sum(aml.balance) AS total_balance + FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + LEFT JOIN res_company cmp ON cmp.id = am.company_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' AND cmp.id='""" + str( + company_id.id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + GROUP BY aa.name, aa.code,aa.id""" + cr = self._cr + cr.execute(sql) + fetched_data = cr.dictfetchall() + for account in self.env['account.account'].search([]): + child_lines = self._get_lines(account, data) + if child_lines: + account_res.append(child_lines) + journals = self.get_journal_lines(account, data) + if journals: + journal_res.append(journals) + + return { + 'date_from': data.get('date_from'), + 'date_to': data.get('date_to'), + 'levels': data.get('level'), + 'doc_ids': self.ids, + 'doc_model': model, + 'fetched_data': fetched_data, + 'account_res': account_res, + 'journal_res': journal_res, + 'fetched': fetched, + 'company_currency_id': currency, + 'company_currency_symbol': symbol, + 'company_currency_position': position, + } + + def _get_lines(self, account, data): + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + state = """AND am.state = 'posted' """ if data.get('target_move') == 'posted' else '' + query = """SELECT aml.account_id,aj.id as j_id,aj.name,am.id, am.name as move_name, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit, COALESCE(SUM(aml.debit - aml.credit),0) AS balance FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_journal aj ON aj.id = am.journal_id + WHERE aa.id = """ + str(account.id) + """ + GROUP BY am.name, aml.account_id, aj.id, aj.name, am.id""" + + cr = self._cr + cr.execute(query) + fetched_data = cr.dictfetchall() + + sql2 = """SELECT aa.name as account_name,aa.id as account_id, aj.id, aj.name, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit, sum(aml.balance) AS total_balance FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_journal aj ON aj.id = am.journal_id + WHERE aa.id = """ + str( + account.id) + """ + GROUP BY aa.name, aj.name, aj.id,aa.id""" + + cr = self._cr + cr.execute(sql2) + fetch_data = cr.dictfetchall() + if fetched_data: + return { + 'account': account.name, + 'id': account.id, + 'code': account.code, + 'move_lines': fetched_data, + 'journal_lines': fetch_data, + } + + + def get_journal_lines(self, account, data, offset=0, fetch_range=FETCH_RANGE): + account_type_id = self.env.ref( + 'account.data_account_type_liquidity').id + offset_count = offset * fetch_range + state = """AND am.state = 'posted' """ if data.get('target_move') == 'posted' else '' + sql2 = """SELECT aa.name as account_name, aj.name, sum(aml.debit) AS total_debit, + sum(aml.credit) AS total_credit, COALESCE(SUM(aml.debit - aml.credit),0) AS balance FROM (SELECT am.* FROM account_move as am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aat.id = aa.user_type_id + WHERE am.date BETWEEN '""" + str( + data.get('date_from')) + """' and '""" + str( + data.get('date_to')) + """' AND aat.id='""" + str( + account_type_id) + """' """ + state + """) am + LEFT JOIN account_move_line aml ON aml.move_id = am.id + LEFT JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_journal aj ON aj.id = am.journal_id + WHERE aa.id = """ + str(account.id) + """ + GROUP BY aa.name, aj.name""" + + cr = self._cr + cr.execute(sql2) + fetched_data = cr.dictfetchall() + if fetched_data: + return { + 'account': account.name, + 'id': account.id, + 'journal_lines': fetched_data, + 'offset': offset_count, + } + + + + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(AccountCasgFlow, self).create(vals) + return res + + def write(self, vals): + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + if vals.get('journal_ids'): + vals.update({'journal_ids': [(6, 0, vals.get('journal_ids'))]}) + if vals.get('journal_ids') == []: + vals.update({'journal_ids': [(5,)]}) + if vals.get('account_ids'): + vals.update({'account_ids': [(4, j) for j in vals.get('account_ids')]}) + if vals.get('account_ids') == []: + vals.update({'account_ids': [(5,)]}) + + res = super(AccountCasgFlow, self).write(vals) + return res + + @api.model + def _get_currency(self): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position, lang] + currency_array = [company_id.currency_id.symbol, + company_id.currency_id.position, lang] + return currency_array + + def get_dynamic_xlsx_report(self, data, response, report_data, dfr_data): + report_main_data = json.loads(dfr_data) + data = json.loads(data) + report_data = report_main_data.get('report_lines') + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + fetched_data = report_data.get('fetched_data') + account_res = report_data.get('account_res') + journal_res = report_data.get('journal_res') + fetched = report_data.get('fetched') + account_type_id = self.env.ref('account.data_account_type_liquidity').id + currency_symbol = self.env.company.currency_id.symbol + + + logged_users = self.env['res.company']._company_default_get('account.account') + sheet = workbook.add_worksheet() + bold = workbook.add_format({'align': 'center', + 'bold': True, + 'font_size': '10px', + 'border': 1}) + date = workbook.add_format({'font_size': '10px'}) + cell_format = workbook.add_format({'bold': True, + 'font_size': '10px'}) + head = workbook.add_format({'align': 'center', + 'bold': True, + 'bg_color': '#D3D3D3', + 'font_size': '15px'}) + txt = workbook.add_format({'align': 'left', + 'font_size': '10px'}) + txt_left = workbook.add_format({'align': 'left', + 'font_size': '10px', + 'border': 1}) + txt_center = workbook.add_format({'align': 'center', + 'font_size': '10px', + 'border': 1}) + amount = workbook.add_format({'align': 'right', + 'font_size': '10px', + 'border': 1}) + amount_bold = workbook.add_format({'align': 'right', + 'bold': True, + 'font_size': '10px', + 'border': 1}) + txt_bold = workbook.add_format({'align': 'left', + 'bold': True, + 'font_size': '10px', + 'border': 1}) + + sheet.set_column('C:C', 30, cell_format) + sheet.set_column('D:E', 20, cell_format) + sheet.set_column('F:F', 20, cell_format) + sheet.merge_range('C3:F5', '') + sheet.merge_range('C3:F4', 'CASH FLOW STATEMENTS', head) + sheet.merge_range('C4:F4', '') + + sheet.write('C6', "Date From", cell_format) + sheet.write('D6', str(data['date_from']), date) + sheet.write('E6', "Date To", cell_format) + sheet.write('F6', str(data['date_to']), date) + if data.get('levels'): + sheet.write('C7', "Level", cell_format) + sheet.write('D7', data.get("levels"), date) + sheet.write('E7', "Target Moves", cell_format) + sheet.write('F7', data.get("target_move"), date) + sheet.write('C9', 'NAME', bold) + sheet.write('D9', 'CASH IN', bold) + sheet.write('E9', 'CASH OUT', bold) + sheet.write('F9', 'BALANCE', bold) + + row_num = 9 + col_num = 2 + fetched_data_list = fetched_data + account_res_list = account_res + journal_res_list = journal_res + fetched_list = fetched + + for i_rec in fetched_data_list: + if data['levels'] == 'summary': + sheet.write(row_num + 1, col_num, str(i_rec['month_part']) + str(int(i_rec['year_part'])), txt_left) + sheet.write(row_num + 1, col_num + 1, str(i_rec['total_debit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 2, str(i_rec['total_credit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 3, + str(i_rec['total_debit'] - i_rec['total_credit']) + str(currency_symbol), + amount) + row_num = row_num + 1 + elif data['levels'] == 'consolidated': + sheet.write(row_num + 1, col_num, i_rec['name'], txt_left) + sheet.write(row_num + 1, col_num + 1, str(i_rec['total_debit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 2, str(i_rec['total_credit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 3, + str(i_rec['total_debit'] - i_rec['total_credit']) + str(currency_symbol), + amount) + row_num = row_num + 1 + + for j_rec in journal_res_list: + if data['levels'] == 'detailed': + for k in fetched_data_list: + if k['name'] == j_rec['account']: + sheet.write(row_num + 1, col_num, str(k['code']) + str(k['name']), txt_bold) + sheet.write(row_num + 1, col_num + 1, str(k['total_debit']) + str(currency_symbol), amount_bold) + sheet.write(row_num + 1, col_num + 2, str(k['total_credit']) + str(currency_symbol), amount_bold) + sheet.write(row_num + 1, col_num + 3, + str(k['total_debit'] - k['total_credit']) + str(currency_symbol), amount_bold) + row_num = row_num + 1 + for l_jrec in j_rec['journal_lines']: + sheet.write(row_num + 1, col_num, l_jrec['name'], txt_left) + sheet.write(row_num + 1, col_num + 1, str(l_jrec['total_debit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 2, str(l_jrec['total_credit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 3, + str(l_jrec['total_debit'] - l_jrec['total_credit']) + str(currency_symbol), + amount) + row_num = row_num + 1 + + for j_rec in account_res_list: + if data['levels'] == 'very': + for k in fetched_data_list: + if k['name'] == j_rec['account']: + sheet.write(row_num + 1, col_num, str(k['code']) + str(k['name']), txt_bold) + sheet.write(row_num + 1, col_num + 1, str(k['total_debit']) + str(currency_symbol), amount_bold) + sheet.write(row_num + 1, col_num + 2, str(k['total_credit']) + str(currency_symbol), amount_bold) + sheet.write(row_num + 1, col_num + 3, + str(k['total_debit'] - k['total_credit']) + str(currency_symbol), amount_bold) + row_num = row_num + 1 + for l_jrec in j_rec['journal_lines']: + if l_jrec['account_name'] == j_rec['account']: + sheet.write(row_num + 1, col_num, l_jrec['name'], txt_left) + sheet.write(row_num + 1, col_num + 1, str(l_jrec['total_debit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 2, str(l_jrec['total_credit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 3, + str(l_jrec['total_debit'] - l_jrec['total_credit']) + str(currency_symbol), + amount) + row_num = row_num + 1 + for m_rec in j_rec['move_lines']: + if m_rec['name'] == l_jrec['name']: + sheet.write(row_num + 1, col_num, m_rec['move_name'], txt_center) + sheet.write(row_num + 1, col_num + 1, str(m_rec['total_debit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 2, str(m_rec['total_credit']) + str(currency_symbol), amount) + sheet.write(row_num + 1, col_num + 3, + str(m_rec['total_debit'] - m_rec['total_credit']) + str(currency_symbol), + amount) + row_num = row_num + 1 + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() \ No newline at end of file diff --git a/dynamic_accounts_report/wizard/daybook.py b/dynamic_accounts_report/wizard/daybook.py new file mode 100644 index 000000000..ff08feb7c --- /dev/null +++ b/dynamic_accounts_report/wizard/daybook.py @@ -0,0 +1,347 @@ +import time +from datetime import date +from datetime import timedelta, datetime +from odoo import fields, models, api, _ +import io +import json +from odoo.http import request +from odoo.exceptions import AccessError, UserError, AccessDenied + +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class AgeingView(models.TransientModel): + _name = 'account.day.book' + + company_id = fields.Many2one('res.company', string='Company', + readonly=True, + default=lambda self: self.env.company) + journal_ids = fields.Many2many('account.journal', string='Journals', + required=True, + default=lambda self: self.env[ + 'account.journal'].search([])) + + account_ids = fields.Many2many('account.account', + required=True, string='Accounts', + ) + + date_from = fields.Date(string='Start Date', default=date.today(), + required=True) + date_to = fields.Date(string='End Date', default=date.today(), + required=True) + + target_move = fields.Selection([('posted', 'All Posted Entries'), + ('all', 'All Entries')], + string='Target Moves', required=True, + default='posted') + + @api.model + def view_report(self, option): + r = self.env['account.day.book'].search([('id', '=', option[0])]) + data = {} + data['ids'] = self.env.context.get('active_ids', []) + data['model'] = self.env.context.get('active_model', 'ir.ui.menu') + data['form'] = \ + r.read(['date_from', 'date_to', 'journal_ids', 'target_move', + 'account_ids'])[0] + filters = self.get_filter(option) + records = self._get_report_values(data) + currency = self._get_currency() + return { + 'name': "Day Book", + 'type': 'ir.actions.client', + 'tag': 'd_b', + 'filters': filters, + 'report_lines': records['Accounts'], + 'currency': currency, + } + def get_current_company_value(self): + + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + def get_filter(self, option): + data = self.get_filter_data(option) + filters = {} + + if data.get('target_move'): + filters['target_move'] = data.get('target_move') + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + if data.get('date_to'): + filters['date_to'] = data.get('date_to') + if data.get('journal_ids'): + filters['journals'] = self.env['account.journal'].browse( + data.get('journal_ids')).mapped('code') + else: + filters['journals'] = ['All'] + if data.get('account_ids', []): + filters['accounts'] = self.env['account.account'].browse( + data.get('account_ids', [])).mapped('code') + else: + filters['accounts'] = ['All'] + filters['company_id'] = '' + filters['accounts_list'] = data.get('accounts_list') + filters['journals_list'] = data.get('journals_list') + filters['company_name'] = data.get('company_name') + filters['target_move'] = data.get('target_move').capitalize() + + return filters + + def get_filter_data(self, option): + r = self.env['account.day.book'].search([('id', '=', option[0])]) + default_filters = {} + # company_id = self.env.company + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + company_domain = [('company_id', '=', company_id.id)] + journals = self.journal_ids if self.journal_ids else self.env[ + 'account.journal'].search(company_domain) + accounts = self.account_ids if self.account_ids else self.env[ + 'account.account'].search(company_domain) + + filter_dict = { + 'journal_ids': self.journal_ids.ids, + 'account_ids': self.account_ids.ids, + 'company_id': company_id.id, + 'date_from': r.date_from, + 'date_to':r.date_to, + + 'target_move': r.target_move, + 'journals_list': [(j.id, j.name, j.code) for j in journals], + 'accounts_list': [(a.id, a.name) for a in accounts], + + 'company_name': company_id and company_id.name, + } + filter_dict.update(default_filters) + return filter_dict + + def _get_report_values(self, data=None): + form_data = data['form'] + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + company_domain = [('company_id', '=', company_id.id)] + active_acc = data['form']['account_ids'] + accounts = self.env['account.account'].search( + [('id', 'in', active_acc)]) if data['form']['account_ids'] else \ + self.env['account.account'].search(company_domain) + if not accounts: + raise UserError(_("No Accounts Found! Please Add One")) + active_jrnl = data['form']['journal_ids'] + journals = self.env['account.journal'].search( + [('id', 'in', active_jrnl)]) if data['form']['journal_ids'] else \ + self.env['account.journal'].search(company_domain) + if not journals: + raise UserError(_("No journals Found!")) + + + date_start = datetime.strptime(str(form_data['date_from']), + '%Y-%m-%d').date() + date_end = datetime.strptime(str(form_data['date_to']), '%Y-%m-%d').date() + days = date_end - date_start + dates = [] + record = [] + for i in range(days.days + 1): + dates.append(date_start + timedelta(days=i)) + for head in dates: + pass_date = str(head) + accounts_res = self._get_account_move_entry( + accounts, form_data,journals, pass_date) + if accounts_res['lines']: + record.append({ + 'date': head, + 'debit': accounts_res['debit'], + 'credit': accounts_res['credit'], + 'balance': accounts_res['balance'], + 'child_lines': accounts_res['lines'], + 'id': accounts_res['move_id'], + }) + return { + 'doc_ids': self.ids, + 'time': time, + 'Accounts': record, + } + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(AgeingView, self).create(vals) + return res + + def write(self, vals): + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + if vals.get('journal_ids'): + vals.update({'journal_ids': [(6, 0, vals.get('journal_ids'))]}) + if vals.get('journal_ids') == []: + vals.update({'journal_ids': [(5,)]}) + if vals.get('account_ids'): + vals.update( + {'account_ids': [(4, j) for j in vals.get('account_ids')]}) + if vals.get('account_ids') == []: + vals.update({'account_ids': [(5,)]}) + res = super(AgeingView, self).write(vals) + return res + + def _get_account_move_entry(self, accounts, form_data,journals, pass_date): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + cr = self.env.cr + move_line = self.env['account.move.line'] + tables, where_clause, where_params = move_line._query_get() + where_params[0] = int(company_id.id) + wheres = [""] + if where_clause.strip(): + wheres.append(where_clause.strip()) + if form_data['target_move'] == 'posted': + target_move = "AND m.state = 'posted'" + else: + target_move = '' + sql = (''' + SELECT l.id AS lid,m.id AS move_id, acc.name as accname, l.account_id AS account_id, l.date AS ldate, j.code AS lcode, l.currency_id, + l.amount_currency, l.ref AS lref, l.name AS lname, COALESCE(l.debit,0) AS debit, COALESCE(l.credit,0) AS credit, + COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) AS balance, + m.name AS move_name, c.symbol AS currency_code, p.name AS partner_name + FROM account_move_line l + JOIN account_move m ON (l.move_id=m.id) + LEFT JOIN res_currency c ON (l.currency_id=c.id) + LEFT JOIN res_partner p ON (l.partner_id=p.id) + JOIN account_journal j ON (l.journal_id=j.id) + JOIN account_account acc ON (l.account_id = acc.id) + WHERE l.account_id IN %s AND l.journal_id IN %s ''' + target_move + ''' AND l.date = %s + GROUP BY l.id,m.id, l.account_id, l.date, + j.code, l.currency_id, l.amount_currency, l.ref, l.name, m.name, c.symbol, p.name , acc.name + ORDER BY l.date DESC + ''') + params = ( + tuple(accounts.ids), tuple(journals.ids), pass_date) + cr.execute(sql, params) + data = cr.dictfetchall() + + res = {} + debit = credit = balance = 0.00 + id = '' + for line in data: + debit += line['debit'] + credit += line['credit'] + balance += line['balance'] + id = line['move_id'] + res['debit'] = debit + res['credit'] = credit + res['balance'] = balance + res['lines'] = data + res['move_id'] = id + return res + + @api.model + def _get_currency(self): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position, lang] + currency_array = [company_id.currency_id.symbol, + company_id.currency_id.position, lang] + return currency_array + + def get_dynamic_xlsx_report(self, data, response, report_data, dfr_data): + report_data_main = json.loads(report_data) + output = io.BytesIO() + filters = json.loads(data) + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + sheet = workbook.add_worksheet() + head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '20px'}) + sub_heading = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + txt_l = workbook.add_format( + {'font_size': '10px', 'border': 1, 'bold': True}) + sheet.merge_range('A2:D3', + filters.get('company_name') + ':' + ' Day Book', + head) + date_head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '10px'}) + date_style = workbook.add_format({'align': 'center', + 'font_size': '10px'}) + if filters.get('date_from'): + sheet.merge_range('A4:B4', 'From: ' + filters.get('date_from'), + date_head) + if filters.get('date_to'): + sheet.merge_range('C4:D4', 'To: ' + filters.get('date_to'), + date_head) + sheet.write('A5', 'Journals: ' + ', '.join([lt or '' for lt in + filters[ + 'journals']]), + date_head) + + sheet.merge_range('E4:F4', + 'Target Moves: ' + filters.get('target_move'), + date_head) + sheet.merge_range('B5:D5', + 'Account Type: ' + ', '.join([lt or '' for lt in + filters[ + 'accounts']]), + date_head) + + sheet.merge_range('A7:E7', 'Date', sub_heading) + sheet.write('F7', 'Debit', sub_heading) + sheet.write('G7', 'Credit', sub_heading) + sheet.write('H7', 'Balance', sub_heading) + + row = 6 + col = 0 + sheet.set_column(4, 0, 15) + sheet.set_column(5, 0, 15) + sheet.set_column(6, 1, 15) + sheet.set_column(7, 2, 15) + sheet.set_column(8, 3, 15) + sheet.set_column(9, 4, 15) + sheet.set_column(10, 5, 15) + sheet.set_column(11, 6, 15) + for rec_data in report_data_main: + one_lst = [] + two_lst = [] + row += 1 + sheet.merge_range(row, col, row, col + 4, rec_data['date'], txt_l) + sheet.write(row, col + 5, rec_data['debit'], txt_l) + sheet.write(row, col + 6, rec_data['credit'], txt_l) + sheet.write(row, col + 7, rec_data['balance'], txt_l) + for line_data in rec_data['child_lines']: + row += 1 + sheet.write(row, col, line_data.get('ldate'), txt) + sheet.write(row, col + 1, line_data.get('lcode'), txt) + sheet.write(row, col + 2, line_data.get('partner_name'), + txt) + sheet.write(row, col + 3, line_data.get('move_name'), txt) + sheet.write(row, col + 4, line_data.get('lname'), txt) + sheet.write(row, col + 5, line_data.get('debit'), txt) + sheet.write(row, col + 6, line_data.get('credit'), txt) + sheet.write(row, col + 7, line_data.get('balance'), txt) + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() diff --git a/dynamic_accounts_report/wizard/general_ledger.py b/dynamic_accounts_report/wizard/general_ledger.py new file mode 100644 index 000000000..39ccd57fc --- /dev/null +++ b/dynamic_accounts_report/wizard/general_ledger.py @@ -0,0 +1,509 @@ +import time +from odoo import fields, models, api, _ + +import io +import json +from odoo.exceptions import AccessError, UserError, AccessDenied +from odoo.http import request +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class GeneralView(models.TransientModel): + _inherit = "account.common.report" + _name = 'account.general.ledger' + + journal_ids = fields.Many2many('account.journal', + + string='Journals', required=True, + default=[]) + account_ids = fields.Many2many( + "account.account", + string="Accounts", + ) + account_tag_ids = fields.Many2many("account.account.tag", string="Account Tags") + + analytic_ids = fields.Many2many( + "account.analytic.account", string="Analytic Accounts" + ) + analytic_tag_ids = fields.Many2many("account.analytic.tag", string="Analytic Tags") + + display_account = fields.Selection( + [('all', 'All'), ('movement', 'With movements'), + ('not_zero', 'With balance is not equal to 0')], + string='Display Accounts', required=True, default='movement') + titles = fields.Char('Title') + target_move = fields.Selection([('posted', 'All Posted Entries'), + ('all', 'All Entries')], + string='Target Moves', required=True) + + @api.model + def view_report(self, option, title): + r = self.env['account.general.ledger'].search([('id', '=', option[0])]) + new_title = '' + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # company_domain = [('company_id', '=', company_id.id)] + journals = r.journal_ids + if title == 'General Ledger': + journals = r.journal_ids + new_title = 'General Ledger' + if title == 'Bank Book': + journals = self.env['account.journal'].search([('type', '=', 'bank'), ('company_id', '=', company_id.id)], + limit=1) + new_title = 'Bank Book' + if title == 'Cash Book': + journals = self.env['account.journal'].search([('type', '=', 'cash'), ('company_id', '=', company_id.id)], + limit=1) + new_title = 'Cash Book' + r.write({ + 'titles': new_title, + }) + data = { + 'display_account': r.display_account, + 'model':self, + 'journals': journals, + 'target_move': r.target_move, + 'accounts': r.account_ids, + 'account_tags': r.account_tag_ids, + 'analytics': r.analytic_ids, + 'analytic_tags': r.analytic_tag_ids, + + } + if r.date_from: + data.update({ + 'date_from': r.date_from, + }) + if r.date_to: + data.update({ + 'date_to': r.date_to, + }) + + filters = self.get_filter(option) + records = self._get_report_values(data) + currency = self._get_currency() + return { + 'name': new_title, + 'type': 'ir.actions.client', + 'tag': 'g_l', + 'filters': filters, + 'report_lines': records['Accounts'], + 'debit_total': records['debit_total'], + 'credit_total': records['credit_total'], + 'debit_balance': records['debit_balance'], + 'currency': currency, + } + + def get_current_company_value(self): + + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + def get_filter(self, option): + data = self.get_filter_data(option) + filters = {} + if data.get('journal_ids'): + filters['journals'] = self.env['account.journal'].browse(data.get('journal_ids')).mapped('code') + else: + filters['journals'] = ['All'] + if data.get('account_ids', []): + filters['accounts'] = self.env['account.account'].browse(data.get('account_ids', [])).mapped('code') + else: + filters['accounts'] = ['All'] + if data.get('account_tag_ids', []): + filters['account_tags'] = data.get('account_tag_ids') + else: + filters['account_tags'] = ['All'] + if data.get('target_move'): + filters['target_move'] = data.get('target_move') + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + if data.get('date_to'): + filters['date_to'] = data.get('date_to') + if data.get('analytic_ids', []): + filters['analytics'] = self.env['account.analytic.account'].browse( + data.get('analytic_ids', [])).mapped('name') + else: + filters['analytics'] = ['All'] + if data.get('analytic_tag_ids', []): + filters['account_tags'] = self.env['account.account.tag'].browse( + data.get('account_tag_ids', [])).mapped('name') + else: + filters['analytic_tags'] = ['All'] + + filters['company_id'] = '' + filters['accounts_list'] = data.get('accounts_list') + filters['account_tag_list'] = data.get('account_tag_list') + filters['journals_list'] = data.get('journals_list') + filters['analytic_list'] = data.get('analytic_list') + filters['analytic_tag_list'] = data.get('analytic_tag_list') + filters['company_name'] = data.get('company_name') + filters['target_move'] = data.get('target_move').capitalize() + + return filters + + def get_filter_data(self, option): + r = self.env['account.general.ledger'].search([('id', '=', option[0])]) + default_filters = {} + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # company_id = self.env.company + company_domain = [('company_id', '=', company_id.id)] + journals = r.journal_ids if r.journal_ids else self.env['account.journal'].search(company_domain) + accounts = self.account_ids if self.account_ids else self.env['account.account'].search(company_domain) + account_tags = r.account_tag_ids if r.account_tag_ids else self.env[ + 'account.account.tag'].search([]) + analytics = r.analytic_ids if r.analytic_ids else self.env['account.analytic.account'].search( + company_domain) + analytic_tags = r.analytic_tag_ids if r.analytic_tag_ids else self.env[ + 'account.analytic.tag'].search([]) + filter_dict = { + 'journal_ids': r.journal_ids.ids, + 'analytic_ids': r.analytic_ids.ids, + 'analytic_tag_ids': r.analytic_tag_ids.ids, + 'account_ids': r.account_ids.ids, + 'account_tag_ids': r.account_tag_ids.ids, + 'company_id': company_id.id, + 'date_from': r.date_from, + 'date_to': r.date_to, + 'target_move': r.target_move, + 'journals_list': [(j.id, j.name, j.code) for j in journals], + 'accounts_list': [(a.id, a.name) for a in accounts], + 'account_tag_list': [(a.id, a.name) for a in account_tags], + 'analytic_list': [(anl.id, anl.name) for anl in analytics], + 'analytic_tag_list': [(anltag.id, anltag.name) for anltag in analytic_tags], + 'company_name': company_id and company_id.name, + } + filter_dict.update(default_filters) + return filter_dict + + def _get_report_values(self, data): + docs = data['model'] + display_account = data['display_account'] + init_balance = True + journals = data['journals'] + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + company_domain = [('company_id', '=', company_id.id)] + accounts = self.env['account.account'].search(company_domain) + if not accounts: + raise UserError(_("No Accounts Found! Please Add One")) + account_res = self._get_accounts(accounts, init_balance, display_account, data) + debit_total = 0 + debit_total = sum(x['debit'] for x in account_res) + credit_total = sum(x['credit'] for x in account_res) + debit_balance = round(debit_total,2) - round(credit_total,2) + return { + 'doc_ids': self.ids, + 'debit_total': debit_total, + 'credit_total': credit_total, + 'debit_balance':debit_balance, + 'docs': docs, + 'time': time, + 'Accounts': account_res, + } + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(GeneralView, self).create(vals) + return res + + def write(self, vals): + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + if vals.get('journal_ids'): + vals.update({'journal_ids': [(6, 0, vals.get('journal_ids'))]}) + if vals.get('journal_ids') == []: + vals.update({'journal_ids': [(5,)]}) + if vals.get('account_ids'): + vals.update({'account_ids': [(4, j) for j in vals.get('account_ids')]}) + if vals.get('account_ids') == []: + vals.update({'account_ids': [(5,)]}) + if vals.get('account_tag_ids'): + vals.update({'account_tag_ids': [(4, j) for j in vals.get('account_tag_ids')]}) + if vals.get('account_tag_ids') == []: + vals.update({'account_tag_ids': [(5,)]}) + if vals.get('analytic_ids'): + vals.update({'analytic_ids': [(4, j) for j in vals.get('analytic_ids')]}) + if vals.get('analytic_ids') == []: + vals.update({'analytic_ids': [(5,)]}) + if vals.get('analytic_tag_ids') == []: + vals.update({'analytic_tag_ids': [(4, j) for j in vals.get('analytic_tag_ids')]}) + if vals.get('analytic_tag_ids') == []: + vals.update({'analytic_tag_ids': [(5,)]}) + res = super(GeneralView, self).write(vals) + return res + + def _get_accounts(self, accounts, init_balance, display_account, data): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + + cr = self.env.cr + MoveLine = self.env['account.move.line'] + move_lines = {x: [] for x in accounts.ids} + + # Prepare initial sql query and Get the initial move lines + if init_balance and data.get('date_from'): + init_tables, init_where_clause, init_where_params = MoveLine.with_context( + date_from=self.env.context.get('date_from'), date_to=False, + initial_bal=True)._query_get() + + init_where_params[0] = int(company_id.id) + init_wheres = [""] + if init_where_clause.strip(): + init_wheres.append(init_where_clause.strip()) + init_filters = " AND ".join(init_wheres) + filters = init_filters.replace('account_move_line__move_id', + 'm').replace('account_move_line', + 'l') + new_filter = filters + if data['target_move'] == 'posted': + new_filter += " AND m.state = 'posted'" + else: + new_filter += " AND m.state in ('draft','posted')" + if data.get('date_from'): + new_filter += " AND l.date < '%s'" % data.get('date_from') + if data['journals']: + new_filter += ' AND j.id IN %s' % str(tuple(data['journals'].ids) + tuple([0])) + if data.get('accounts'): + WHERE = "WHERE l.account_id IN %s" % str(tuple(data.get('accounts').ids) + tuple([0])) + else: + WHERE = "WHERE l.account_id IN %s" + if data.get('analytics'): + WHERE += ' AND anl.id IN %s' % str(tuple(data.get('analytics').ids) + tuple([0])) + if data.get('analytic_tags'): + WHERE += ' AND anltag.account_analytic_tag_id IN %s' % str( + tuple(data.get('analytic_tags').ids) + tuple([0])) + + + sql = ("""SELECT 0 AS lid, l.account_id AS account_id, '' AS ldate, '' AS lcode, 0.0 AS amount_currency, '' AS lref, 'Initial Balance' AS lname, COALESCE(SUM(l.debit),0.0) AS debit, COALESCE(SUM(l.credit),0.0) AS credit, COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance, '' AS lpartner_id,\ + '' AS move_name, '' AS mmove_id, '' AS currency_code,\ + NULL AS currency_id,\ + '' AS invoice_id, '' AS invoice_type, '' AS invoice_number,\ + '' AS partner_name\ + FROM account_move_line l\ + LEFT JOIN account_move m ON (l.move_id=m.id)\ + LEFT JOIN res_currency c ON (l.currency_id=c.id)\ + LEFT JOIN res_partner p ON (l.partner_id=p.id)\ + LEFT JOIN account_move i ON (m.id =i.id)\ + LEFT JOIN account_account_tag_account_move_line_rel acc ON (acc.account_move_line_id=l.id) + LEFT JOIN account_analytic_account anl ON (l.analytic_account_id=anl.id) + LEFT JOIN account_analytic_tag_account_move_line_rel anltag ON (anltag.account_move_line_id=l.id) + JOIN account_journal j ON (l.journal_id=j.id)""" + + WHERE + new_filter + ' GROUP BY l.account_id') + if data.get('accounts'): + params = tuple(init_where_params) + else: + params = (tuple(accounts.ids),) + tuple(init_where_params) + cr.execute(sql, params) + for row in cr.dictfetchall(): + row['m_id'] = row['account_id'] + move_lines[row.pop('account_id')].append(row) + + tables, where_clause, where_params = MoveLine._query_get() + where_params[0] = int(company_id.id) + wheres = [""] + if where_clause.strip(): + wheres.append(where_clause.strip()) + final_filters = " AND ".join(wheres) + final_filters = final_filters.replace('account_move_line__move_id', 'm').replace( + 'account_move_line', 'l') + new_final_filter = final_filters + if data['target_move'] == 'posted': + new_final_filter += " AND m.state = 'posted'" + else: + new_final_filter += " AND m.state in ('draft','posted')" + if data.get('date_from'): + new_final_filter += " AND l.date >= '%s'" % data.get('date_from') + if data.get('date_to'): + new_final_filter += " AND l.date <= '%s'" % data.get('date_to') + + if data['journals']: + new_final_filter += ' AND j.id IN %s' % str(tuple(data['journals'].ids) + tuple([0])) + if data.get('accounts'): + WHERE = "WHERE l.account_id IN %s" % str(tuple(data.get('accounts').ids) + tuple([0])) + else: + WHERE = "WHERE l.account_id IN %s" + if data.get('analytics'): + WHERE += ' AND anl.id IN %s' % str(tuple(data.get('analytics').ids) + tuple([0])) + + if data.get('analytic_tags'): + WHERE += ' AND anltag.account_analytic_tag_id IN %s' % str( + tuple(data.get('analytic_tags').ids) + tuple([0])) + + # Get move lines base on sql query and Calculate the total balance of move lines + sql = ('''SELECT l.id AS lid,m.id AS move_id, l.account_id AS account_id, l.date AS ldate, j.code AS lcode, l.currency_id, l.amount_currency, l.ref AS lref, l.name AS lname, COALESCE(l.debit,0) AS debit, COALESCE(l.credit,0) AS credit, COALESCE(SUM(l.balance),0) AS balance,\ + m.name AS move_name, c.symbol AS currency_code, p.name AS partner_name\ + FROM account_move_line l\ + JOIN account_move m ON (l.move_id=m.id)\ + LEFT JOIN res_currency c ON (l.currency_id=c.id)\ + LEFT JOIN res_partner p ON (l.partner_id=p.id)\ + LEFT JOIN account_analytic_account anl ON (l.analytic_account_id=anl.id) + LEFT JOIN account_account_tag_account_move_line_rel acc ON (acc.account_move_line_id=l.id) + LEFT JOIN account_analytic_tag_account_move_line_rel anltag ON (anltag.account_move_line_id=l.id) + JOIN account_journal j ON (l.journal_id=j.id)\ + JOIN account_account a ON (l.account_id = a.id) ''' + + WHERE + new_final_filter + ''' GROUP BY l.id, m.id, l.account_id, l.date, j.code, l.currency_id, l.amount_currency, l.ref, l.name, m.name, c.symbol, c.position, p.name''' ) + if data.get('accounts'): + params = tuple(where_params) + else: + params = (tuple(accounts.ids),) + tuple(where_params) + cr.execute(sql, params) + + for row in cr.dictfetchall(): + balance = 0 + for line in move_lines.get(row['account_id']): + balance += round(line['debit'],2) - round(line['credit'],2) + row['balance'] += round(balance,2) + row['m_id'] = row['account_id'] + move_lines[row.pop('account_id')].append(row) + + # Calculate the debit, credit and balance for Accounts + account_res = [] + for account in accounts: + currency = account.currency_id and account.currency_id or account.company_id.currency_id + res = dict((fn, 0.0) for fn in ['credit', 'debit', 'balance']) + res['code'] = account.code + res['name'] = account.name + res['id'] = account.id + res['move_lines'] = move_lines[account.id] + for line in res.get('move_lines'): + res['debit'] += round(line['debit'],2) + res['credit'] += round(line['credit'],2) + res['balance'] = round(line['balance'],2) + if display_account == 'all': + account_res.append(res) + if display_account == 'movement' and res.get('move_lines'): + account_res.append(res) + if display_account == 'not_zero' and not currency.is_zero( + res['balance']): + account_res.append(res) + + return account_res + + @api.model + def _get_currency(self): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + currency_array = [self.env.company.currency_id.symbol, + self.env.company.currency_id.position,lang] + currency_array = [company_id.currency_id.symbol, + company_id.currency_id.position, lang] + return currency_array + + def get_dynamic_xlsx_report(self, data, response ,report_data, dfr_data): + report_data_main = json.loads(report_data) + output = io.BytesIO() + name_data = json.loads(dfr_data) + filters = json.loads(data) + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + sheet = workbook.add_worksheet() + head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '20px'}) + sub_heading = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + txt_l = workbook.add_format({'font_size': '10px', 'border': 1, 'bold': True}) + sheet.merge_range('A2:J3', filters.get('company_name') + ':' + name_data.get('name'), head) + date_head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '10px'}) + date_style = workbook.add_format({'align': 'center', + 'font_size': '10px'}) + if filters.get('date_from'): + sheet.merge_range('B4:C4', 'From: ' + filters.get('date_from'), date_head) + if filters.get('date_to'): + sheet.merge_range('H4:I4', 'To: ' + filters.get('date_to'), date_head) + # sheet.merge_range('A5:J6', 'Journals: ' + ', '.join( + # [lt or '' for lt in filters['journals']]) + ' Target Moves: ' + filters.get('target_move'), date_head) + + sheet.merge_range('A5:J6', ' Journals: ' + ', '.join( + [lt or '' for lt in + filters['journals']]) + ' Accounts: ' + ', '.join( + [lt or '' for lt in + filters['accounts']]) + ' Account Tags: ' + ', '.join( + [lt or '' for lt in + filters['analytic_tags']]) + ' Analytic: ' + ', '.join( + [at or '' for at in + filters['analytics']]) + ' Target Moves : ' + filters.get('target_move'), + date_head) + + + sheet.write('A8', 'Code', sub_heading) + sheet.write('B8', 'Amount', sub_heading) + sheet.write('C8', 'Date', sub_heading) + sheet.write('D8', 'JRNL', sub_heading) + sheet.write('E8', 'Partner', sub_heading) + sheet.write('F8', 'Move', sub_heading) + sheet.write('G8', 'Entry Label', sub_heading) + sheet.write('H8', 'Debit', sub_heading) + sheet.write('I8', 'Credit', sub_heading) + sheet.write('J8', 'Balance', sub_heading) + + row = 6 + col = 0 + sheet.set_column(8, 0, 15) + sheet.set_column('B:B', 40) + sheet.set_column(8, 2, 15) + sheet.set_column(8, 3, 15) + sheet.set_column(8, 4, 15) + sheet.set_column(8, 5, 15) + sheet.set_column(8, 6, 50) + sheet.set_column(8, 7, 26) + sheet.set_column(8, 8, 15) + sheet.set_column(8, 9, 15) + + for rec_data in report_data_main: + + row += 1 + sheet.write(row + 1, col, rec_data['code'], txt) + sheet.write(row + 1, col + 1, rec_data['name'], txt) + sheet.write(row + 1, col + 2, '', txt) + sheet.write(row + 1, col + 3, '', txt) + sheet.write(row + 1, col + 4, '', txt) + sheet.write(row + 1, col + 5, '', txt) + sheet.write(row + 1, col + 6, '', txt) + + sheet.write(row + 1, col + 7, rec_data['debit'], txt) + sheet.write(row + 1, col + 8, rec_data['credit'], txt) + sheet.write(row + 1, col + 9, rec_data['balance'], txt) + for line_data in rec_data['move_lines']: + row += 1 + sheet.write(row + 1, col, '', txt) + sheet.write(row + 1, col + 1, '', txt) + sheet.write(row + 1, col + 2, line_data.get('ldate'), txt) + sheet.write(row + 1, col + 3, line_data.get('lcode'), txt) + sheet.write(row + 1, col + 4, line_data.get('partner_name'), txt) + sheet.write(row + 1, col + 5, line_data.get('move_name'), txt) + sheet.write(row + 1, col + 6, line_data.get('lname'), txt) + sheet.write(row + 1, col + 7, line_data.get('debit'), txt) + sheet.write(row + 1, col + 8, line_data.get('credit'), txt) + sheet.write(row + 1, col + 9, line_data.get('balance'), txt) + + + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() \ No newline at end of file diff --git a/dynamic_accounts_report/wizard/partner_leadger.py b/dynamic_accounts_report/wizard/partner_leadger.py new file mode 100644 index 000000000..fa9bd1ea3 --- /dev/null +++ b/dynamic_accounts_report/wizard/partner_leadger.py @@ -0,0 +1,482 @@ +import time +from odoo import fields, models, api, _ + +import io +import json +from odoo.exceptions import AccessError, UserError, AccessDenied +from odoo.http import request +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class PartnerView(models.TransientModel): + _inherit = "account.common.report" + _name = 'account.partner.ledger' + + journal_ids = fields.Many2many('account.journal', + string='Journals', required=True, + default=[]) + account_ids = fields.Many2many( + "account.account", + string="Accounts", check_company=True, + ) + + display_account = fields.Selection( + [('all', 'All'), ('movement', 'With movements'), + ('not_zero', 'With balance is not equal to 0')], + string='Display Accounts', required=True, default='movement') + + partner_ids = fields.Many2many('res.partner', string='Partner') + partner_category_ids = fields.Many2many('res.partner.category', + string='Partner tags') + reconciled = fields.Selection([ + ('unreconciled', 'Unreconciled Only')], + string='Reconcile Type', default='unreconciled') + + account_type_ids = fields.Many2many('account.account.type',string='Account Type', + domain=[('type', 'in', ('receivable', 'payable'))]) + + @api.model + def view_report(self, option): + r = self.env['account.partner.ledger'].search([('id', '=', option[0])]) + data = { + 'display_account': r.display_account, + 'model': self, + 'journals': r.journal_ids, + 'accounts': r.account_ids, + 'target_move': r.target_move, + 'partners': r.partner_ids, + 'reconciled': r.reconciled, + 'account_type': r.account_type_ids, + 'partner_tags': r.partner_category_ids, + } + + if r.date_from: + data.update({ + 'date_from':r.date_from, + }) + if r.date_to: + data.update({ + 'date_to':r.date_to, + }) + + filters = self.get_filter(option) + records = self._get_report_values(data) + currency = self._get_currency() + + return { + 'name': "partner Ledger", + 'type': 'ir.actions.client', + 'tag': 'p_l', + 'filters': filters, + 'report_lines': records['Partners'], + 'debit_total': records['debit_total'], + 'credit_total': records['credit_total'], + 'debit_balance': records['debit_balance'], + 'currency': currency, + } + + def get_current_company_value(self): + + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + def get_filter(self, option): + data = self.get_filter_data(option) + + filters = {} + if data.get('journal_ids'): + filters['journals'] = self.env['account.journal'].browse(data.get('journal_ids')).mapped('code') + else: + filters['journals'] = ['All'] + if data.get('account_ids', []): + filters['accounts'] = self.env['account.account'].browse(data.get('account_ids', [])).mapped('code') + else: + filters['accounts'] = ['All Payable and Receivable'] + if data.get('target_move'): + filters['target_move'] = data.get('target_move').capitalize() + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + if data.get('date_to'): + filters['date_to'] = data.get('date_to') + + filters['company_id'] = '' + filters['accounts_list'] = data.get('accounts_list') + filters['journals_list'] = data.get('journals_list') + + filters['company_name'] = data.get('company_name') + + if data.get('partners'): + filters['partners'] = self.env['res.partner'].browse( + data.get('partners')).mapped('name') + else: + filters['partners'] = ['All'] + + if data.get('reconciled') == 'unreconciled': + filters['reconciled'] = 'Unreconciled' + + if data.get('account_type', []): + filters['account_type'] = self.env['account.account.type'].browse(data.get('account_type', [])).mapped('name') + else: + filters['account_type'] = ['Receivable and Payable'] + + if data.get('partner_tags', []): + filters['partner_tags'] = self.env['res.partner.category'].browse( + data.get('partner_tags', [])).mapped('name') + else: + filters['partner_tags'] = ['All'] + + filters['partners_list'] = data.get('partners_list') + filters['category_list'] = data.get('category_list') + filters['account_type_list'] = data.get('account_type_list') + filters['target_move'] = data.get('target_move').capitalize() + return filters + + def get_filter_data(self, option): + r = self.env['account.partner.ledger'].search([('id', '=', option[0])]) + default_filters = {} + # company_id = self.env.company + company = self.get_current_company_value() + company_id = self.env['res.company'].search([('id', 'in', company)]) + company_domain = [('company_id', 'in', company)] + journals = r.journal_ids if r.journal_ids else self.env['account.journal'].search(company_domain) + company_domain += [('user_type_id.type', 'in', ('receivable', 'payable'))] + accounts = self.account_ids if self.account_ids else self.env['account.account'].search(company_domain) + + partner = r.partner_ids if r.partner_ids else self.env[ + 'res.partner'].search([]) + categories = self.partner_category_ids if self.partner_category_ids \ + else self.env['res.partner.category'].search([]) + account_types = r.account_type_ids if r.account_type_ids \ + else self.env['account.account.type'].search([('type', 'in', ('receivable', 'payable'))]) + + filter_dict = { + 'journal_ids': r.journal_ids.ids, + 'account_ids': r.account_ids.ids, + 'company_id': company_id[0].id, + 'date_from': r.date_from, + 'date_to': r.date_to, + 'target_move': r.target_move, + 'journals_list': [(j.id, j.name, j.code) for j in journals], + 'accounts_list': [(a.id, a.name) for a in accounts], + 'company_name': company_id[0] and company_id[0].name, + 'partners': r.partner_ids.ids, + 'reconciled': r.reconciled, + 'account_type': r.account_type_ids.ids, + 'partner_tags': r.partner_category_ids.ids, + 'partners_list': [(p.id, p.name) for p in partner], + 'category_list': [(c.id, c.name) for c in categories], + 'account_type_list': [(t.id, t.name) for t in account_types], + + } + filter_dict.update(default_filters) + return filter_dict + + def _get_report_values(self, data): + docs = data['model'] + display_account = data['display_account'] + init_balance = True + company = self.get_current_company_value() + company_id = self.env['res.company'].search([('id', 'in', company)]) + accounts = self.env['account.account'].search([('user_type_id.type', 'in', ('receivable', 'payable')), + ('company_id', 'in', company)]) + if data['account_type']: + accounts = self.env['account.account'].search( + [('user_type_id.id', 'in', data['account_type'].ids), ('company_id', '=', company_id.id)]) + + partners = self.env['res.partner'].search([]) + + if data['partner_tags']: + partners = self.env['res.partner'].search( + [('category_id', 'in', data['partner_tags'].ids)]) + if not accounts: + raise UserError(_("No Accounts Found! Please Add One")) + partner_res = self._get_partners(partners, accounts, init_balance, display_account, data) + + debit_total = 0 + debit_total = sum(x['debit'] for x in partner_res) + credit_total = sum(x['credit'] for x in partner_res) + debit_balance = round(debit_total,2) - round(credit_total,2) + return { + 'doc_ids': self.ids, + 'debit_total': debit_total, + 'credit_total': credit_total, + 'debit_balance':debit_balance, + 'docs': docs, + 'time': time, + 'Partners': partner_res, + } + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(PartnerView, self).create(vals) + return res + + def write(self, vals): + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + if vals.get('journal_ids'): + vals.update({'journal_ids': [(6, 0, vals.get('journal_ids'))]}) + if not vals.get('journal_ids'): + vals.update({'journal_ids': [(5,)]}) + if vals.get('account_ids'): + vals.update({'account_ids': [(4, j) for j in vals.get('account_ids')]}) + if not vals.get('account_ids'): + vals.update({'account_ids': [(5,)]}) + if vals.get('partner_ids'): + vals.update( + {'partner_ids': [(4, j) for j in vals.get('partner_ids')]}) + if not vals.get('partner_ids'): + vals.update({'partner_ids': [(5,)]}) + if vals.get('partner_category_ids'): + vals.update({'partner_category_ids': [(4, j) for j in vals.get( + 'partner_category_ids')]}) + if not vals.get('partner_category_ids'): + vals.update({'partner_category_ids': [(5,)]}) + + if vals.get('account_type-ids'): + vals.update( + {'account_type_ids': [(4, j) for j in vals.get('account_type_ids')]}) + if not vals.get('account_type_ids'): + vals.update({'account_type_ids': [(5,)]}) + + res = super(PartnerView, self).write(vals) + return res + + def _get_partners(self, partners, accounts, init_balance, display_account, data): + + cr = self.env.cr + move_line = self.env['account.move.line'] + move_lines = {x: [] for x in partners.ids} + currency_id = self.env.company.currency_id + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + tables, where_clause, where_params = move_line._query_get() + where_params[0] = int(company_id.id) + wheres = [""] + if where_clause.strip(): + wheres.append(where_clause.strip()) + final_filters = " AND ".join(wheres) + final_filters = final_filters.replace('account_move_line__move_id', 'm').replace( + 'account_move_line', 'l') + new_final_filter = final_filters + if data['target_move'] == 'posted': + new_final_filter += " AND m.state = 'posted'" + else: + new_final_filter += " AND m.state in ('draft','posted')" + if data.get('date_from'): + new_final_filter += " AND l.date >= '%s'" % data.get('date_from') + if data.get('date_to'): + new_final_filter += " AND l.date <= '%s'" % data.get('date_to') + + if data['journals']: + new_final_filter += ' AND j.id IN %s' % str(tuple(data['journals'].ids) + tuple([0])) + + if data.get('accounts'): + WHERE = "WHERE l.account_id IN %s" % str(tuple(data.get('accounts').ids) + tuple([0])) + else: + WHERE = "WHERE l.account_id IN %s" + + if data.get('partners'): + WHERE += ' AND p.id IN %s' % str( + tuple(data.get('partners').ids) + tuple([0])) + + if data.get('reconciled') == 'unreconciled': + WHERE += ' AND l.full_reconcile_id is null AND' \ + ' l.balance != 0 AND a.reconcile is true' + + sql = ('''SELECT l.id AS lid,l.partner_id AS partner_id,m.id AS move_id, + l.account_id AS account_id, l.date AS ldate, j.code AS lcode, l.currency_id, + l.amount_currency, l.ref AS lref, l.name AS lname, + COALESCE(l.debit,0) AS debit, COALESCE(l.credit,0) AS credit, + COALESCE(SUM(l.balance),0) AS balance,\ + m.name AS move_name, c.symbol AS currency_code,c.position AS currency_position, p.name AS partner_name\ + FROM account_move_line l\ + JOIN account_move m ON (l.move_id=m.id)\ + JOIN account_account a ON (l.account_id=a.id) + LEFT JOIN res_currency c ON (l.currency_id=c.id)\ + LEFT JOIN res_partner p ON (l.partner_id=p.id)\ + JOIN account_journal j ON (l.journal_id=j.id)\ + JOIN account_account acc ON (l.account_id = acc.id) ''' + + WHERE + new_final_filter + ''' GROUP BY l.id, m.id, l.account_id, l.date, j.code, l.currency_id, l.amount_currency, l.ref, l.name, m.name, c.symbol, c.position, p.name''' ) + if data.get('accounts'): + params = tuple(where_params) + else: + params = (tuple(accounts.ids),) + tuple(where_params) + cr.execute(sql, params) + + account_list = {x.id: {'name': x.name, 'code': x.code} for x in accounts} + for row in cr.dictfetchall(): + balance = 0 + if row['partner_id'] in move_lines: + for line in move_lines.get(row['partner_id']): + balance += round(line['debit'],2) - round(line['credit'],2) + row['balance'] += (round(balance, 2)) + row['m_id'] = row['account_id'] + row['account_name'] = account_list[row['account_id']]['name'] + "(" +account_list[row['account_id']]['code'] + ")" + move_lines[row.pop('partner_id')].append(row) + + partner_res = [] + for partner in partners: + # company_id = self.env.company + company = self.get_current_company_value() + company_id = self.env['res.company'].search([('id', 'in', company)]) + currency = company_id.currency_id + res = dict((fn, 0.0) for fn in ['credit', 'debit', 'balance']) + res['name'] = partner.name + res['id'] = partner.id + res['move_lines'] = move_lines[partner.id] + for line in res.get('move_lines'): + res['debit'] += round(line['debit'], 2) + res['credit'] += round(line['credit'], 2) + res['balance'] = round(line['balance'], 2) + if display_account == 'all': + partner_res.append(res) + if display_account == 'movement' and res.get('move_lines'): + partner_res.append(res) + if display_account == 'not_zero' and not currency.is_zero( + res['balance']): + partner_res.append(res) + return partner_res + + @api.model + def _get_currency(self): + company = self.get_current_company_value() + company_id = self.env['res.company'].search([('id', 'in', company)]) + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position, lang] + currency_array = [company_id[0].currency_id.symbol, + company_id[0].currency_id.position, lang] + return currency_array + + def get_dynamic_xlsx_report(self, data, response, report_data, dfr_data): + report_data = json.loads(report_data) + filters = json.loads(data) + + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + cell_format = workbook.add_format( + {'align': 'center', 'bold': True, + 'border': 0 + }) + sheet = workbook.add_worksheet() + head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '20px'}) + + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + sub_heading_sub = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + sheet.merge_range('A1:H2', + filters.get('company_name') + ':' + 'Partner Ledger', + head) + date_head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '10px'}) + + sheet.merge_range('A4:B4', + 'Target Moves: ' + filters.get('target_move'), + date_head) + + sheet.merge_range('C4:D4', 'Account Type: ' + ', ' .join( + [lt or '' for lt in + filters['account_type']]), + date_head) + sheet.merge_range('E3:F3', ' Partners: ' + ', '.join( + [lt or '' for lt in + filters['partners']]), date_head) + sheet.merge_range('G3:H3', ' Partner Tags: ' + ', '.join( + [lt or '' for lt in + filters['partner_tags']]), + date_head) + sheet.merge_range('A3:B3', ' Journals: ' + ', '.join( + [lt or '' for lt in + filters['journals']]), + date_head) + sheet.merge_range('C3:D3', ' Accounts: ' + ', '.join( + [lt or '' for lt in + filters['accounts']]), + date_head) + + if filters.get('date_from') and filters.get('date_to'): + sheet.merge_range('E4:F4', 'From: ' + filters.get('date_from'), + date_head) + + sheet.merge_range('G4:H4', 'To: ' + filters.get('date_to'), + date_head) + elif filters.get('date_from'): + sheet.merge_range('E4:F4', 'From: ' + filters.get('date_from'), + date_head) + elif filters.get('date_to'): + sheet.merge_range('E4:F4', 'To: ' + filters.get('date_to'), + date_head) + + sheet.merge_range('A5:E5', 'Partner', cell_format) + sheet.write('F5', 'Debit', cell_format) + sheet.write('G5', 'Credit', cell_format) + sheet.write('H5', 'Balance', cell_format) + + row = 4 + col = 0 + + sheet.set_column(0, 0, 15) + sheet.set_column(1, 1, 15) + sheet.set_column(2, 2, 25) + sheet.set_column(3, 3, 15) + sheet.set_column(4, 4, 36) + sheet.set_column(5, 5, 15) + sheet.set_column(6, 6, 15) + sheet.set_column(7, 7, 15) + + for report in report_data: + + row += 1 + sheet.merge_range(row, col + 0, row, col + 4, report['name'], + sub_heading_sub) + sheet.write(row, col + 5, report['debit'], sub_heading_sub) + sheet.write(row, col + 6, report['credit'], sub_heading_sub) + sheet.write(row, col + 7, report['balance'], sub_heading_sub) + row += 1 + sheet.write(row, col + 0, 'Date', cell_format) + sheet.write(row, col + 1, 'JRNL', cell_format) + sheet.write(row, col + 2, 'Account', cell_format) + sheet.write(row, col + 3, 'Move', cell_format) + sheet.write(row, col + 4, 'Entry Label', cell_format) + sheet.write(row, col + 5, 'Debit', cell_format) + sheet.write(row, col + 6, 'Credit', cell_format) + sheet.write(row, col + 7, 'Balance', cell_format) + for r_rec in report['move_lines']: + row += 1 + sheet.write(row, col + 0, r_rec['ldate'], txt) + sheet.write(row, col + 1, r_rec['lcode'], txt) + sheet.write(row, col + 2, r_rec['account_name'], txt) + sheet.write(row, col + 3, r_rec['move_name'], txt) + sheet.write(row, col + 4, r_rec['lname'], txt) + sheet.write(row, col + 5, r_rec['debit'], txt) + sheet.write(row, col + 6, r_rec['credit'], txt) + sheet.write(row, col + 7, r_rec['balance'], txt) + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() diff --git a/dynamic_accounts_report/wizard/trial_balance.py b/dynamic_accounts_report/wizard/trial_balance.py new file mode 100644 index 000000000..14ef1db51 --- /dev/null +++ b/dynamic_accounts_report/wizard/trial_balance.py @@ -0,0 +1,355 @@ +import time +from odoo import fields, models, api, _ + +import io +import json +from odoo.http import request +from odoo.exceptions import AccessError, UserError, AccessDenied + +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class TrialView(models.TransientModel): + _inherit = "account.common.report" + _name = 'account.trial.balance' + _check_company_auto = True + + journal_ids = fields.Many2many('account.journal', + + string='Journals', required=True, + default=[]) + company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env['res.company']._company_default_get( + 'account.trial.balance')) + display_account = fields.Selection( + [('all', 'All'), ('movement', 'With movements'), + ('not_zero', 'With balance is not equal to 0')], + string='Display Accounts', required=True, default='movement') + + @api.model + def view_report(self, option): + r = self.env['account.trial.balance'].search([('id', '=', option[0])]) + + data = { + 'display_account': r.display_account, + 'model': self, + 'journals': r.journal_ids, + 'target_move': r.target_move, + + } + if r.date_from: + data.update({ + 'date_from':r.date_from, + }) + if r.date_to: + data.update({ + 'date_to':r.date_to, + }) + + filters = self.get_filter(option) + records = self._get_report_values(data) + currency = self._get_currency() + + return { + 'name': "Trial Balance", + 'type': 'ir.actions.client', + 'tag': 't_b', + 'filters': filters, + 'report_lines': records['Accounts'], + 'debit_total': records['debit_total'], + 'credit_total': records['credit_total'], + 'currency': currency, + } + + def get_filter(self, option): + data = self.get_filter_data(option) + filters = {} + if data.get('journal_ids'): + filters['journals'] = self.env['account.journal'].browse(data.get('journal_ids')).mapped('code') + else: + filters['journals'] = ['All'] + if data.get('target_move'): + filters['target_move'] = data.get('target_move') + if data.get('date_from'): + filters['date_from'] = data.get('date_from') + if data.get('date_to'): + filters['date_to'] = data.get('date_to') + + filters['company_id'] = '' + filters['journals_list'] = data.get('journals_list') + filters['company_name'] = data.get('company_name') + filters['target_move'] = data.get('target_move').capitalize() + + return filters + + def get_filter_data(self, option): + r = self.env['account.trial.balance'].search([('id', '=', option[0])]) + default_filters = {} + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + # company_id = self.env.company + company_domain = [('company_id', '=', company_id.id)] + journals = r.journal_ids if r.journal_ids else self.env['account.journal'].search(company_domain) + + filter_dict = { + 'journal_ids': r.journal_ids.ids, + 'company_id': company_id.id, + 'date_from': r.date_from, + 'date_to': r.date_to, + 'target_move': r.target_move, + 'journals_list': [(j.id, j.name, j.code) for j in journals], + 'company_name': company_id and company_id.name, + } + filter_dict.update(default_filters) + return filter_dict + + def get_current_company_value(self): + + cookies_cids = [int(r) for r in request.httprequest.cookies.get('cids').split(",")] \ + if request.httprequest.cookies.get('cids') \ + else [request.env.user.company_id.id] + for company_id in cookies_cids: + if company_id not in self.env.user.company_ids.ids: + cookies_cids.remove(company_id) + if not cookies_cids: + cookies_cids = [self.env.company.id] + if len(cookies_cids) == 1: + cookies_cids.append(0) + return cookies_cids + + def _get_report_values(self, data): + docs = data['model'] + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + company_domain = [('company_id', '=', company_id.id)] + display_account = data['display_account'] + journals = data['journals'] + # accounts = self.env['account.account'].search([]) + accounts = self.env['account.account'].search(company_domain) + if not accounts: + raise UserError(_("No Accounts Found! Please Add One")) + account_res = self._get_accounts(accounts, display_account, data) + debit_total = 0 + debit_total = sum(x['debit'] for x in account_res) + credit_total = sum(x['credit'] for x in account_res) + return { + 'doc_ids': self.ids, + 'debit_total': debit_total, + 'credit_total': credit_total, + 'docs': docs, + 'time': time, + 'Accounts': account_res, + } + + @api.model + def create(self, vals): + vals['target_move'] = 'posted' + res = super(TrialView, self).create(vals) + return res + + def write(self, vals): + if vals.get('target_move'): + vals.update({'target_move': vals.get('target_move').lower()}) + if vals.get('journal_ids'): + vals.update({'journal_ids': [(6, 0, vals.get('journal_ids'))]}) + if vals.get('journal_ids') == []: + vals.update({'journal_ids': [(5,)]}) + res = super(TrialView, self).write(vals) + return res + + def _get_accounts(self, accounts, display_account, data): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + account_result = {} + # Prepare sql query base on selected parameters from wizard + tables, where_clause, where_params = self.env['account.move.line']._query_get() + where_params[0] = int(company_id.id) + tables = tables.replace('"', '') + if not tables: + tables = 'account_move_line' + wheres = [""] + if where_clause.strip(): + wheres.append(where_clause.strip()) + filters = " AND ".join(wheres) + if data['target_move'] == 'posted': + filters += " AND account_move_line__move_id.state = 'posted'" + else: + filters += " AND account_move_line__move_id.state in ('draft','posted')" + if data.get('date_from'): + filters += " AND account_move_line.date >= '%s'" % data.get('date_from') + if data.get('date_to'): + filters += " AND account_move_line.date <= '%s'" % data.get('date_to') + + if data['journals']: + filters += ' AND jrnl.id IN %s' % str(tuple(data['journals'].ids) + tuple([0])) + tables += 'JOIN account_journal jrnl ON (account_move_line.journal_id=jrnl.id)' + # compute the balance, debit and credit for the provided accounts + request = ( + "SELECT account_id AS id, SUM(debit) AS debit, SUM(credit) AS credit, (SUM(debit) - SUM(credit)) AS balance" + \ + " FROM " + tables + " WHERE account_id IN %s " + filters + " GROUP BY account_id") + params = (tuple(accounts.ids),) + tuple(where_params) + self.env.cr.execute(request, params) + for row in self.env.cr.dictfetchall(): + account_result[row.pop('id')] = row + + account_res = [] + for account in accounts: + res = dict((fn, 0.0) for fn in ['credit', 'debit', 'balance']) + currency = account.currency_id and account.currency_id or account.company_id.currency_id + res['code'] = account.code + res['name'] = account.name + res['id'] = account.id + if data.get('date_from'): + + res['Init_balance'] = self.get_init_bal(account, display_account, data) + + if account.id in account_result: + res['debit'] = account_result[account.id].get('debit') + res['credit'] = account_result[account.id].get('credit') + res['balance'] = account_result[account.id].get('balance') + if display_account == 'all': + account_res.append(res) + if display_account == 'not_zero' and not currency.is_zero( + res['balance']): + account_res.append(res) + if display_account == 'movement' and ( + not currency.is_zero(res['debit']) or not currency.is_zero( + res['credit'])): + account_res.append(res) + return account_res + + def get_init_bal(self, account, display_account, data): + if data.get('date_from'): + + tables, where_clause, where_params = self.env[ + 'account.move.line']._query_get() + tables = tables.replace('"', '') + if not tables: + tables = 'account_move_line' + wheres = [""] + if where_clause.strip(): + wheres.append(where_clause.strip()) + filters = " AND ".join(wheres) + if data['target_move'] == 'posted': + filters += " AND account_move_line__move_id.state = 'posted'" + else: + filters += " AND account_move_line__move_id.state in ('draft','posted')" + if data.get('date_from'): + filters += " AND account_move_line.date < '%s'" % data.get('date_from') + + if data['journals']: + filters += ' AND jrnl.id IN %s' % str(tuple(data['journals'].ids) + tuple([0])) + tables += 'JOIN account_journal jrnl ON (account_move_line.journal_id=jrnl.id)' + + # compute the balance, debit and credit for the provided accounts + request = ( + "SELECT account_id AS id, SUM(debit) AS debit, SUM(credit) AS credit, (SUM(debit) - SUM(credit)) AS balance" + \ + " FROM " + tables + " WHERE account_id = %s" % account.id + filters + " GROUP BY account_id") + params = tuple(where_params) + self.env.cr.execute(request, params) + for row in self.env.cr.dictfetchall(): + return row + + @api.model + def _get_currency(self): + company = self.get_current_company_value()[0] + company_id = self.env['res.company'].search([('id', '=', int(company))]) + journal = self.env['account.journal'].browse( + self.env.context.get('default_journal_id', False)) + if journal.currency_id: + return journal.currency_id.id + lang = self.env.user.lang + if not lang: + lang = 'en_US' + lang = lang.replace("_", '-') + # currency_array = [self.env.company.currency_id.symbol, + # self.env.company.currency_id.position, + # lang] + currency_array = [company_id.currency_id.symbol, + company_id.currency_id.position, + lang] + return currency_array + + def get_dynamic_xlsx_report(self, data, response ,report_data, dfr_data): + report_data_main = json.loads(report_data) + output = io.BytesIO() + total = json.loads(dfr_data) + filters = json.loads(data) + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + sheet = workbook.add_worksheet() + head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '20px'}) + sub_heading = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '10px', + 'border': 1, + 'border_color': 'black'}) + txt = workbook.add_format({'font_size': '10px', 'border': 1}) + txt_l = workbook.add_format({'font_size': '10px', 'border': 1, 'bold': True}) + sheet.merge_range('A2:D3', filters.get('company_name') + ':' + ' Trial Balance', head) + date_head = workbook.add_format({'align': 'center', 'bold': True, + 'font_size': '10px'}) + date_style = workbook.add_format({'align': 'center', + 'font_size': '10px'}) + if filters.get('date_from'): + sheet.merge_range('A4:B4', 'From: '+filters.get('date_from') , date_head) + if filters.get('date_to'): + sheet.merge_range('C4:D4', 'To: '+ filters.get('date_to'), date_head) + sheet.merge_range('A5:D6', 'Journals: ' + ', '.join([ lt or '' for lt in filters['journals'] ]) + ' Target Moves: '+ filters.get('target_move'), date_head) + sheet.write('A7', 'Code', sub_heading) + sheet.write('B7', 'Amount', sub_heading) + if filters.get('date_from'): + sheet.write('C7', 'Initial Debit', sub_heading) + sheet.write('D7', 'Initial Credit', sub_heading) + sheet.write('E7', 'Debit', sub_heading) + sheet.write('F7', 'Credit', sub_heading) + else: + sheet.write('C7', 'Debit', sub_heading) + sheet.write('D7', 'Credit', sub_heading) + + row = 6 + col = 0 + sheet.set_column(5, 0, 15) + sheet.set_column(6, 1, 15) + sheet.set_column(7, 2, 26) + if filters.get('date_from'): + sheet.set_column(8, 3, 15) + sheet.set_column(9, 4, 15) + sheet.set_column(10, 5, 15) + sheet.set_column(11, 6, 15) + else: + + sheet.set_column(8, 3, 15) + sheet.set_column(9, 4, 15) + for rec_data in report_data_main: + + row += 1 + sheet.write(row, col, rec_data['code'], txt) + sheet.write(row, col + 1, rec_data['name'], txt) + if filters.get('date_from'): + if rec_data.get('Init_balance'): + sheet.write(row, col + 2, rec_data['Init_balance']['debit'], txt) + sheet.write(row, col + 3, rec_data['Init_balance']['credit'], txt) + else: + sheet.write(row, col + 2, 0, txt) + sheet.write(row, col + 3, 0, txt) + + sheet.write(row, col + 4, rec_data['debit'], txt) + sheet.write(row, col + 5, rec_data['credit'], txt) + + else: + sheet.write(row, col + 2, rec_data['debit'], txt) + sheet.write(row, col + 3, rec_data['credit'], txt) + sheet.write(row+1, col, 'Total', sub_heading) + if filters.get('date_from'): + sheet.write(row + 1, col + 4, total.get('debit_total'), txt_l) + sheet.write(row + 1, col + 5, total.get('credit_total'), txt_l) + else: + sheet.write(row + 1, col + 2, total.get('debit_total'), txt_l) + sheet.write(row + 1, col + 3, total.get('credit_total'), txt_l) + + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close()