summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 17:13:41 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 17:13:41 +0700
commit444049320b8e2411a0cf688f61adfa999a792b00 (patch)
tree938f2517a090a5bdcafd5675da6764216851e460
parent011dbe0390d3263a94c53656b5fb21d10b901fa3 (diff)
initial commitHEADmaster
-rwxr-xr-xaddons/account_reports_xlsx/README.rst19
-rwxr-xr-xaddons/account_reports_xlsx/__init__.py26
-rwxr-xr-xaddons/account_reports_xlsx/__manifest__.py53
-rwxr-xr-xaddons/account_reports_xlsx/controllers/__init__.py23
-rwxr-xr-xaddons/account_reports_xlsx/controllers/main.py56
-rwxr-xr-xaddons/account_reports_xlsx/doc/RELEASE_NOTES.md6
-rwxr-xr-xaddons/account_reports_xlsx/models/__init__.py26
-rwxr-xr-xaddons/account_reports_xlsx/models/account_aged_partner_balance.py266
-rwxr-xr-xaddons/account_reports_xlsx/models/account_financial_report.py91
-rwxr-xr-xaddons/account_reports_xlsx/models/account_general_ledger.py156
-rwxr-xr-xaddons/account_reports_xlsx/models/account_partner_ledger.py151
-rwxr-xr-xaddons/account_reports_xlsx/report/__init__.py1
-rwxr-xr-xaddons/account_reports_xlsx/report/account_aged_partner_balance.py261
-rwxr-xr-xaddons/account_reports_xlsx/security/ir.model.access.csv7
-rwxr-xr-xaddons/account_reports_xlsx/static/description/banner.pngbin0 -> 49617 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/icon.pngbin0 -> 15233 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/Accounting Reports in Excel.pngbin0 -> 118352 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_Report_2.pngbin0 -> 45909 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_report.pngbin0 -> 35854 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_report_3.pngbin0 -> 39464 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_report_6.pngbin0 -> 47052 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_report_7.pngbin0 -> 28114 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_report_8.pngbin0 -> 55753 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/account_report_9.pngbin0 -> 37960 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/accounting-report.gifbin0 -> 3921987 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/accounting_report_4.pngbin0 -> 99203 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/accounting_report_5.pngbin0 -> 37366 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/bank_book.pngbin0 -> 114348 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/banner.pngbin0 -> 127361 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/cash_book.jpegbin0 -> 148633 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/checked.pngbin0 -> 15093 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/cybrosys.pngbin0 -> 52522 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/day_book_report.pngbin0 -> 135936 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/dynamic_financial_report.pngbin0 -> 114408 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/full_accounting_kit.gifbin0 -> 266897 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/images/project_report.pngbin0 -> 92918 bytes
-rwxr-xr-xaddons/account_reports_xlsx/static/description/index.html402
-rwxr-xr-xaddons/account_reports_xlsx/static/src/js/action_manager.js52
-rwxr-xr-xaddons/account_reports_xlsx/views/account_financial_report_data.xml71
-rwxr-xr-xaddons/account_reports_xlsx/views/action_manager.xml9
-rwxr-xr-xaddons/account_reports_xlsx/views/financial_report_wizard_view.xml16
-rwxr-xr-xaddons/account_reports_xlsx/views/financial_report_xls_view.xml15
-rwxr-xr-xaddons/account_reports_xlsx/views/general_ledger_report_view.xml15
-rwxr-xr-xaddons/account_reports_xlsx/views/general_ledger_report_wizard_view.xml15
-rwxr-xr-xaddons/account_reports_xlsx/views/partner_ledgerreport.xml96
-rwxr-xr-xaddons/account_reports_xlsx/views/report.xml17
-rwxr-xr-xaddons/account_reports_xlsx/views/report_agedpartnerbalance.xml95
-rwxr-xr-xaddons/account_reports_xlsx/views/supplier_aging_report_view.xml85
-rwxr-xr-xaddons/account_reports_xlsx/wizard/__init__.py27
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_financial_report.py245
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_financial_report_view.xml63
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_report_aged_partner_balance.py209
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_report_aged_partner_balance_view.xml42
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_report_financial.py181
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_report_general_ledger.py240
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_report_general_ledger_view.xml39
-rwxr-xr-xaddons/account_reports_xlsx/wizard/account_report_partner_ledger.py265
-rwxr-xr-xaddons/account_reports_xlsx/wizard/partner_ledger_wizard_view.xml63
-rw-r--r--addons/banner_sale/__init__.py1
-rw-r--r--addons/banner_sale/__manifest__.py22
-rw-r--r--addons/banner_sale/models/__init__.py4
-rw-r--r--addons/banner_sale/models/banner.py16
-rw-r--r--addons/banner_sale/models/banner_category.py11
-rw-r--r--addons/banner_sale/models/coupon_program.py10
-rw-r--r--addons/banner_sale/models/product_brand.py10
-rw-r--r--addons/banner_sale/security/ir.model.access.csv3
-rw-r--r--addons/banner_sale/views/banner.xml61
-rw-r--r--addons/banner_sale/views/banner_category.xml53
-rw-r--r--addons/banner_sale/views/product_brand.xml26
-rw-r--r--addons/mail_reply_to_sender/__init__.py3
-rw-r--r--addons/mail_reply_to_sender/__manifest__.py22
-rw-r--r--addons/mail_reply_to_sender/models/__init__.py2
-rw-r--r--addons/mail_reply_to_sender/models/ir_mail_server.py16
-rw-r--r--addons/mail_reply_to_sender/static/description/banner.pngbin0 -> 232656 bytes
-rw-r--r--addons/mail_reply_to_sender/static/description/icon.pngbin0 -> 46313 bytes
-rw-r--r--addons/mail_reply_to_sender/static/description/index.html87
-rw-r--r--addons/mail_reply_to_sender/static/description/mail_reply_to_1.pngbin0 -> 59383 bytes
-rw-r--r--addons/mail_reply_to_sender/static/description/mail_reply_to_2.pngbin0 -> 47181 bytes
-rw-r--r--addons/mail_reply_to_sender/static/description/ppts/odoo-erp-customization.svg1
-rw-r--r--addons/mail_reply_to_sender/static/description/ppts/odoo-erp-implementation.svg1
-rw-r--r--addons/mail_reply_to_sender/static/description/ppts/odoo-erp-integration.svg1
-rw-r--r--addons/mail_reply_to_sender/static/description/ppts/odoo-erp-migration.svg1
-rw-r--r--addons/mail_reply_to_sender/static/description/ppts/odoo-erp-support.svg1
-rw-r--r--addons/mail_reply_to_sender/static/description/reply_to.pngbin0 -> 27416 bytes
-rw-r--r--addons/product_brand_sale/README.md32
-rw-r--r--addons/product_brand_sale/__init__.py1
-rw-r--r--addons/product_brand_sale/__manifest__.py41
-rw-r--r--addons/product_brand_sale/doc/RELEASE_NOTES.md6
-rw-r--r--addons/product_brand_sale/models/__init__.py1
-rw-r--r--addons/product_brand_sale/models/brand.py36
-rw-r--r--addons/product_brand_sale/security/ir.model.access.csv2
-rw-r--r--addons/product_brand_sale/static/description/banner.pngbin0 -> 82897 bytes
-rw-r--r--addons/product_brand_sale/static/description/icon.pngbin0 -> 20776 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/1.jpegbin0 -> 72086 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/2.jpegbin0 -> 86978 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/3.jpegbin0 -> 67289 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/4.jpegbin0 -> 65042 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/5.jpegbin0 -> 154945 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/6.jpegbin0 -> 141285 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/checked.pngbin0 -> 15093 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/cybrosys.pngbin0 -> 52522 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand1.pngbin0 -> 263911 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand2.pngbin0 -> 38326 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand3.pngbin0 -> 80188 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand4.pngbin0 -> 288265 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand5.pngbin0 -> 234664 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand6.pngbin0 -> 68786 bytes
-rw-r--r--addons/product_brand_sale/static/description/images/productbrand7.pngbin0 -> 56021 bytes
-rw-r--r--addons/product_brand_sale/static/description/index.html327
-rw-r--r--addons/product_brand_sale/views/brand_views.xml108
110 files changed, 4310 insertions, 0 deletions
diff --git a/addons/account_reports_xlsx/README.rst b/addons/account_reports_xlsx/README.rst
new file mode 100755
index 0000000..fec390b
--- /dev/null
+++ b/addons/account_reports_xlsx/README.rst
@@ -0,0 +1,19 @@
+Accounting Reports xlsx v14
+===========================
+Shows the Accounting Reports Excel
+
+Installation
+============
+ - www.odoo.com/documentation/14.0/setup/install.html
+ - Install our custom addon
+
+Configuration
+=============
+
+ No additional configurations needed
+
+Credits
+=======
+ Developer V12: Risha C.T @ cybrosys
+ Migrated V13: Varsha Vivek K @ cybrosys
+ Migrated V14: Saurabh @ cybrosys
diff --git a/addons/account_reports_xlsx/__init__.py b/addons/account_reports_xlsx/__init__.py
new file mode 100755
index 0000000..a7428e0
--- /dev/null
+++ b/addons/account_reports_xlsx/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies(odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from . import report
+from . import controllers
+from . import models
+from . import wizard
diff --git a/addons/account_reports_xlsx/__manifest__.py b/addons/account_reports_xlsx/__manifest__.py
new file mode 100755
index 0000000..9a821cf
--- /dev/null
+++ b/addons/account_reports_xlsx/__manifest__.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+{
+ 'name': 'Accounting Report Excel',
+ 'version': '14.0.1.0.0',
+ 'author': 'Cybrosys Techno Solutions',
+ 'website': "https://www.cybrosys.com",
+ 'category': 'Accounting',
+ 'live_test_url': 'https://www.youtube.com/watch?v=Sch1VcrunT0&list=PLeJtXzTubzj_wOC0fzgSAyGln4TJWKV4k&index=33',
+ 'summary': """Generates Excel report for Partner Ledger,General Ledger,Balance Sheet,
+ Profit and Loss,Aged Partner Balance.""",
+ 'description': """Generates Excel reports,
+ Accounting Reports, Odoo 14, Odoo 14 report,Odoo 14 Accounting Report,Odoo 14 Excel Report, Partner Profit and Loss,Aged Partner Balance,Ledger,General Ledger,Balance Sheet,Account Reports, Excel Report, Excel, Xlsx Report, xlsx,Accounting Excel Reports, Account Excel Reports""",
+ 'depends': ['base', 'account'],
+ 'data': [
+ 'views/action_manager.xml',
+ 'security/ir.model.access.csv',
+ 'views/report_agedpartnerbalance.xml',
+ 'wizard/partner_ledger_wizard_view.xml',
+ 'views/partner_ledgerreport.xml',
+ 'wizard/account_report_aged_partner_balance_view.xml',
+ 'wizard/account_report_general_ledger_view.xml',
+ 'wizard/account_financial_report_view.xml',
+ 'views/account_financial_report_data.xml',
+ ],
+ 'license': 'OPL-1',
+ 'price': 19.99,
+ 'currency': 'EUR',
+ 'images': ['static/description/banner.png'],
+ 'auto_install': False,
+ 'installable': True,
+ 'application': True,
+}
diff --git a/addons/account_reports_xlsx/controllers/__init__.py b/addons/account_reports_xlsx/controllers/__init__.py
new file mode 100755
index 0000000..593cba3
--- /dev/null
+++ b/addons/account_reports_xlsx/controllers/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from . import main
diff --git a/addons/account_reports_xlsx/controllers/main.py b/addons/account_reports_xlsx/controllers/main.py
new file mode 100755
index 0000000..3a886bf
--- /dev/null
+++ b/addons/account_reports_xlsx/controllers/main.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+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 XLSXReportController(http.Controller):
+
+ @http.route('/xlsx_reports', type='http', auth='user', methods=['POST'], csrf=False)
+ def get_report_xlsx(self, model, options, output_format, token, report_name, **kw):
+ uid = request.session.uid
+ report_obj = request.env[model].with_user(uid)
+ options = json.loads(options)
+ 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_xlsx_report(options, response)
+ 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))) \ No newline at end of file
diff --git a/addons/account_reports_xlsx/doc/RELEASE_NOTES.md b/addons/account_reports_xlsx/doc/RELEASE_NOTES.md
new file mode 100755
index 0000000..50d36c1
--- /dev/null
+++ b/addons/account_reports_xlsx/doc/RELEASE_NOTES.md
@@ -0,0 +1,6 @@
+## Module <account_reports_xlsx>
+
+#### 30.10.2020
+##### Version 14.0.1.0.0
+###### ADD
+- Initial commit for Accounting Reports Excel \ No newline at end of file
diff --git a/addons/account_reports_xlsx/models/__init__.py b/addons/account_reports_xlsx/models/__init__.py
new file mode 100755
index 0000000..f7265a3
--- /dev/null
+++ b/addons/account_reports_xlsx/models/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from . import account_partner_ledger
+from . import account_aged_partner_balance
+from . import account_general_ledger
+from . import account_financial_report
diff --git a/addons/account_reports_xlsx/models/account_aged_partner_balance.py b/addons/account_reports_xlsx/models/account_aged_partner_balance.py
new file mode 100755
index 0000000..1f6eef7
--- /dev/null
+++ b/addons/account_reports_xlsx/models/account_aged_partner_balance.py
@@ -0,0 +1,266 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+import time
+from odoo import api, models, _
+from odoo.exceptions import UserError
+from odoo.tools import float_is_zero
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
+
+
+class ReportAgedPartnerBalance(models.AbstractModel):
+
+ _inherit = 'report.account_reports_xlsx.report_agedpartnerbalance'
+
+ def _get_partner_move_lines(self, account_type, date_from, target_move, period_length):
+ # This method can receive the context key 'include_nullified_amount' {Boolean}
+ # Do an invoice and a payment and unreconcile. The amount will be nullified
+ # By default, the partner wouldn't appear in this report.
+ # The context key allow it to appear
+ # In case of a period_length of 30 days as of 2020-02-08, we want the following periods:
+ # Name Stop Start
+ # 1 - 30 : 2020-02-07 - 2020-01-09
+ # 31 - 60 : 2020-01-08 - 2018-12-10
+ # 61 - 90 : 2018-12-09 - 2018-11-10
+ # 91 - 120 : 2018-11-09 - 2018-10-11
+ # +120 : 2018-10-10
+ periods = {}
+ if date_from is False:
+ raise UserError(_("You must set a start date"))
+ start = datetime.strptime(str(date_from), "%Y-%m-%d")
+ 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
+ user_company = self.env.user.company_id
+ 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]
+ move_state = ['draft', 'posted']
+ if target_move == 'posted':
+ move_state = ['posted']
+ arg_list = (tuple(move_state), tuple(account_type))
+ #build the reconciliation clause to see what partner needs to be printed
+ 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))
+ 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
+ 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
+ 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 str(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 str(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.user.company_id.currency_id.is_zero(line_amount):
+ undue_amounts[partner_id] += line_amount
+ lines[partner_id].append({
+ 'line': line,
+ 'amount': line_amount,
+ 'period': 6,
+ })
+
+ # Use one query per period and store results in history (a list variable)
+ # Each history will contain: history[1] = {'<partner_id>': <partner_debit-credit>}
+ 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).with_context(prefetch_fields=False):
+ partner_id = line.partner_id.id or False
+ 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 str(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 str(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.user.company_id.currency_id.is_zero(line_amount):
+ partners_amount[partner_id] += line_amount
+ lines[partner_id].append({
+ 'line': line,
+ 'amount': line_amount,
+ 'period': i + 1,
+ })
+ 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
+ if not float_is_zero(values['direction'], precision_rounding=self.env.user.company_id.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.user.company_id.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_report_values(self, docids, data=None):
+ if not data.get('form') or not self.env.context.get('active_model') or not self.env.context.get('active_id'):
+ raise UserError(_("Form content is missing, this report cannot be printed."))
+
+ total = []
+ model = self.env.context.get('active_model')
+ docs = self.env[model].browse(self.env.context.get('active_id'))
+
+ target_move = data['form'].get('target_move', 'all')
+ date_from = data['form'].get('date_from', time.strftime('%Y-%m-%d'))
+
+ if data['form']['result_selection'] == 'customer':
+ account_type = ['receivable']
+ elif data['form']['result_selection'] == 'supplier':
+ account_type = ['payable']
+ else:
+ account_type = ['payable', 'receivable']
+
+ movelines, total, dummy = self._get_partner_move_lines(account_type, date_from, target_move, data['form']['period_length'])
+ return {
+ 'doc_ids': self.ids,
+ 'doc_model': model,
+ 'data': data['form'],
+ 'docs': docs,
+ 'time': time,
+ 'get_partner_lines': movelines,
+ 'get_direction': total,
+ }
diff --git a/addons/account_reports_xlsx/models/account_financial_report.py b/addons/account_reports_xlsx/models/account_financial_report.py
new file mode 100755
index 0000000..fad2359
--- /dev/null
+++ b/addons/account_reports_xlsx/models/account_financial_report.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from odoo import api, models, fields, _
+
+
+# ---------------------------------------------------------
+# Account Financial Report
+# ---------------------------------------------------------
+
+
+class AccountFinancialReport(models.Model):
+ _name = "account.financial.report"
+ _description = "Account Report"
+
+ @api.depends('parent_id', 'parent_id.level')
+ def _get_level(self):
+ '''Returns a dictionary with key=the ID of a record and value = the level of this
+ record in the tree structure.'''
+ for report in self:
+ level = 0
+ if report.parent_id:
+ level = report.parent_id.level + 1
+ report.level = level
+
+ def _get_children_by_order(self):
+ '''returns a recordset of all the children computed recursively, and sorted by sequence. Ready for the printing'''
+ res = self
+ children = self.search([('parent_id', 'in', self.ids)], order='sequence ASC')
+ if children:
+ for child in children:
+ res += child._get_children_by_order()
+ return res
+
+ name = fields.Char('Report Name', required=True, translate=True)
+ parent_id = fields.Many2one('account.financial.report', 'Parent')
+ children_ids = fields.One2many('account.financial.report', 'parent_id', 'Account Report')
+ sequence = fields.Integer('Sequence')
+ level = fields.Integer(compute='_get_level', string='Level', store=True)
+ type = fields.Selection([
+ ('sum', 'View'),
+ ('accounts', 'Accounts'),
+ ('account_type', 'Account Type'),
+ ('account_report', 'Report Value'),
+ ], 'Type', default='sum')
+ account_ids = fields.Many2many('account.account', 'account_account_financial_report', 'report_line_id',
+ 'account_id', 'Accounts')
+ account_report_id = fields.Many2one('account.financial.report', 'Report Value')
+ account_type_ids = fields.Many2many('account.account.type', 'account_account_financial_report_type', 'report_id',
+ 'account_type_id', 'Account Types')
+ sign = fields.Selection([
+ ('-1', 'Reverse balance sign'),
+ ('1', 'Preserve balance sign')],
+ 'Sign on Reports',
+ required=True,
+ default='1',
+ help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.')
+ display_detail = fields.Selection([
+ ('no_detail', 'No detail'),
+ ('detail_flat', 'Display children flat'),
+ ('detail_with_hierarchy', 'Display children with hierarchy')
+ ], 'Display details', default='detail_flat')
+ style_overwrite = fields.Selection([
+ ('0', 'Automatic formatting'),
+ ('1', 'Main Title 1 (bold, underlined)'),
+ ('2', 'Title 2 (bold)'),
+ ('3', 'Title 3 (bold, smaller)'),
+ ('4', 'Normal Text'),
+ ('5', 'Italic Text (smaller)'),
+ ('6', 'Smallest Text'),
+ ], 'Financial Report Style', default='0',
+ help="You can set up here the format you want this record to be displayed. If you leave the automatic formatting, it will be computed based on the financial reports hierarchy (auto-computed field 'level').")
diff --git a/addons/account_reports_xlsx/models/account_general_ledger.py b/addons/account_reports_xlsx/models/account_general_ledger.py
new file mode 100755
index 0000000..ded77f4
--- /dev/null
+++ b/addons/account_reports_xlsx/models/account_general_ledger.py
@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+import time
+from odoo import api, models, _
+from odoo.exceptions import UserError
+
+
+class ReportGeneralLedger(models.AbstractModel):
+ _name = 'report.account.report_generalledger'
+
+ def _get_account_move_entry(self, accounts, init_balance, sortby, display_account):
+ """
+ :param:
+ accounts: the recordset of accounts
+ init_balance: boolean value of initial_balance
+ sortby: sorting by date or partner and journal
+ display_account: type of account(receivable, payable and both)
+
+ Returns a dictionary of accounts with following key and value {
+ 'code': account code,
+ 'name': account name,
+ 'debit': sum of total debit amount,
+ 'credit': sum of total credit amount,
+ 'balance': total balance,
+ 'amount_currency': sum of amount_currency,
+ 'move_lines': list of move line
+ }
+ """
+ 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:
+ 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_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')
+ 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)\
+ JOIN account_journal j ON (l.journal_id=j.id)\
+ WHERE l.account_id IN %s""" + filters + ' GROUP BY l.account_id')
+ params = (tuple(accounts.ids),) + tuple(init_where_params)
+ cr.execute(sql, params)
+ for row in cr.dictfetchall():
+ move_lines[row.pop('account_id')].append(row)
+
+ sql_sort = 'l.date, l.move_id'
+ if sortby == 'sort_journal_partner':
+ sql_sort = 'j.code, p.name, l.move_id'
+
+ # Prepare sql query base on selected parameters from wizard
+ tables, where_clause, where_params = MoveLine._query_get()
+ wheres = [""]
+ if where_clause.strip():
+ wheres.append(where_clause.strip())
+ filters = " AND ".join(wheres)
+ filters = filters.replace('account_move_line__move_id', 'm').replace('account_move_line', 'l')
+
+ # Get move lines base on sql query and Calculate the total balance of move lines
+ sql = ('''SELECT l.id AS lid, 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 ''' + filters + ''' GROUP BY l.id, l.account_id, l.date, j.code, l.currency_id, l.amount_currency, l.ref, l.name, m.name, c.symbol, p.name ORDER BY ''' + sql_sort)
+ 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 += line['debit'] - line['credit']
+ row['balance'] += balance
+ 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['company_id'] = account.company_id.id
+ res['move_lines'] = move_lines[account.id]
+ for line in res.get('move_lines'):
+ res['debit'] += line['debit']
+ res['credit'] += line['credit']
+ res['balance'] = line['balance']
+ 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_report_values(self, docids, data=None):
+ if not data.get('form') or not self.env.context.get('active_model'):
+ raise UserError(_("Form content is missing, this report cannot be printed."))
+
+ model = self.env.context.get('active_model')
+ docs = self.env[model].browse(self.env.context.get('active_ids', []))
+
+ init_balance = data['form'].get('initial_balance', True)
+ sortby = data['form'].get('sortby', 'sort_date')
+ display_account = data['form']['display_account']
+ codes = []
+ if data['form'].get('journal_ids', False):
+ codes = [journal.code for journal in self.env['account.journal'].search([('id', 'in', data['form']['journal_ids'])])]
+
+ accounts = docs if model == 'account.account' else self.env['account.account'].search([])
+ accounts_res = self.with_context(data['form'].get('used_context',{}))._get_account_move_entry(accounts, init_balance, sortby, display_account)
+ return {
+ 'doc_ids': docids,
+ 'doc_model': model,
+ 'data': data['form'],
+ 'docs': docs,
+ 'time': time,
+ 'Accounts': accounts_res,
+ 'print_journal': codes,
+ }
diff --git a/addons/account_reports_xlsx/models/account_partner_ledger.py b/addons/account_reports_xlsx/models/account_partner_ledger.py
new file mode 100755
index 0000000..51a7df2
--- /dev/null
+++ b/addons/account_reports_xlsx/models/account_partner_ledger.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+import logging
+from datetime import datetime
+import time
+from odoo import api, models, _
+from odoo.exceptions import UserError
+from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
+
+_logger = logging.getLogger(__name__)
+
+
+class ReportPartnerLedger(models.AbstractModel):
+ _name = 'report.account_reports_xlsx.report_partnerledger'
+
+ def _lines(self, data, partner):
+ full_account = []
+ currency = self.env['res.currency']
+ query_get_data = self.env['account.move.line'].with_context(data['form'].get('used_context', {}))._query_get()
+ reconcile_clause = "" if data['form']['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL '
+ params = [partner.id, tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2]
+ query = """
+ SELECT "account_move_line".id, "account_move_line".date, j.code, acc.code as a_code, acc.name as a_name, "account_move_line".ref, m.name as move_name, "account_move_line".name, "account_move_line".debit, "account_move_line".credit, "account_move_line".amount_currency,"account_move_line".currency_id, c.symbol AS currency_code
+ FROM """ + query_get_data[0] + """
+ LEFT JOIN account_journal j ON ("account_move_line".journal_id = j.id)
+ LEFT JOIN account_account acc ON ("account_move_line".account_id = acc.id)
+ LEFT JOIN res_currency c ON ("account_move_line".currency_id=c.id)
+ LEFT JOIN account_move m ON (m.id="account_move_line".move_id)
+ WHERE "account_move_line".partner_id = %s
+ AND m.state IN %s
+ AND "account_move_line".account_id IN %s AND """ + query_get_data[1] + reconcile_clause + """
+ ORDER BY "account_move_line".date"""
+ self.env.cr.execute(query, tuple(params))
+ res = self.env.cr.dictfetchall()
+ sum = 0.0
+ lang_code = self.env.context.get('lang') or 'en_US'
+ lang = self.env['res.lang']
+ lang_id = lang._lang_get(lang_code)
+ date_format = lang_id.date_format
+ for r in res:
+ r['date'] = datetime.strptime(str(r['date']), DEFAULT_SERVER_DATE_FORMAT).strftime(date_format)
+ r['displayed_name'] = '-'.join(
+ r[field_name] for field_name in ('move_name', 'ref', 'name')
+ if r[field_name] not in (None, '', '/')
+ )
+ sum += r['debit'] - r['credit']
+ r['progress'] = sum
+ r['currency_id'] = currency.browse(r.get('currency_id'))
+ full_account.append(r)
+ return full_account
+
+ def _sum_partner(self, data, partner, field):
+ if field not in ['debit', 'credit', 'debit - credit', 'amount_currency']:
+ return
+ result = 0.0
+ query_get_data = self.env['account.move.line'].with_context(data['form'].get('used_context', {}))._query_get()
+ reconcile_clause = "" if data['form']['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL '
+
+ params = [partner.id, tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2]
+ query = """SELECT sum(""" + field + """)
+ FROM """ + query_get_data[0] + """, account_move AS m
+ WHERE "account_move_line".partner_id = %s
+ AND m.id = "account_move_line".move_id
+ AND m.state IN %s
+ AND account_id IN %s
+ AND """ + query_get_data[1] + reconcile_clause
+ self.env.cr.execute(query, tuple(params))
+
+ contemp = self.env.cr.fetchone()
+ if contemp is not None:
+ result = contemp[0] or 0.0
+ return result
+
+ @api.model
+ def get_report_values(self, docids, data=None):
+ if not data.get('form'):
+ raise UserError(_("Form content is missing, this report cannot be printed."))
+
+ data['computed'] = {}
+
+ obj_partner = self.env['res.partner']
+ query_get_data = self.env['account.move.line'].with_context(data['form'].get('used_context', {}))._query_get()
+ data['computed']['move_state'] = ['draft', 'posted']
+ if data['form'].get('target_move', 'all') == 'posted':
+ data['computed']['move_state'] = ['posted']
+ result_selection = data['form'].get('result_selection', 'customer')
+ if result_selection == 'supplier':
+ data['computed']['ACCOUNT_TYPE'] = ['payable']
+ elif result_selection == 'customer':
+ data['computed']['ACCOUNT_TYPE'] = ['receivable']
+ else:
+ data['computed']['ACCOUNT_TYPE'] = ['payable', 'receivable']
+
+ self.env.cr.execute("""
+ SELECT a.id
+ FROM account_account a
+ WHERE a.internal_type IN %s
+ AND NOT a.deprecated""", (tuple(data['computed']['ACCOUNT_TYPE']),))
+ data['computed']['account_ids'] = [a for (a,) in self.env.cr.fetchall()]
+ params = [tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2]
+ reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL '
+ query = """
+ SELECT DISTINCT "account_move_line".partner_id
+ FROM """ + query_get_data[0] + """, account_account AS account, account_move AS am
+ WHERE "account_move_line".partner_id IS NOT NULL
+ AND "account_move_line".account_id = account.id
+ AND am.id = "account_move_line".move_id
+ AND am.state IN %s
+ AND "account_move_line".account_id IN %s
+ AND NOT account.deprecated
+ AND """ + query_get_data[1] + reconcile_clause
+ self.env.cr.execute(query, tuple(params))
+ # ---------------------Taking only selected partners---------------------------
+ if data['form']['partner_ids']:
+ partner_ids = data['form']['partner_ids']
+ else:
+ partner_ids = [res['partner_id'] for res in self.env.cr.dictfetchall()]
+ # -----------------------------------------------------------------------------
+ # partner_ids = [res['partner_id'] for res in self.env.cr.dictfetchall()]
+ partners = obj_partner.browse(partner_ids)
+ partners = sorted(partners, key=lambda x: (x.ref or '', x.name or ''))
+
+ return {
+ 'doc_ids': partner_ids,
+ 'doc_model': self.env['res.partner'],
+ 'data': data,
+ 'docs': partners,
+ 'time': time,
+ 'lines': self._lines,
+ 'sum_partner': self._sum_partner,
+ }
diff --git a/addons/account_reports_xlsx/report/__init__.py b/addons/account_reports_xlsx/report/__init__.py
new file mode 100755
index 0000000..76740c2
--- /dev/null
+++ b/addons/account_reports_xlsx/report/__init__.py
@@ -0,0 +1 @@
+from . import account_aged_partner_balance
diff --git a/addons/account_reports_xlsx/report/account_aged_partner_balance.py b/addons/account_reports_xlsx/report/account_aged_partner_balance.py
new file mode 100755
index 0000000..b88782a
--- /dev/null
+++ b/addons/account_reports_xlsx/report/account_aged_partner_balance.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+
+import time
+from odoo import api, fields, models, _
+from odoo.exceptions import UserError
+from odoo.tools import float_is_zero
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
+
+class ReportAgedPartnerBalance(models.AbstractModel):
+
+ _name = 'report.account_reports_xlsx.report_agedpartnerbalance'
+ _description = 'Aged Partner Balance Report'
+
+ def _get_partner_move_lines(self, account_type, date_from, target_move, period_length):
+ # This method can receive the context key 'include_nullified_amount' {Boolean}
+ # Do an invoice and a payment and unreconcile. The amount will be nullified
+ # By default, the partner wouldn't appear in this report.
+ # The context key allow it to appear
+ # In case of a period_length of 30 days as of 2020-02-08, we want the following periods:
+ # Name Stop Start
+ # 1 - 30 : 2020-02-07 - 2020-01-09
+ # 31 - 60 : 2020-01-08 - 2018-12-10
+ # 61 - 90 : 2018-12-09 - 2018-11-10
+ # 91 - 120 : 2018-11-09 - 2018-10-11
+ # +120 : 2018-10-10
+ ctx = self._context
+ periods = {}
+ date_from = fields.Date.from_string(date_from)
+ start = date_from
+ 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 = []
+ partner_clause = ''
+ cr = self.env.cr
+ user_company = self.env.company
+ user_currency = user_company.currency_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), date_from, date_from,)
+ if ctx.get('partner_ids'):
+ partner_clause = 'AND (l.partner_id IN %s)'
+ arg_list += (tuple(ctx['partner_ids'].ids),)
+ if ctx.get('partner_categories'):
+ partner_clause += 'AND (l.partner_id IN %s)'
+ partner_ids = self.env['res.partner'].search([('category_id', 'in', ctx['partner_categories'].ids)]).ids
+ arg_list += (tuple(partner_ids or [0]),)
+ arg_list += (date_from, tuple(company_ids))
+
+ query = '''
+ SELECT DISTINCT l.partner_id, res_partner.name AS name, UPPER(res_partner.name) AS UPNAME, CASE WHEN prop.value_text IS NULL THEN 'normal' ELSE prop.value_text END AS trust
+ FROM account_move_line AS l
+ LEFT JOIN res_partner ON l.partner_id = res_partner.id
+ LEFT JOIN ir_property prop ON (prop.res_id = 'res.partner,'||res_partner.id AND prop.name='trust' AND prop.company_id=%s),
+ 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.reconciled IS FALSE
+ OR l.id IN(
+ SELECT credit_move_id FROM account_partial_reconcile where max_date > %s
+ UNION ALL
+ SELECT debit_move_id FROM account_partial_reconcile where max_date > %s
+ )
+ )
+ ''' + partner_clause + '''
+ AND (l.date <= %s)
+ AND l.company_id IN %s
+ ORDER BY UPPER(res_partner.name)'''
+ arg_list = (self.env.company.id,) + arg_list
+ 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 [], [], {}
+
+ # Use one query per period and store results in history (a list variable)
+ # Each history will contain: history[1] = {'<partner_id>': <partner_debit-credit>}
+ 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
+ ORDER BY COALESCE(l.date_maturity, l.date)'''
+ 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).with_context(prefetch_fields=False):
+ partner_id = line.partner_id.id or False
+ if partner_id not in partners_amount:
+ partners_amount[partner_id] = 0.0
+ line_amount = line.company_id.currency_id._convert(line.balance, user_currency, user_company, date_from)
+ 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 += partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
+ for partial_line in line.matched_credit_ids:
+ if partial_line.max_date <= date_from:
+ line_amount -= partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
+
+ if not self.env.company.currency_id.is_zero(line_amount):
+ partners_amount[partner_id] += line_amount
+ lines.setdefault(partner_id, [])
+ lines[partner_id].append({
+ 'line': line,
+ 'amount': line_amount,
+ 'period': i + 1,
+ })
+ history.append(partners_amount)
+
+ # 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
+ ORDER BY COALESCE(l.date_maturity, l.date)'''
+ 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
+ if partner_id not in undue_amounts:
+ undue_amounts[partner_id] = 0.0
+ line_amount = line.company_id.currency_id._convert(line.balance, user_currency, user_company, date_from)
+ 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 += partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
+ for partial_line in line.matched_credit_ids:
+ if partial_line.max_date <= date_from:
+ line_amount -= partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
+ if not self.env.company.currency_id.is_zero(line_amount):
+ undue_amounts[partner_id] += line_amount
+ lines.setdefault(partner_id, [])
+ lines[partner_id].append({
+ 'line': line,
+ 'amount': line_amount,
+ 'period': 6,
+ })
+
+ 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
+ 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']:
+ values['name'] = len(partner['name']) >= 45 and partner['name'][0:40] + '...' or partner['name']
+ values['trust'] = 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_report_values(self, docids, data=None):
+ if not data.get('form') or not self.env.context.get('active_model') or not self.env.context.get('active_id'):
+ raise UserError(_("Form content is missing, this report cannot be printed."))
+
+ total = []
+ model = self.env.context.get('active_model')
+ docs = self.env[model].browse(self.env.context.get('active_id'))
+
+ target_move = data['form'].get('target_move', 'all')
+ date_from = fields.Date.from_string(data['form'].get('date_from')) or fields.Date.today()
+
+ if data['form']['result_selection'] == 'customer':
+ account_type = ['receivable']
+ elif data['form']['result_selection'] == 'supplier':
+ account_type = ['payable']
+ else:
+ account_type = ['payable', 'receivable']
+
+ movelines, total, dummy = self._get_partner_move_lines(account_type, date_from, target_move, data['form']['period_length'])
+ return {
+ 'doc_ids': self.ids,
+ 'doc_model': model,
+ 'data': data['form'],
+ 'docs': docs,
+ 'time': time,
+ 'get_partner_lines': movelines,
+ 'get_direction': total,
+ 'company_id': self.env['res.company'].browse(
+ data['form']['company_id'][0]),
+ }
diff --git a/addons/account_reports_xlsx/security/ir.model.access.csv b/addons/account_reports_xlsx/security/ir.model.access.csv
new file mode 100755
index 0000000..a5410fe
--- /dev/null
+++ b/addons/account_reports_xlsx/security/ir.model.access.csv
@@ -0,0 +1,7 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_xlsx_reports,account.financial.report.manager,model_account_financial_report,account.group_account_manager,1,1,1,1
+access_account_aged_trial_balance_xlsx,access.account.aged.trial.balance.xlsx,model_account_aged_trial_balance_xlsx,account.group_account_user,1,1,1,1
+access_account_report_partner_ledger_xlsx,access.account.report.partner.ledger.xlsx,model_account_report_partner_ledger_xlsx,account.group_account_user,1,1,1,1
+access_account_report_general_ledger_xlsx,access.account.report.general.ledger.xlsx,model_account_report_general_ledger_xlsx,account.group_account_user,1,1,1,1
+access_accounting_report_xlsx,access.accounting.report.xlsx,model_accounting_report_xlsx,account.group_account_user,1,1,1,1
+access_report_account_reports_xlsx_report_agedpartnerbalance,access.report.account_reports_xlsx.report_agedpartnerbalance,model_report_account_reports_xlsx_report_agedpartnerbalance,account.group_account_user,1,1,1,1 \ No newline at end of file
diff --git a/addons/account_reports_xlsx/static/description/banner.png b/addons/account_reports_xlsx/static/description/banner.png
new file mode 100755
index 0000000..d93f8da
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/banner.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/icon.png b/addons/account_reports_xlsx/static/description/icon.png
new file mode 100755
index 0000000..7dd03bb
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/icon.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/Accounting Reports in Excel.png b/addons/account_reports_xlsx/static/description/images/Accounting Reports in Excel.png
new file mode 100755
index 0000000..3bb18fd
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/Accounting Reports in Excel.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_Report_2.png b/addons/account_reports_xlsx/static/description/images/account_Report_2.png
new file mode 100755
index 0000000..afec944
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_Report_2.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_report.png b/addons/account_reports_xlsx/static/description/images/account_report.png
new file mode 100755
index 0000000..6c87017
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_report.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_report_3.png b/addons/account_reports_xlsx/static/description/images/account_report_3.png
new file mode 100755
index 0000000..91c0ada
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_report_3.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_report_6.png b/addons/account_reports_xlsx/static/description/images/account_report_6.png
new file mode 100755
index 0000000..29c5d8b
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_report_6.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_report_7.png b/addons/account_reports_xlsx/static/description/images/account_report_7.png
new file mode 100755
index 0000000..96105a0
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_report_7.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_report_8.png b/addons/account_reports_xlsx/static/description/images/account_report_8.png
new file mode 100755
index 0000000..2957b12
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_report_8.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/account_report_9.png b/addons/account_reports_xlsx/static/description/images/account_report_9.png
new file mode 100755
index 0000000..050f242
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/account_report_9.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/accounting-report.gif b/addons/account_reports_xlsx/static/description/images/accounting-report.gif
new file mode 100755
index 0000000..c5d35c3
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/accounting-report.gif
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/accounting_report_4.png b/addons/account_reports_xlsx/static/description/images/accounting_report_4.png
new file mode 100755
index 0000000..75abf4e
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/accounting_report_4.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/accounting_report_5.png b/addons/account_reports_xlsx/static/description/images/accounting_report_5.png
new file mode 100755
index 0000000..b3aea42
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/accounting_report_5.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/bank_book.png b/addons/account_reports_xlsx/static/description/images/bank_book.png
new file mode 100755
index 0000000..088d9be
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/bank_book.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/banner.png b/addons/account_reports_xlsx/static/description/images/banner.png
new file mode 100755
index 0000000..60b9433
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/banner.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/cash_book.jpeg b/addons/account_reports_xlsx/static/description/images/cash_book.jpeg
new file mode 100755
index 0000000..b7a48f2
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/cash_book.jpeg
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/checked.png b/addons/account_reports_xlsx/static/description/images/checked.png
new file mode 100755
index 0000000..578cedb
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/checked.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/cybrosys.png b/addons/account_reports_xlsx/static/description/images/cybrosys.png
new file mode 100755
index 0000000..d76b5ba
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/cybrosys.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/day_book_report.png b/addons/account_reports_xlsx/static/description/images/day_book_report.png
new file mode 100755
index 0000000..a3fced2
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/day_book_report.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/dynamic_financial_report.png b/addons/account_reports_xlsx/static/description/images/dynamic_financial_report.png
new file mode 100755
index 0000000..b025b5c
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/dynamic_financial_report.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/full_accounting_kit.gif b/addons/account_reports_xlsx/static/description/images/full_accounting_kit.gif
new file mode 100755
index 0000000..7c28a18
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/full_accounting_kit.gif
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/images/project_report.png b/addons/account_reports_xlsx/static/description/images/project_report.png
new file mode 100755
index 0000000..3c430a7
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/images/project_report.png
Binary files differ
diff --git a/addons/account_reports_xlsx/static/description/index.html b/addons/account_reports_xlsx/static/description/index.html
new file mode 100755
index 0000000..5da7471
--- /dev/null
+++ b/addons/account_reports_xlsx/static/description/index.html
@@ -0,0 +1,402 @@
+<div class="row" style="margin: 0;position: relative;color: #000;background-position: center;background: #ffffff;border-bottom: 1px solid #e4e4e4;text-align: center; margin: auto; display: flex;justify-content: center;"> <a href="https://www.cybrosys.com/" target="_blank"><img src="images/cybrosys.png" style=" width: 293px; padding: 1rem 0rem; margin: auto" alt="cybrosys-logo"></a> </div>
+<div class="row" style="margin:75px 0;position: relative;color: #000;background-position: center;background: #ffffff;border-bottom: 1px solid #e4e4e4; padding-bottom: 30px;">
+ <div class="col-md-7 col-sm-12 col-xs-12" style="padding: 0px">
+ <div style=" margin: 0 0 0px;padding: 20px 0 10;font-size: 23px;line-height: 35px;font-weight: 400;color: #000;border-top: 1px solid rgba(255,255,255,0.1);border-bottom: 1px solid rgba(255,255,255,0.11);text-align: left;">
+
+ <h1 style="font-size: 39px;font-weight: 600;margin: 0px !important;">Accounting Report Excel </h1>
+ <h3 style="font-size: 21px;margin-top: 8px;position: relative;">Generates XLSX reports for all accounting records of a business. </h3>
+ </div>
+ <h2 style="font-weight: 600;font-size: 1.8rem;margin-top: 15px;">Key Highlights</h2>
+ <ul style=" padding: 0 1px; list-style: none; ">
+ <li style="display:flex;align-items: self-start;padding:8px 0;font-size:18px;"><i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Partner Ledger Report in Excel Template</li>
+ <li style="display:flex;align-items: self-start;padding:8px 0;font-size:18px;"><i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> General Ledger Report in Excel Template</li>
+ <li style="display:flex;align-items: self-start;padding:8px 0;font-size:18px;"><i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Balance Sheet Report in Excel Template</li>
+ <li style="display:flex;align-items: self-start;padding:8px 0;font-size:18px;"><i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Profit and Loss Report in Excel Template</li>
+ <li style="display:flex;align-items: self-start;padding:8px 0;font-size:18px;"><i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Aged Partner Balance Report in Excel Template</li>
+ </ul>
+ </div>
+ <div class="col-md-5 col-sm-12 col-xs-12"> <img src="images/accounting-report.gif" class="img-responsive" alt=""> </div>
+</div>
+<div>
+ <section class="oe_container" style="padding: 1rem 0rem 1rem; background-color: #ffffff !important;">
+ <div class="row py-4 px-3">
+ <div class="w-100" style="padding-top:30px;padding-bottom:45px;border-radius: 10px;">
+ <ul role="tablist" class="nav nav-pills justify-content-center" data-tabs="tabs" id="pills-tab" style="border: none;background: unset;">
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true" class="nav-link active show" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;">Overview </a> </li>
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a id="pills-home-tab" data-toggle="pill" href="#pills-home1" role="tab" aria-controls="pills-home" aria-selected="true" class="nav-link " style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;">Features </a> </li>
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;">Screenshots </a> </li>
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-video" role="tab" aria-controls="pills-profile" aria-selected="false" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;">Video </a> </li>
+ </ul>
+ <div class="tab-content" id="pills-tabContent"
+ style="padding-top: 30px; padding-bottom: 30px; padding: 30px;">
+ <div class="px-3 pt-1 tab-pane fade active show" id="pills-home" role="tabpanel" aria-labelledby="
+ pills-home-tab">
+ <!-- Overview-->
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Overview</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <h3 class="oe_slogan" style="text-align: center;font-size: 19px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 31px;font-weight: 400;letter-spacing: .5px;margin-bottom: 21px;">
+ Generates xlsx reports for every financial compilation such as Partner Ledger, General Ledger, Balance Sheet, Profit and Loss and Aged Partner Balance. Earlier only pdf reports were made available to the end users of Odoo community. However, these reports were of not much use as they came hard to interpret.
+ <br>
+ <br>
+ The module Accounting Report Excel envisions in giving stress-free accounting experience to the user. Using the module generated XLSX accounting reports, businesses can now seamlessly examine each transaction. The cuser can also print and download the excel reports, making the accounting process more simpler and hassle-free.
+ </div>
+ <div class="px-3 pt-1 tab-pane fade " id="pills-home1" role="tabpanel" aria-labelledby="
+ pills-home-tab">
+ <!-- feature tab-->
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Accounting Report Excel </h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <ul>
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Generates xlsx report for:
+ </li>
+
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Partner Ledger
+ </li>
+
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ General Ledger
+ </li>
+
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Balance Sheet
+ </li>
+
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Profit and Loss
+ </li>
+
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Aged Partner Balance
+ </li>
+ </ul>
+ </div>
+ <!-- Screenshot tab-->
+ <div class="px-3 tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" >
+ <div class="tab-pane">
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Screenshots</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <div>
+ <section class="oe_container">
+ <div id="demo" class="row carousel slide mb32" data-ride="carousel">
+ <div class="carousel-inner">
+ <div class="carousel-item active" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Aged Partner Balance
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_report.png"> </div>
+ </div>
+ <div class="carousel-item active" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i>
+ Aged Partner Balance
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_Report_2.png"> </div>
+ </div>
+ </div>
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Balance Sheet
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_report_7.png"> </div>
+ </div>
+ </div>
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Balance Sheet
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_report_8.png"> </div>
+ </div>
+ </div>
+
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> General Ledger
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_report_3.png"> </div>
+ </div>
+ </div>
+
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> General Ledger
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/accounting_report_4.png"> </div>
+ </div>
+ </div>
+
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Partner Ledger
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/accounting_report_5.png"> </div>
+ </div>
+ </div>
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Partner Ledger
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_report_6.png"> </div>
+ </div>
+ </div>
+
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle" style="width: auto;color: #6AC259;font-size: 25px;padding-right: 10px;"></i> Profit and Loss
+ </h3>
+
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/account_report_9.png"> </div>
+ </div>
+ </div>
+ </div>
+ <a class="carousel-control-prev" href="#demo" data-slide="prev" style="left:-25px;width: 35px;color: #000;"> <span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span> </a> <a class="carousel-control-next" href="#demo" data-slide="next" style="right:-25px;width: 35px;color: #000;"> <span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span> </a>
+ </div>
+ </section>
+ </div>
+ </div>
+ </div>
+ <div class="px-3 pt-1 tab-pane fade" id="pills-video" role="tabpanel" aria-labelledby="
+ pills-home-tab">
+ <!-- Video-->
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Video</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <center>
+ <p>Accounting Report Excel Demo</p>
+ <!--<a href="https://www.youtube.com/watch?v=57QWXrMYe84&feature=youtu.be" target="_blank"> <img src="addon-youtube.png" style="width:80%;"></a>-->
+ <div class="s_panel_video" data-video-id="Sch1VcrunT0?rel=0" style="cursor:pointer;">
+ <img class="img-fluid s_tooltip_tabs_tooltip_image s_figure_link pb0" src="images/Accounting Reports in Excel.png" alt="Cybrosys Cover Video" style="max-width:100%;">
+ </div>
+ </center>
+ </div>
+ <!-- faq tab-->
+ <div class="px-2 px-lg-4 pt-3 tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">
+ <ul class="list-unstyled">
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section class="oe_container" style="padding: 2rem 3rem 1rem;">
+ <h2 style="font-weight: 600;text-align: center;margin-bottom: 25px;width: 100%;">Suggested Products</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <div id="demo1" class="row carousel slide" data-ride="carousel">
+ <!-- The slideshow -->
+ <div class="carousel-inner">
+ <div class="carousel-item active" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/account_day_book/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/day_book_report.png"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/accounting_dynamic_reports/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/dynamic_financial_report.png"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/base_accounting_kit/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/full_accounting_kit.gif"> </div>
+ </a>
+ </div>
+ </div>
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/project_report_pdf/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/project_report.png"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/account_bank_book/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/bank_book.png"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/account_cash_book/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/cash_book.jpeg"> </div>
+ </a>
+ </div>
+ </div>
+ </div>
+ <!-- Left and right controls -->
+ <a class="carousel-control-prev" href="#demo1" data-slide="prev" style="left:-25px;width: 35px;color: #000;"> <span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span> </a> <a class="carousel-control-next" href="#demo1" data-slide="next" style="right:-25px;width: 35px;color: #000;"> <span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span> </a>
+ </div>
+ </section>
+ <section class="row" style="padding: 2rem 3rem 1rem;margin:0px">
+ <h2 style="font-weight: 600;margin-bottom: 20px;text-align: center;width: 100%;">Our Service</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <div class="row" style=" display: flex; justify-content: center; flex-wrap: wrap;width: 100%; ">
+ <!-- <div style="display:flex;padding-top: 20px;justify-content: space-between;"> -->
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-customization.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Customization </a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-erp-implementation.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Implementation </a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-erp-integration.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Integration </a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-erp-support.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Support</a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank"> <img src="https://www.cybrosys.com/images/hire-odoo-developer.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Hire Odoo Developers</a> </h3>
+ </a>
+ </div>
+ <!-- </div> -->
+ </div>
+ </section>
+ <section class="row" style="padding: 2rem 3rem 1rem;margin:0px">
+ <div class="row" style="margin: 0">
+ <h2 style="font-weight: 600;margin-bottom: 20px;text-align: center;width: 100%;">Our Industries</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <!-- <div style="display:flex;justify-content: space-between;flex-wrap:wrap;"> -->
+ <div class="row" style="width: 100%">
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-1.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> Trading </a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> Easily procure and sell your products. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-2.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;" style=" margin-bottom: 10px; ">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> Manufacturing</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;font-family: 'Montserrat',sans-serif;"> Plan, track and schedule your operations. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-3.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> Restaurant</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;font-family: 'Montserrat',sans-serif;"> Run your bar or restaurant methodical. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-4.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> POS</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;font-family: 'Montserrat',sans-serif;"> Easy configuring and convivial selling. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-5.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 0px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> E-commerce & Website</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> Mobile friendly, awe-inspiring product pages. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-6.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Hotel Management</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> An all-inclusive hotel management application. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-7.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Education</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> A Collaborative platform for educational management. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-8.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Service Management</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> Keep track of services and invoice accordingly. </h3>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</section>
+<section class="oe_container" style="padding: 0% 0% 6% 0%;">
+ <center>
+ <div class="col-md-12" style="margin: auto !important;
+ width: 70%;
+ padding: 30px;">
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Need Any Help?</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <h4 style="font-size:16px;"> If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support. </h4>
+ <div class="col-md-6" style="float:left; padding:20px;">
+ <h4><i class="fa fa-envelope"></i>Email us </h4>
+ <p>odoo@cybrosys.com / info@cybrosys.com</p>
+ </div>
+ <div class="col-md-6" style="float:left; padding:20px;">
+ <h4><i class="fa fa-phone"></i> Contact Us </h4>
+ <a href="https://www.cybrosys.com/contact/" target="_blank"> www.cybrosys.com</a>
+ </div>
+ </div>
+ </center>
+</section>
+<section class="oe_container" style="padding: 0% 0% 6% 0%;">
+ <div class="oe_slogan" style="margin-bottom: 0px;">
+ <div style=" display: flex; justify-content: center; flex-wrap: wrap; ">
+ </div>
+ <br>
+ <img src="https://www.cybrosys.com/images/logo.png" style="width: 190px; margin-bottom: 25px;margin-top: 30px;" class="center-block">
+ <div style=" display: flex; justify-content: center; flex-wrap: wrap; "> <a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ <a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ <a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px; height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ <a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ </div>
+ </div>
+</section>
+</div> \ No newline at end of file
diff --git a/addons/account_reports_xlsx/static/src/js/action_manager.js b/addons/account_reports_xlsx/static/src/js/action_manager.js
new file mode 100755
index 0000000..15ef8d3
--- /dev/null
+++ b/addons/account_reports_xlsx/static/src/js/action_manager.js
@@ -0,0 +1,52 @@
+odoo.define('account_reports_xlsx.ActionManager', function (require) {
+"use strict";
+
+/**
+ * The purpose of this file is to add the actions of type
+ * 'ir_actions_xlsx_download' to the ActionManager.
+ */
+
+var ActionManager = require('web.ActionManager');
+var framework = require('web.framework');
+var session = require('web.session');
+
+ActionManager.include({
+
+ /**
+ * Executes actions of type 'ir_actions_xlsx_download'.
+ *
+ * @private
+ * @param {Object} action the description of the action to execute
+ * @returns {Deferred} resolved when the report has been downloaded ;
+ * rejected if an error occurred during the report generation
+ */
+ _executexlsxReportDownloadAction: function (action) {
+ console.log("ExecutexlsxReportDownloadAction")
+ console.log(action)
+ framework.blockUI();
+ var def = $.Deferred();
+ session.get_file({
+ url: '/xlsx_reports',
+ data: action.data,
+ success: def.resolve.bind(def),
+ error: (error) => this.call('crash_manager', 'rpc_error', error),
+ complete: framework.unblockUI,
+ });
+ return def;
+ },
+ /**
+ * Overrides to handle the 'ir_actions_xlsx_download' actions.
+ *
+ * @override
+ * @private
+ */
+ _executeReportAction: function (action, options) {
+ console.log("inside Execute report action")
+ if (action.report_type === 'xlsx') {
+ return this._executexlsxReportDownloadAction(action, options);
+ }
+ return this._super.apply(this, arguments);
+ },
+});
+
+});
diff --git a/addons/account_reports_xlsx/views/account_financial_report_data.xml b/addons/account_reports_xlsx/views/account_financial_report_data.xml
new file mode 100755
index 0000000..2309c50
--- /dev/null
+++ b/addons/account_reports_xlsx/views/account_financial_report_data.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data noupdate="1">
+ <!--
+ Financial Reports
+ -->
+ <record id="account_financial_report_profitandloss0" model="account.financial.report">
+ <field name="name">Profit and Loss</field>
+<!-- <field name="sign" eval="-1" />-->
+ <field name="sign">-1</field>
+ <field name="type">sum</field>
+ </record>
+
+ <record id="account_financial_report_income0" model="account.financial.report">
+ <field name="name">Income</field>
+<!-- <field name="sign" eval="-1" />-->
+ <field name="sign">-1</field>
+ <field name="parent_id" ref="account_financial_report_profitandloss0"/>
+ <field name="display_detail">detail_with_hierarchy</field>
+ <field name="type">account_type</field>
+ <field name="account_type_ids" eval="[(4,ref('account.data_account_type_other_income')), (4,ref('account.data_account_type_revenue'))]"/>
+ </record>
+
+ <record id="account_financial_report_expense0" model="account.financial.report">
+ <field name="name">Expense</field>
+<!-- <field name="sign" eval="-1" />-->
+ <field name="sign">-1</field>
+ <field name="parent_id" ref="account_financial_report_profitandloss0"/>
+ <field name="display_detail">detail_with_hierarchy</field>
+ <field name="type">account_type</field>
+ <field name="account_type_ids" eval="[(4,ref('account.data_account_type_expenses')), (4,ref('account.data_account_type_direct_costs')), (4,ref('account.data_account_type_depreciation'))]"/>
+ </record>
+
+ <record id="account_financial_report_balancesheet0" model="account.financial.report">
+ <field name="name">Balance Sheet</field>
+ <field name="type">sum</field>
+ </record>
+
+ <record id="account_financial_report_assets0" model="account.financial.report">
+ <field name="name">Assets</field>
+ <field name="parent_id" ref="account_financial_report_balancesheet0"/>
+ <field name="display_detail">detail_with_hierarchy</field>
+ <field name="type">account_type</field>
+ <field name="account_type_ids" eval="[(4,ref('account.data_account_type_receivable')), (4,ref('account.data_account_type_liquidity')), (4,ref('account.data_account_type_current_assets')), (4,ref('account.data_account_type_non_current_assets'), (4,ref('account.data_account_type_prepayments'))), (4,ref('account.data_account_type_fixed_assets'))]"/>
+ </record>
+
+ <record id="account_financial_report_liabilitysum0" model="account.financial.report">
+ <field name="name">Liability</field>
+ <field name="parent_id" ref="account_financial_report_balancesheet0"/>
+ <field name="display_detail">no_detail</field>
+ <field name="type">sum</field>
+ </record>
+
+ <record id="account_financial_report_liability0" model="account.financial.report">
+ <field name="name">Liability</field>
+ <field name="parent_id" ref="account_financial_report_liabilitysum0"/>
+ <field name="display_detail">detail_with_hierarchy</field>
+ <field name="type">account_type</field>
+ <field name="account_type_ids" eval="[(4,ref('account.data_account_type_payable')), (4,ref('account.data_account_type_equity')), (4,ref('account.data_account_type_current_liabilities')), (4,ref('account.data_account_type_non_current_liabilities'))]"/>
+ </record>
+
+ <record id="account_financial_report_profitloss_toreport0" model="account.financial.report">
+ <field name="name">Profit (Loss) to report</field>
+ <field name="parent_id" ref="account_financial_report_liabilitysum0"/>
+ <field name="display_detail">no_detail</field>
+ <field name="type">account_report</field>
+ <field name="account_report_id" ref="account_financial_report_profitandloss0"/>
+ </record>
+
+ </data>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/action_manager.xml b/addons/account_reports_xlsx/views/action_manager.xml
new file mode 100755
index 0000000..f5c8f87
--- /dev/null
+++ b/addons/account_reports_xlsx/views/action_manager.xml
@@ -0,0 +1,9 @@
+<odoo>
+ <data>
+ <template id="assets_backend" name="xls_assets" inherit_id="web.assets_backend">
+ <xpath expr="." position="inside">
+ <script type="text/javascript" src="/account_reports_xlsx/static/src/js/action_manager.js"/>
+ </xpath>
+ </template>
+ </data>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/financial_report_wizard_view.xml b/addons/account_reports_xlsx/views/financial_report_wizard_view.xml
new file mode 100755
index 0000000..6723928
--- /dev/null
+++ b/addons/account_reports_xlsx/views/financial_report_wizard_view.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <record id="financial_wizard_xlsx_form_view" model="ir.ui.view">
+ <field name="name">Accounting report</field>
+ <field name="model">accounting.report.xlsx</field>
+ <field name="inherit_id" ref="account.account_common_report_view"/>
+ <!--XLS print button in financial report wizard-->
+ <field name="arch" type="xml">
+ <xpath expr="//button[@name='check_report']" position="after">
+ <button name="check_report" string="Export XLSX" type="object" context="{'xls_export':1}" class="oe_highlight" style="margin: 0 5px;"/>
+ </xpath>
+ </field>
+ </record>
+ </data>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/financial_report_xls_view.xml b/addons/account_reports_xlsx/views/financial_report_xls_view.xml
new file mode 100755
index 0000000..05c02bf
--- /dev/null
+++ b/addons/account_reports_xlsx/views/financial_report_xls_view.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <report
+ id="accounting_report_xls"
+ model="accounting.report.xlsx"
+ string="Financial Report "
+ print_report_name = "Financial Report"
+ report_type="xlsx"
+ name="account_reports_xlsx.financial_report_xls"
+ file="account_reports_xlsx.financial_report_xls"
+ attachment_use="False"
+ />
+ </data>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/general_ledger_report_view.xml b/addons/account_reports_xlsx/views/general_ledger_report_view.xml
new file mode 100755
index 0000000..81c208c
--- /dev/null
+++ b/addons/account_reports_xlsx/views/general_ledger_report_view.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <report
+ id="ledger_xlsx"
+ model="account.report.general.ledger.xlsx"
+ string="General Ledger"
+ print_report_name = "General Ledger"
+ report_type="xlsx"
+ name="account_reports_xlsx.ledger_report_xls"
+ file="account_reports_xlsx.ledger_report_xls"
+ attachment_use="False"
+ />
+ </data>
+</openerp>
diff --git a/addons/account_reports_xlsx/views/general_ledger_report_wizard_view.xml b/addons/account_reports_xlsx/views/general_ledger_report_wizard_view.xml
new file mode 100755
index 0000000..3f7c0e0
--- /dev/null
+++ b/addons/account_reports_xlsx/views/general_ledger_report_wizard_view.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <record id="general_ledger_wizard_xlsx_form_view" model="ir.ui.view">
+ <field name="name">General Ledger</field>
+ <field name="model">account.report.general.ledger.xlsx</field>
+ <field name="inherit_id" ref="account.account_report_general_ledger_view"/>
+ <field name="arch" type="xml">
+ <xpath expr="//button[@name='check_report']" position="after">
+ <button name="report_xlsx" string="Export XLSX" type="object" class="oe_highlight" style="margin: 0 5px;"/>
+ </xpath>
+ </field>
+ </record>
+ </data>
+</odoo> \ No newline at end of file
diff --git a/addons/account_reports_xlsx/views/partner_ledgerreport.xml b/addons/account_reports_xlsx/views/partner_ledgerreport.xml
new file mode 100755
index 0000000..c42418d
--- /dev/null
+++ b/addons/account_reports_xlsx/views/partner_ledgerreport.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<template id="account_reports_xlsx.report_partnerledger">
+ <t t-call="web.html_container">
+ <t t-set="data_report_margin_top" t-value="12"/>
+ <t t-set="data_report_header_spacing" t-value="9"/>
+ <t t-set="data_report_dpi" t-value="110"/>
+ <t t-foreach="docs" t-as="o">
+ <t t-call="web.internal_layout">
+ <div class="page">
+ <h2>Partner Ledger</h2>
+
+ <div class="row">
+ <div class="col-xs-3">
+ <strong>Company:</strong>
+ <p t-esc="res_company.name"/>
+ </div>
+ <div class="col-xs-3">
+ <t t-if="data['form']['date_from']"><strong>Date from :</strong> <span t-esc="data['form']['date_from']"/><br/></t>
+ <t t-if="data['form']['date_to']"><strong>Date to :</strong> <span t-esc="data['form']['date_to']"/></t>
+ </div>
+ <div class="col-xs-3">
+ <strong>Target Moves:</strong>
+ <p t-if="data['form']['target_move'] == 'all'">All Entries</p>
+ <p t-if="data['form']['target_move'] == 'posted'">All Posted Entries</p>
+ </div>
+ </div>
+
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>Date</th>
+ <th>JRNL</th>
+ <th>Account</th>
+ <th>Ref</th>
+ <th>Debit</th>
+ <th>Credit</th>
+ <th>Balance</th>
+ <th t-if="data['form']['amount_currency']">Currency</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td colspan="4">
+ <strong t-esc="o.ref"/>
+ - <strong t-esc="o.name"/>
+ </td>
+ <td class="text-right">
+ <strong t-esc="sum_partner(data, o, 'debit')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <strong t-esc="sum_partner(data, o, 'credit')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <strong t-esc="sum_partner(data, o, 'debit - credit')" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right" t-if="data['form']['amount_currency']">
+ <strong t-esc="sum_partner(data, o, 'amount_currency')" />
+ </td>
+ </tr>
+ <tr t-foreach="lines(data, o)" t-as="line">
+ <td>
+ <span t-esc="line['date']"/>
+ </td>
+ <td>
+ <span t-esc="line['code']"/>
+ </td>
+ <td>
+ <span t-esc="line['a_code']"/>
+ </td>
+ <td>
+ <span t-esc="line['displayed_name']"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="line['debit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="line['credit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="line['progress']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right" t-if="data['form']['amount_currency']">
+ <t t-if="line['currency_id']">
+ <span t-esc="line['amount_currency']" t-options="{'widget': 'monetary', 'display_currency': line['currency_id']}"/>
+ </t>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </t>
+ </t>
+ </t>
+</template>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/report.xml b/addons/account_reports_xlsx/views/report.xml
new file mode 100755
index 0000000..cf3b8d0
--- /dev/null
+++ b/addons/account_reports_xlsx/views/report.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+
+ <act_window name="Partner Ledger"
+ res_model="account.report.partner.ledger.xlsx"
+ src_model="res.partner"
+ view_mode="form"
+ view_id ="account_reports_xlsx.account_report_partner_ledger_view"
+ target="new"
+ key2="client_print_multi"
+ id="action_account_partner_ledger_report_filter"
+ context="{'default_partner_ids':active_ids}"
+ />
+
+ </data>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/report_agedpartnerbalance.xml b/addons/account_reports_xlsx/views/report_agedpartnerbalance.xml
new file mode 100755
index 0000000..40fe28e
--- /dev/null
+++ b/addons/account_reports_xlsx/views/report_agedpartnerbalance.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<template id="report_agedpartnerbalance">
+ <t t-call="web.html_container">
+ <t t-call="web.internal_layout">
+ <div class="page">
+ <h2>Aged Partner Balance</h2>
+
+ <div class="row mt32">
+ <div class="col-3">
+ <strong>Start Date:</strong>
+ <p t-esc="data['date_from']"/>
+ </div>
+ <div class="col-3">
+ <strong>Period Length (days)</strong>
+ <p t-esc="data['period_length']"/>
+ </div>
+ </div>
+ <div class="row mb32">
+ <div class="col-3">
+ <strong>Partner's:</strong>
+ <p>
+ <span t-if="data['result_selection'] == 'customer'">Receivable Accounts</span>
+ <span t-if="data['result_selection'] == 'supplier'">Payable Accounts</span>
+ <span t-if="data['result_selection'] == 'customer_supplier'">Receivable and Payable Accounts</span>
+ </p>
+ </div>
+ <div class="col-3">
+ <strong>Target Moves:</strong>
+ <p>
+ <span t-if="data['target_move'] == 'all'">All Entries</span>
+ <span t-if="data['target_move'] == 'posted'">All Posted Entries</span>
+ </p>
+ </div>
+ </div>
+
+ <table class="table table-sm">
+ <thead>
+ <tr>
+ <th><span>Partners</span></th>
+ <th class="text-right">
+ <span>Not due</span>
+ </th>
+ <th class="text-right"><span t-esc="data['4']['name']"/></th>
+ <th class="text-right"><span t-esc="data['3']['name']"/></th>
+ <th class="text-right"><span t-esc="data['2']['name']"/></th>
+ <th class="text-right"><span t-esc="data['1']['name']"/></th>
+ <th class="text-right"><span t-esc="data['0']['name']"/></th>
+ <th class="text-right"><span>Total</span></th>
+ </tr>
+ <tr t-if="get_partner_lines">
+ <th>Account Total</th>
+ <th class="text-right"><span t-esc="get_direction[6]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ <th class="text-right"><span t-esc="get_direction[4]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ <th class="text-right"><span t-esc="get_direction[3]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ <th class="text-right"><span t-esc="get_direction[2]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ <th class="text-right"><span t-esc="get_direction[1]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ <th class="text-right"><span t-esc="get_direction[0]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ <th class="text-right"><span t-esc="get_direction[5]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr t-foreach="get_partner_lines" t-as="partner">
+ <td>
+ <span t-esc="partner['name']"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['direction']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['4']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['3']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['2']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['1']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['0']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['total']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </t>
+ </t>
+</template>
+</odoo>
diff --git a/addons/account_reports_xlsx/views/supplier_aging_report_view.xml b/addons/account_reports_xlsx/views/supplier_aging_report_view.xml
new file mode 100755
index 0000000..d2c0cd0
--- /dev/null
+++ b/addons/account_reports_xlsx/views/supplier_aging_report_view.xml
@@ -0,0 +1,85 @@
+<odoo>
+ <data>
+ <template id="account_reports_xlsx.aging_partnerbalance">
+ <t t-call="web.html_container">
+ <t t-call="web.external_layout">
+ <div class="page">
+ <h2>Aged Partner Balance</h2>
+ <div class="row mt32">
+ <div class="col-xs-3">
+ <strong>Start Date:</strong>
+ <p t-esc="data['date_from']"/>
+ </div>
+ <div class="col-xs-3">
+ <strong>Period Length (days)</strong>
+ <p t-esc="data['period_length']"/>
+ </div>
+ </div>
+ <div class="row mb32">
+ <div class="col-xs-3">
+ <strong>Partner's:</strong>
+ <p>
+ <span t-if="data['result_selection'] == 'customer'">Receivable Accounts</span>
+ <span t-if="data['result_selection'] == 'supplier'">Payable Accounts</span>
+ <span t-if="data['result_selection'] == 'customer_supplier'">Receivable and Payable Accounts</span>
+ </p>
+ </div>
+ <div class="col-xs-3">
+ <strong>Target Moves:</strong>
+ <p>
+ <span t-if="data['target_move'] == 'all'">All Entries</span>
+ <span t-if="data['target_move'] == 'posted'">All Posted Entries</span>
+ </p>
+ </div>
+ </div>
+
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>Partners</th>
+ <th class="text-right">
+ <span>Not due</span>
+ </th>
+ <th class="text-right"><span t-esc="data['4']['name']"/></th>
+ <th class="text-right"><span t-esc="data['3']['name']"/></th>
+ <th class="text-right"><span t-esc="data['2']['name']"/></th>
+ <th class="text-right"><span t-esc="data['1']['name']"/></th>
+ <th class="text-right"><span t-esc="data['0']['name']"/></th>
+ <th class="text-right">Total</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr t-foreach="get_partner_lines" t-as="partner">
+ <td>
+ <span t-esc="partner['name'] "/>
+ </td>
+ <td class="text-right">
+ <span t-esc="partner['direction']"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="round(partner['4'], 3)"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="round(partner['3'], 3)"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="round(partner['2'], 3)"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="round(partner['1'], 3)"/>
+ </td>
+ <td class="text-right">
+ <span t-esc="round(partner['0'], 3)" />
+ </td>
+ <td class="text-right">
+ <span t-esc="round(partner['total'], 3)"/>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </t>
+ </t>
+ </template>
+ </data>
+</odoo> \ No newline at end of file
diff --git a/addons/account_reports_xlsx/wizard/__init__.py b/addons/account_reports_xlsx/wizard/__init__.py
new file mode 100755
index 0000000..c94f568
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/__init__.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies(odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from . import account_report_partner_ledger
+from . import account_report_aged_partner_balance
+from . import account_report_general_ledger
+from . import account_financial_report
+from . import account_report_financial
diff --git a/addons/account_reports_xlsx/wizard/account_financial_report.py b/addons/account_reports_xlsx/wizard/account_financial_report.py
new file mode 100755
index 0000000..7ee7826
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_financial_report.py
@@ -0,0 +1,245 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2019-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies(odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from datetime import datetime
+import json
+import datetime
+import io
+from odoo import api, fields, models, _
+from odoo.tools import date_utils
+try:
+ from odoo.tools.misc import xlsxwriter
+except ImportError:
+ import xlsxwriter
+
+
+class AccountingReport(models.TransientModel):
+ _name = "accounting.report.xlsx"
+ _description = "Accounting Report"
+
+ @api.model
+ def _get_account_report(self):
+ reports = []
+ if self._context.get('active_id'):
+ menu = self.env['ir.ui.menu'].browse(self._context.get('active_id')).name
+ reports = self.env['account.financial.report'].search([('name', 'ilike', menu)])
+ return reports and reports[0] or False
+
+ enable_filter = fields.Boolean(string=_('Enable Comparison'))
+ account_report_id = fields.Many2one('account.financial.report', string=_('Account Reports'), required=True,
+ default=_get_account_report)
+ label_filter = fields.Char(string=_('Column Label'),
+ help="This label will be displayed on report to show the balance computed for the given comparison filter.")
+ filter_cmp = fields.Selection([('filter_no', _('No Filters')), ('filter_date', _('Date'))], string=_('Filter by'),
+ required=True, default='filter_no')
+ date_from_cmp = fields.Date(string=_('Start Date'))
+ date_to_cmp = fields.Date(string=_('End Date'))
+ debit_credit = fields.Boolean(string=_('Display Debit/Credit Columns'),
+ help="This option allows you to get more details about the way your balances are computed. Because it is space consuming, we do not allow to use it while doing a comparison.")
+
+ def _build_comparison_context(self, data):
+ result = {}
+ result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
+ result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
+ if data['form']['filter_cmp'] == 'filter_date':
+ result['date_from'] = data['form']['date_from_cmp']
+ result['date_to'] = data['form']['date_to_cmp']
+ result['strict_range'] = True
+ return result
+
+ def check_report(self):
+ res = super(AccountingReport, self).check_report()
+ data = {}
+ data['form'] = \
+ self.read(['account_report_id', 'date_from_cmp', 'date_to_cmp', 'journal_ids', 'filter_cmp', 'target_move'])[0]
+ for field in ['account_report_id']:
+ if isinstance(data['form'][field], tuple):
+ data['form'][field] = data['form'][field][0]
+ comparison_context = self._build_comparison_context(data)
+ res['data']['form']['comparison_context'] = comparison_context
+ return res
+
+ def _print_report(self, data):
+ data['form'].update(self.read(
+ ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter',
+ 'label_filter', 'target_move'])[0])
+ return self.env.ref('account.action_report_financial').report_action(self, data=data, config=False)
+
+ company_id = fields.Many2one('res.company', string=_('Company'), readonly=True,
+ default=lambda self: self.env.user.company_id)
+ journal_ids = fields.Many2many('account.journal', string=_('Journals'), required=True,
+ default=lambda self: self.env['account.journal'].search([]))
+ date_from = fields.Date(string=_('Start Date'))
+ date_to = fields.Date(string=_('End Date'))
+ target_move = fields.Selection([('posted', _('All Posted Entries')),
+ ('all', _('All Entries')),
+ ], string=_('Target Moves'), required=True, default='posted')
+
+ def _build_contexts(self, data):
+ result = {}
+ result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
+ result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
+ result['date_from'] = data['form']['date_from'] or False
+ result['date_to'] = data['form']['date_to'] or False
+ result['strict_range'] = True if result['date_from'] else False
+ return result
+
+ # def _print_report(self, data):
+ # raise NotImplementedError()
+
+ def check_report(self):
+ self.ensure_one()
+ data = {}
+ data['ids'] = self.env.context.get('active_ids', [])
+ data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
+ data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move'])[0]
+ used_context = self._build_contexts(data)
+ data['form']['used_context'] = dict(used_context, lang=self.env.context.get('lang') or 'en_US')
+ return {
+ 'type': 'ir.actions.report',
+ 'data': {'model': 'accounting.report.xlsx',
+ 'options': json.dumps(data, default=date_utils.json_default),
+ 'output_format': 'xlsx',
+ 'report_name': self.account_report_id.name,
+ },
+ 'report_type': 'xlsx'
+ }
+
+ def get_xlsx_report(self, options, response):
+ output = io.BytesIO()
+ workbook = xlsxwriter.Workbook(output, {'in_memory': True})
+ data = {}
+ obj = self.search([('id', '=', options['form']['id'])])
+ data['form'] = obj.read([])[0]
+ comp_dic = {}
+ env_obj = obj.env['report.account.report_financial']
+ data['form']['used_context'] = {}
+ data['form']['used_context']['date_to'] = data['form']['date_to']
+ data['form']['used_context']['date_from'] = data['form']['date_from']
+ data['form']['used_context']['journal_ids'] = data['form']['journal_ids']
+ data['form']['used_context']['state'] = 'posted'
+ data['form']['used_context']['strict_range'] = True
+ comp_dic['state'] = 'posted'
+ comp_dic['journal_ids'] = data['form']['journal_ids']
+ data['form']['comparison_context'] = comp_dic
+ data['account_report_id'] = data['form']['account_report_id']
+ accounting_data = env_obj.get_account_lines(data.get('form'))
+ sheet = workbook.add_worksheet()
+ format1 = workbook.add_format({'font_size': 16, 'align': 'center', 'bg_color': '#D3D3D3', 'bold': True})
+ format1.set_font_color('#000080')
+ format1.set_font_name('Times New Roman')
+ format2 = workbook.add_format({'font_size': 12, 'bold': True, 'bg_color': '#D3D3D3'})
+ format3 = workbook.add_format({'font_size': 10, 'bold': True})
+ format4 = workbook.add_format({'font_size': 10})
+ format6 = workbook.add_format({'font_size': 10, 'bold': True})
+ format7 = workbook.add_format({'font_size': 10})
+ format8 = workbook.add_format({'font_size': 12, 'bold': True, 'bg_color': '#D3D3D3'})
+ format1.set_align('center')
+ format2.set_align('center')
+ format3.set_align('center')
+ format4.set_align('center')
+ format8.set_align('left')
+ sheet.set_column('E:E', 10, format4)
+ sheet.set_column('H:H', 10, format4)
+ sheet.set_column('I:I', 10, format4)
+ sheet.set_column('J:J', 10, format4)
+ currency = self.env.user.company_id.currency_id.symbol
+ format7.set_num_format('0.00 ' + currency)
+ format6.set_num_format('0.00 ' + currency)
+ report_date = datetime.datetime.now().strftime("%Y-%m-%d")
+ sheet.merge_range('A1:B1', _("Report Date"), format6)
+ sheet.merge_range('C1:D1', report_date, format7)
+ if obj.account_report_id.name:
+ sheet.merge_range(3, 0, 4, 9, obj.account_report_id.name, format1)
+ if obj.target_move == 'all':
+ target_moves = 'All entries'
+ else:
+ target_moves = 'All posted entries'
+ sheet.merge_range('A7:B7', _("Target Moves:"), format6)
+ sheet.write('C7', target_moves, format7)
+ if obj.date_from:
+ sheet.write('E7', _("Date From:"), format6)
+ sheet.write('F7', str(obj.date_from), format7)
+ if obj.date_to:
+ sheet.write('H7', _("Date to:"), format6)
+ sheet.write('I7', str(obj.date_to), format7)
+ row_number = 9
+ col_number = 0
+ if obj.debit_credit == 1:
+ sheet.merge_range('A9:G9', _("Name"), format8)
+ sheet.write('H9', _("Debit"), format2)
+ sheet.write('I9', _("Credit"), format2)
+ sheet.write('J9', _("Balance"), format2)
+ for values in accounting_data:
+ if not self.env.user.company_id.parent_id:
+ if values['level'] != 0:
+ pass
+ else:
+ if values['level'] != 0:
+ if values['level'] == 1:
+ sheet.write(row_number, col_number, values['name'], format6)
+ sheet.write(row_number, col_number + 7, values['debit'], format6)
+ sheet.write(row_number, col_number + 8, values['credit'], format6)
+ sheet.write(row_number, col_number + 9, values['balance'], format6)
+ row_number += 1
+ elif not values['account_type'] == 'sum':
+ sheet.write(row_number, col_number, values['name'], format7)
+ sheet.write(row_number, col_number + 7, values['debit'], format7)
+ sheet.write(row_number, col_number + 8, values['credit'], format7)
+ sheet.write(row_number, col_number + 9, values['balance'], format7)
+ row_number += 1
+
+ if not obj.enable_filter and not obj.debit_credit:
+ sheet.merge_range('A9:I9', _("Name"), format8)
+ sheet.write('J9', _("Balance"), format2)
+ for values in accounting_data:
+ if values['level'] != 0:
+ if values['level'] == 1:
+ # assets and liabilities
+ sheet.write(row_number, col_number, values['name'], format6)
+ sheet.write(row_number, col_number + 9, values['balance'], format6)
+ row_number += 1
+ elif not values['account_type'] == 'sum':
+ sheet.write(row_number, col_number + 1, values['name'], format7)
+ # sheet.write(row_number, col_number, values['name'], format7)
+ sheet.write(row_number, col_number + 9, values['balance'], format7)
+ row_number += 1
+ if obj.enable_filter and not obj.debit_credit:
+ sheet.merge_range('A9:H9', _("Name"), format8)
+ sheet.write('I9', _("Balance"), format2)
+ sheet.write('J9', data['form']['label_filter'], format2)
+ for values in accounting_data:
+ if values['level'] != 0:
+ if values['level'] == 1:
+ sheet.write(row_number, col_number, values['name'], format6)
+ sheet.write(row_number, col_number + 8, values['balance'], format6)
+ sheet.write(row_number, col_number + 9, values['balance_cmp'], format6)
+ row_number += 1
+ elif not values['account_type'] == 'sum':
+ sheet.write(row_number, col_number, values['name'], format7)
+ sheet.write(row_number, col_number + 8, values['balance'], format7)
+ sheet.write(row_number, col_number + 9, values['balance_cmp'], format7)
+ row_number += 1
+ workbook.close()
+ output.seek(0)
+ response.stream.write(output.read())
+ output.close() \ No newline at end of file
diff --git a/addons/account_reports_xlsx/wizard/account_financial_report_view.xml b/addons/account_reports_xlsx/wizard/account_financial_report_view.xml
new file mode 100755
index 0000000..6bdf685
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_financial_report_view.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+ <record id="accounting_report_view" model="ir.ui.view">
+ <field name="name">Accounting Report</field>
+ <field name="model">accounting.report.xlsx</field>
+ <field name="inherit_id" ref="account.account_common_report_view"/>
+ <field name="arch" type="xml">
+ <field name="target_move" position="before">
+ <field name="account_report_id" domain="[('parent_id','=',False)]"/>
+ </field>
+ <field name="target_move" position="after">
+ <field name="enable_filter"/>
+ <field name="debit_credit" attrs="{'invisible': [('enable_filter','=',True)]}"/>
+ </field>
+ <field name="journal_ids" position="after">
+ <notebook tabpos="up" colspan="4">
+ <page string="Comparison" name="comparison" attrs="{'invisible': [('enable_filter','=',False)]}">
+ <group>
+ <field name="label_filter" attrs="{'required': [('enable_filter', '=', True)]}"/>
+ <field name="filter_cmp"/>
+ </group>
+ <group string="Dates" attrs="{'invisible':[('filter_cmp', '!=', 'filter_date')]}">
+ <field name="date_from_cmp" attrs="{'required':[('filter_cmp', '=', 'filter_date')]}"/>
+ <field name="date_to_cmp" attrs="{'required':[('filter_cmp', '=', 'filter_date')]}"/>
+ </group>
+ </page>
+ </notebook>
+ </field>
+ <field name="journal_ids" position="replace"/>
+ </field>
+ </record>
+
+ <record id="action_account_report_bs" model="ir.actions.act_window">
+ <field name="name">Balance Sheet</field>
+ <field name="res_model">accounting.report.xlsx</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="accounting_report_view"/>
+ <field name="target">new</field>
+ </record>
+
+ <record id="action_account_report_pl" model="ir.actions.act_window">
+ <field name="name">Profit and Loss</field>
+ <field name="res_model">accounting.report.xlsx</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="accounting_report_view"/>
+ <field name="target">new</field>
+ </record>
+
+ <record id="action_account_report" model="ir.actions.act_window">
+ <field name="name">Financial Reports</field>
+ <field name="res_model">accounting.report.xlsx</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="accounting_report_view"/>
+ <field name="target">new</field>
+ </record>
+
+ <menuitem id="menu_account_report" name="Financial Report" action="action_account_report" parent="account.account_reports_management_menu" sequence="2" groups="account.group_account_user"/>
+
+</odoo>
diff --git a/addons/account_reports_xlsx/wizard/account_report_aged_partner_balance.py b/addons/account_reports_xlsx/wizard/account_report_aged_partner_balance.py
new file mode 100755
index 0000000..4f41c44
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_report_aged_partner_balance.py
@@ -0,0 +1,209 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+import time
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
+from odoo.exceptions import UserError
+import json
+import datetime
+import io
+from odoo import api, fields, models, _
+from odoo.tools import date_utils
+try:
+ from odoo.tools.misc import xlsxwriter
+except ImportError:
+ import xlsxwriter
+
+
+class AccountAgedTrialBalance(models.TransientModel):
+
+ _name = 'account.aged.trial.balance.xlsx'
+ _description = 'Account Aged Trial balance Report'
+
+ period_length = fields.Integer(string=_('Period Length (days)'), required=True, default=30)
+ journal_ids = fields.Many2many('account.journal', string=_('Journals'), required=True)
+ date_from = fields.Date(default=lambda *a: time.strftime('%Y-%m-%d'))
+
+ def _print_report(self, data):
+ res = {}
+ data = self.pre_print_report(data)
+ data['form'].update(self.read(['period_length'])[0])
+ period_length = data['form']['period_length']
+ if period_length<=0:
+ raise UserError(_('You must set a period length greater than 0.'))
+ if not data['form']['date_from']:
+ raise UserError(_('You must set a start date.'))
+
+ start = datetime.strptime(str(data['form']['date_from']), "%Y-%m-%d")
+
+ for i in range(5)[::-1]:
+ stop = start - relativedelta(days=period_length - 1)
+ res[str(i)] = {
+ 'name': (i!=0 and (str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length)) or ('+'+str(4 * period_length))),
+ 'stop': start.strftime('%Y-%m-%d'),
+ 'start': (i!=0 and stop.strftime('%Y-%m-%d') or False),
+ }
+ start = stop - relativedelta(days=1)
+ data['form'].update(res)
+ return self.env.ref('account.action_report_aged_partner_balance').with_context(landscape=True).report_action(self, data=data)
+
+ def pre_print_report(self, data):
+ data['form'].update(self.read(['result_selection'])[0])
+ return data
+
+ result_selection = fields.Selection([('customer', _('Receivable Accounts')),
+ ('supplier', _('Payable Accounts')),
+ ('customer_supplier', _('Receivable and Payable Accounts'))
+ ], string=_("Partner's"), required=True, default='customer')
+
+ company_id = fields.Many2one('res.company', string=_('Company'), readonly=True,
+ default=lambda self: self.env.user.company_id)
+ journal_ids = fields.Many2many('account.journal', string=_('Journals'), required=True,
+ default=lambda self: self.env['account.journal'].search([]))
+ date_from = fields.Date(string=_('Start Date'))
+ date_to = fields.Date(string=_('End Date'))
+ target_move = fields.Selection([('posted', _('All Posted Entries')),
+ ('all', _('All Entries')),
+ ], string=_('Target Moves'), required=True, default='posted')
+
+ def _build_contexts(self, data):
+ result = {}
+ result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
+ result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
+ result['date_from'] = data['form']['date_from'] or False
+ result['date_to'] = data['form']['date_to'] or False
+ result['strict_range'] = True if result['date_from'] else False
+ return result
+
+ # def _print_report(self, data):
+ # raise NotImplementedError()
+
+ def check_report(self):
+ self.ensure_one()
+ data = {}
+ data['ids'] = self.env.context.get('active_ids', [])
+ data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
+ data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move'])[0]
+ used_context = self._build_contexts(data)
+ data['form']['used_context'] = dict(used_context, lang=self.env.context.get('lang') or 'en_US')
+ return {
+ 'type': 'ir.actions.report',
+ 'data': {'model': 'account.aged.trial.balance.xlsx',
+ 'options': json.dumps(data, default=date_utils.json_default),
+ 'output_format': 'xlsx',
+ 'report_name': 'aged partner report',
+ },
+ 'report_type': 'xlsx'
+ }
+
+ def get_xlsx_report(self, options, response):
+ output = io.BytesIO()
+ workbook = xlsxwriter.Workbook(output, {'in_memory': True})
+ env_obj = self.search([('id','=',options['form']['id'])]).env['report.account_reports_xlsx.report_agedpartnerbalance']
+ vals = self.search([('id','=',options['form']['id'])])
+ result_selection = vals.result_selection
+ if result_selection == 'customer':
+ account_type = ['receivable']
+ account_type_name = _("Receivable Accounts")
+ elif result_selection == 'supplier':
+ account_type = ['payable']
+ account_type_name = _("Payable Accounts")
+ else:
+ account_type = ['payable', 'receivable']
+ account_type_name = _("Receivable and Payable Accounts")
+ # sales_person_wise = vals.user_wise_report
+ date_from = options['form']['date_from']
+ target_move = options['form']['target_move']
+ if target_move == 'all':
+ target_move_name = _("All Entries")
+ else:
+ target_move_name = _("All Posted Entries")
+ period_length = vals.period_length
+ # # user_ids = vals.user_ids.ids
+ move_lines, total, dummy = env_obj._get_partner_move_lines(account_type, date_from, target_move, period_length)
+ sheet = workbook.add_worksheet()
+ format1 = workbook.add_format({'font_size': 16, 'align': 'center', 'bg_color': '#D3D3D3', 'bold': True})
+ format1.set_font_color('#000080')
+ format2 = workbook.add_format({'font_size': 10, 'bold': True})
+ format3 = workbook.add_format({'font_size': 10})
+ logged_users = self.env['res.company']._company_default_get('account.account')
+ sheet.write('A1', logged_users.name, format3)
+ sheet.write('A3', _('Start Date:'), format2)
+ sheet.write('B3', date_from, format3)
+ sheet.merge_range('E3:G3', _('Period Length (days):'), format2)
+ sheet.write('H3', period_length, format3)
+ sheet.write('A4', _("Partner's:"), format2)
+ sheet.merge_range('B4:C4', account_type_name, format3)
+ sheet.merge_range('E4:F4', _('Target Moves:'), format2)
+ sheet.merge_range('G4:H4', target_move_name, format3)
+ sheet.set_column(0, 0, 20)
+ # # if sales_person_wise:
+ # # sheet.set_column(1, 1, 20)
+ # # sheet.merge_range(5, 0, 7, 8, "Aged Partner Balance", format1)
+ # # else:
+ sheet.merge_range(5, 0, 7, 7, _("Aged Partner Balance"), format1)
+ row_value = 8
+ column_value = 0
+ # # if sales_person_wise:
+ # # sheet.write(row_value, column_value, "Sales Person", format2)
+ # # column_value += 1
+ sheet.write(row_value, column_value, _("Partners"), format2)
+ sheet.write(row_value, column_value + 1, _("Not due"), format2)
+ sheet.write(row_value, column_value + 2, "0-" + str(period_length), format2)
+ sheet.write(row_value, column_value + 3, str(period_length) + "-" + str(2 * period_length), format2)
+ sheet.write(row_value, column_value + 4, str(2 * period_length) + "-" + str(3 * period_length), format2)
+ sheet.write(row_value, column_value + 5, str(3 * period_length) + "-" + str(4 * period_length), format2)
+ sheet.write(row_value, column_value + 6, "+" + str(4 * period_length), format2)
+ sheet.write(row_value, column_value + 7, _("Total"), format2)
+ row_value += 1
+ column_value = 0
+ if move_lines:
+ sheet.write(row_value, column_value, _("Account Total"), format2)
+ sheet.write(row_value, column_value + 1, total[6], format2)
+ sheet.write(row_value, column_value + 2, total[4], format2)
+ sheet.write(row_value, column_value + 3, total[3], format2)
+ sheet.write(row_value, column_value + 4, total[2], format2)
+ sheet.write(row_value, column_value + 5, total[1], format2)
+ sheet.write(row_value, column_value + 6, total[0], format2)
+ sheet.write(row_value, column_value + 7, total[5], format2)
+ row_value += 1
+ for i in move_lines:
+ partner_ref = self.env['res.partner'].browse(i['partner_id']).ref
+ if partner_ref:
+ partner_ref = "[" + str(partner_ref) + "] "
+ partner_name = partner_ref + str(i['name'])
+ else:
+ partner_name = str(i['name'])
+ sheet.write(row_value, column_value, partner_name, format3)
+ sheet.write(row_value, column_value + 1, i['direction'], format3)
+ sheet.write(row_value, column_value + 2, i['4'], format3)
+ sheet.write(row_value, column_value + 3, i['3'], format3)
+ sheet.write(row_value, column_value + 4, i['2'], format3)
+ sheet.write(row_value, column_value + 5, i['1'], format3)
+ sheet.write(row_value, column_value + 6, i['0'], format3)
+ sheet.write(row_value, column_value + 7, i['total'], format3)
+ row_value += 1
+ workbook.close()
+ output.seek(0)
+ response.stream.write(output.read())
+ output.close() \ No newline at end of file
diff --git a/addons/account_reports_xlsx/wizard/account_report_aged_partner_balance_view.xml b/addons/account_reports_xlsx/wizard/account_report_aged_partner_balance_view.xml
new file mode 100755
index 0000000..69d2298
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_report_aged_partner_balance_view.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+ <record id="account_aged_balance_view" model="ir.ui.view">
+ <field name="name">Aged Partner Balance</field>
+ <field name="model">account.aged.trial.balance.xlsx</field>
+ <field name="arch" type="xml">
+ <form string="Report Options">
+ <separator string="Aged Partner Balance"/>
+ <span> Aged Partner Balance is a more detailed report of your receivables by intervals. Odoo calculates a table of credit balance by start Date. So if you request an interval of 30 days Odoo generates an analysis of creditors for the past month, past two months, and so on. </span>
+ <group col="4">
+ <field name="date_from"/>
+ <field name="period_length"/>
+ <newline/>
+ <field name="result_selection" widget="radio"/>
+ <field name="target_move" widget="radio"/>
+ </group>
+ <field name="journal_ids" required="0" invisible="1"/>
+ <footer>
+ <button name="check_report" string="Print" type="object" default_focus="1" class="oe_highlight"/>
+ <button string="Cancel" class="btn btn-default" special="cancel"/>
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <record id="action_account_aged_balance_view" model="ir.actions.act_window">
+ <field name="name">Aged Partner Balance</field>
+ <field name="res_model">account.aged.trial.balance.xlsx</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="view_mode">tree,form</field>
+ <field name="view_id" ref="account_aged_balance_view"/>
+ <field name="context">{}</field>
+ <field name="target">new</field>
+ </record>
+
+ <menuitem id="menu_aged_trial_balance"
+ name="Aged Partner Balance"
+ action="action_account_aged_balance_view"
+ parent="account.account_reports_management_menu"/>
+
+</odoo>
diff --git a/addons/account_reports_xlsx/wizard/account_report_financial.py b/addons/account_reports_xlsx/wizard/account_report_financial.py
new file mode 100755
index 0000000..d42c4e6
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_report_financial.py
@@ -0,0 +1,181 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+import time
+from odoo import api, models, _
+from odoo.exceptions import UserError
+
+
+class ReportFinancial(models.AbstractModel):
+ _name = 'report.account.report_financial'
+
+ 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.fromkeys(mapping, 0.0)
+ 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 accoutns 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 = self.env['account.financial.report'].search([('id', '=', data['account_report_id'][0])])
+ 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.with_context(data.get('comparison_context'))._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:
+ vals = {
+ 'name': report.name,
+ 'balance': res[report.id]['balance'] * int(report.sign),
+ 'type': 'report',
+ 'level': bool(report.style_overwrite) and report.level,
+ 'account_type': report.type or 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 = {
+ 'name': account.code + ' ' + account.name,
+ 'balance': value['balance'] * int(report.sign) or 0.0,
+ 'type': 'account',
+ '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
+
+ @api.model
+ def get_report_values(self, docids, data=None):
+ if not data.get('form') or not self.env.context.get('active_model') or not self.env.context.get('active_id'):
+ raise UserError(_("Form content is missing, this report cannot be printed."))
+
+ self.model = self.env.context.get('active_model')
+ docs = self.env[self.model].browse(self.env.context.get('active_id'))
+ report_lines = self.get_account_lines(data.get('form'))
+ return {
+ 'doc_ids': self.ids,
+ 'doc_model': self.model,
+ 'data': data['form'],
+ 'docs': docs,
+ 'time': time,
+ 'get_account_lines': report_lines,
+ }
diff --git a/addons/account_reports_xlsx/wizard/account_report_general_ledger.py b/addons/account_reports_xlsx/wizard/account_report_general_ledger.py
new file mode 100755
index 0000000..e74d815
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_report_general_ledger.py
@@ -0,0 +1,240 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
+from odoo.exceptions import UserError
+import json
+import datetime
+import io
+from odoo import api, fields, models, _
+from odoo.tools import date_utils
+try:
+ from odoo.tools.misc import xlsxwriter
+except ImportError:
+ import xlsxwriter
+
+
+class AccountReportGeneralLedger(models.TransientModel):
+ _name = "account.report.general.ledger.xlsx"
+ _description = "General Ledger Report"
+
+ initial_balance = fields.Boolean(string=_('Include Initial Balances'),
+ help='If you selected date, this field allow you to add a row to display the amount of debit/credit/balance that precedes the filter you\'ve set.')
+ sortby = fields.Selection([('sort_date', _('Date')), ('sort_journal_partner', _('Journal & Partner'))], string=_('Sort by'), required=True, default='sort_date')
+ journal_ids = fields.Many2many('account.journal', 'account_report_general_ledger_journal_rel', 'account_id', 'journal_id', string=_('Journals'), required=True)
+
+ def _print_report(self, data):
+ data = self.pre_print_report(data)
+ data['form'].update(self.read(['initial_balance', 'sortby'])[0])
+ if data['form'].get('initial_balance') and not data['form'].get('date_from'):
+ raise UserError(_("You must define a Start Date"))
+ records = self.env[data['model']].browse(data.get('ids', []))
+ return self.env.ref('account.action_report_general_ledger').with_context(landscape=True).report_action(records, data=data)
+
+ 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')
+
+ def pre_print_report(self, data):
+ data['form'].update(self.read(['display_account'])[0])
+ return data
+
+ company_id = fields.Many2one('res.company', string=_('Company'), readonly=True,
+ default=lambda self: self.env.user.company_id)
+ journal_ids = fields.Many2many('account.journal', string=_('Journals'), required=True,
+ default=lambda self: self.env['account.journal'].search([]))
+ date_from = fields.Date(string=_('Start Date'))
+ date_to = fields.Date(string=_('End Date'))
+ target_move = fields.Selection([('posted', _('All Posted Entries')),
+ ('all', _('All Entries')),
+ ], string=_('Target Moves'), required=True, default='posted')
+
+ def _build_contexts(self, data):
+ result = {}
+ result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
+ result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
+ result['date_from'] = data['form']['date_from'] or False
+ result['date_to'] = data['form']['date_to'] or False
+ result['strict_range'] = True if result['date_from'] else False
+ return result
+
+ # def _print_report(self, data):
+ # raise NotImplementedError()
+
+ def check_report(self):
+ self.ensure_one()
+ data = {}
+ data['ids'] = self.env.context.get('active_ids', [])
+ data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
+ data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move'])[0]
+ used_context = self._build_contexts(data)
+ data['form']['used_context'] = dict(used_context, lang=self.env.context.get('lang') or 'en_US')
+ return {
+ 'type': 'ir.actions.report',
+ 'data': {'model': 'account.report.general.ledger.xlsx',
+ 'options': json.dumps(data, default=date_utils.json_default),
+ 'output_format': 'xlsx',
+ 'report_name': 'general ledger report',
+ },
+ 'report_type': 'xlsx'
+ }
+
+ def get_xlsx_report(self, options, response):
+ output = io.BytesIO()
+ workbook = xlsxwriter.Workbook(output, {'in_memory': True})
+ data = {}
+ vals = self.search([('id', '=', options['form']['id'])])
+ data['form'] = vals.read([])[0]
+ data['model'] = 'ir.ui.menu'
+ data['ids'] = []
+ data['form']['used_context'] = {
+ 'date_to': vals.date_to,
+ 'date_from': vals.date_from,
+ 'strict_range': True,
+ 'state': vals.target_move,
+ # 'active_model': 'account.account' if vals.active_account else None,
+ # 'active_ids': [vals.active_account.id] if vals.active_account else None,
+ # 'active_id': vals.active_account.id if vals.active_account else None,
+ 'journal_ids': vals.journal_ids.ids,
+ }
+
+ env_obj = vals.env['report.account.report_generalledger']
+ sortby = data['form'].get('sortby', 'sort_date')
+ display_account = data['form']['display_account']
+ codes = []
+ if data['form'].get('journal_ids', False):
+ codes = [journal.code for journal in
+ self.env['account.journal'].search([('id', 'in', data['form']['journal_ids'])])]
+ # accounts = vals.active_account if vals.active_account else self.env['account.account'].search([])
+ accounts = self.env['account.account'].browse(options['ids']) or self.env['account.account'].search([])
+ init_balance = vals['initial_balance']
+ report_obj = env_obj.with_context(data['form'].get('used_context', {}))._get_account_move_entry(
+ accounts, init_balance, sortby, display_account)
+ sheet = workbook.add_worksheet()
+ format1 = workbook.add_format({'font_size': 16, 'align': 'center', 'bg_color': '#D3D3D3', 'bold': True})
+ format1.set_font_color('#000080')
+ format2 = workbook.add_format({'font_size': 12, 'bold': True, 'bg_color': '#D3D3D3'})
+ format3 = workbook.add_format({'font_size': 10, 'bold': True})
+ format4 = workbook.add_format({'font_size': 10})
+ format6 = workbook.add_format({'font_size': 10, 'bold': True})
+ format7 = workbook.add_format({'font_size': 10, 'align': 'center'})
+ format5 = workbook.add_format({'font_size': 10, 'align': 'right'})
+ format1.set_align('center')
+ format2.set_align('center')
+ format3.set_align('right')
+ format4.set_align('left')
+ codes = []
+ if data['form'].get('journal_ids', False):
+ codes = [journal.code for journal in
+ self.env['account.journal'].search([('id', 'in', data['form']['journal_ids'])])]
+ logged_users = self.env['res.company']._company_default_get('account.account')
+ report_date = datetime.datetime.now().strftime("%Y-%m-%d")
+ sheet.merge_range('M8:N8', _("Report Date"), format3)
+ sheet.merge_range('M9:N9', report_date, format4)
+ sheet.merge_range(1, 0, 1, 14, logged_users.name, format4)
+ sheet.merge_range(3, 0, 4, 14, _("General Ledger Report"), format1)
+ sheet.merge_range('A6:B6', _("Journals :"), format6)
+ row = 6
+ col = 0
+ i = 0
+ for values in codes:
+ sheet.write(row, col + i, values, format7)
+ i += 1
+ if data['form']['display_account'] == 'all':
+ display_account = _('All accounts')
+ elif data['form']['display_account'] == 'movement':
+ display_account = _('With movements')
+ else:
+ display_account = _('With balance not equal to zero')
+
+ if data['form']['target_move'] == 'all':
+ target_moves = _('All entries')
+ else:
+ target_moves = _('All posted entries')
+
+ if data['form']['sortby'] == 'sort_date':
+ sortby = 'Date'
+ else:
+ sortby = 'Journal and partners'
+ if data['form']['date_from']:
+ date_start = data['form']['date_from']
+ else:
+ date_start = ""
+ if data['form']['date_to']:
+ date_end = data['form']['date_to']
+ else:
+ date_end = ""
+ if sortby == 'Date':
+ sheet.write('G8', _("Start Date"), format3)
+ sheet.write('G9', date_start, format4)
+ sheet.write('J8', _("End Date"), format3)
+ sheet.write('J9', date_end, format4)
+ sheet.merge_range('C8:D8', _("Sorted By"), format3)
+ sheet.merge_range('C9:D9', sortby, format4)
+ sheet.merge_range('A8:B8', _("Display Account"), format6)
+ sheet.merge_range('A9:B9', display_account, format7)
+ sheet.merge_range('E8:F8', _("Target Moves"), format6)
+ sheet.merge_range('E9:F9', target_moves, format7)
+ sheet.write('A11', "Date ", format2)
+ sheet.write('B11', "JRNL", format2)
+ sheet.merge_range('C11:D11', _("Partner"), format2)
+ sheet.merge_range('E11:F11', _("Ref"), format2)
+ sheet.merge_range('G11:H11', _("Move"), format2)
+ sheet.merge_range('I11:L11', _("Entry Label"), format2)
+ sheet.write('M11', _("Debit"), format2)
+ sheet.write('N11', _("Credit"), format2)
+ sheet.write('O11', _("Balance"), format2)
+ accounts = self.env['account.account'].search([])
+ row_number = 11
+ col_number = 0
+ for datas in accounts:
+ for values in report_obj:
+ if datas['name'] == values['name'] and datas['company_id'].id == values['company_id']:
+ sheet.write(row_number, col_number, datas['code'], format3)
+ sheet.merge_range(row_number, col_number + 1, row_number, col_number + 11, datas['name'], format6)
+ sheet.write(row_number, col_number + 12,
+ logged_users.currency_id.symbol + ' ' + "{:,}".format(values['debit']), format3)
+ sheet.write(row_number, col_number + 13,
+ logged_users.currency_id.symbol + ' ' + "{:,}".format(values['credit']), format3)
+ sheet.write(row_number, col_number + 14,
+ logged_users.currency_id.symbol + ' ' + "{:,}".format(values['balance']), format3)
+ row_number += 1
+ for lines in values['move_lines']:
+ sheet.write(row_number, col_number, lines['ldate'], format4)
+ sheet.write(row_number, col_number + 1, lines['lcode'], format4)
+ sheet.merge_range(row_number, col_number + 2, row_number, col_number + 3, lines['partner_name'],
+ format4)
+ sheet.merge_range(row_number, col_number + 4, row_number, col_number + 5, lines['lref'],
+ format4)
+ sheet.merge_range(row_number, col_number + 6, row_number, col_number + 7, lines['move_name'],
+ format4)
+ sheet.merge_range(row_number, col_number + 8, row_number, col_number + 11, lines['lname'],
+ format4)
+ sheet.write(row_number, col_number + 12, "{:,}".format(lines['debit']), format5)
+ sheet.write(row_number, col_number + 13, "{:,}".format(lines['credit']), format5)
+ sheet.write(row_number, col_number + 14, "{:,}".format(lines['balance']), format5)
+ row_number += 1
+ workbook.close()
+ output.seek(0)
+ response.stream.write(output.read())
+ output.close() \ No newline at end of file
diff --git a/addons/account_reports_xlsx/wizard/account_report_general_ledger_view.xml b/addons/account_reports_xlsx/wizard/account_report_general_ledger_view.xml
new file mode 100755
index 0000000..ca391d5
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_report_general_ledger_view.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+ <record id="account_report_general_ledger_view" model="ir.ui.view">
+ <field name="name">General Ledger</field>
+ <field name="model">account.report.general.ledger.xlsx</field>
+ <field name="inherit_id" ref="account_common_report_view"/>
+ <field name="arch" type="xml">
+ <data>
+ <xpath expr="//field[@name='target_move']" position="after">
+ <field name="sortby" widget="radio"/>
+ <field name="display_account" widget="radio"/>
+ <field name="initial_balance"/>
+ <newline/>
+ </xpath>
+ </data>
+ </field>
+ </record>
+
+ <record id="action_account_general_ledger_menu" model="ir.actions.act_window">
+ <field name="name">General Ledger</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">account.report.general.ledger.xlsx</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="account_report_general_ledger_view"/>
+ <field name="target">new</field>
+ <field name="binding_model_id" ref="account.model_account_account" />
+ <field name="binding_type">report</field>
+ </record>
+
+ <menuitem
+ id="menu_general_ledger"
+ name="General Ledger"
+ parent="account.account_reports_management_menu"
+ action="action_account_general_ledger_menu"
+ groups="account.group_account_user"
+ />
+
+</odoo>
diff --git a/addons/account_reports_xlsx/wizard/account_report_partner_ledger.py b/addons/account_reports_xlsx/wizard/account_report_partner_ledger.py
new file mode 100755
index 0000000..83ccffc
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/account_report_partner_ledger.py
@@ -0,0 +1,265 @@
+# -*- coding: utf-8 -*-
+######################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# Author: Cybrosys Technologies (odoo@cybrosys.com)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+########################################################################################
+
+from odoo import fields, models,api
+import json
+import datetime
+import io
+from odoo import api, fields, models, _
+from odoo.exceptions import ValidationError
+from odoo.tools import date_utils
+try:
+ from odoo.tools.misc import xlsxwriter
+except ImportError:
+ import xlsxwriter
+
+
+class AccountPartnerLedger(models.TransientModel):
+ _name = "account.report.partner.ledger.xlsx"
+
+ partner_ids = fields.Many2many('res.partner', 'partner_ledger_partner_rel', 'id', 'partner_id', string=_('Partners'))
+
+ def pre_print_report(self, data):
+ data['form'].update(self.read(['result_selection'])[0])
+ return data
+
+ company_id = fields.Many2one('res.company', string=_('Company'), readonly=True,
+ default=lambda self: self.env.user.company_id)
+ journal_ids = fields.Many2many('account.journal', string=_('Journals'), required=True,
+ default=lambda self: self.env['account.journal'].search([]))
+ date_from = fields.Date(string=_('Start Date'))
+ date_to = fields.Date(string=_('End Date'))
+ target_move = fields.Selection([('posted', _('All Posted Entries')),
+ ('all', _('All Entries')),
+ ], string=_('Target Moves'), required=True, default='posted')
+
+ def _print_report(self, data):
+ context = self._context
+ data = self.pre_print_report(data)
+ data['form'].update({'reconciled': self.reconciled, 'amount_currency': self.amount_currency,
+ 'partner_ids': self.partner_ids.ids})
+
+ if context.get('xls_export'):
+ return {
+ 'type': 'ir.actions.report',
+ 'data': {'model': 'account.report.partner.ledger.xlsx',
+ 'options': json.dumps(data, default=date_utils.json_default),
+ 'output_format': 'xlsx',
+ 'report_name': 'maintenance_report',
+ },
+ 'report_type': 'xlsx'
+ }
+ # return self.env.ref('account_reports_xlsx.partner_ledger_xlsx').report_action(self, data=data)
+ else:
+ return self.env.ref('account.action_report_partnerledger').report_action(self, data=data)
+
+ amount_currency = fields.Boolean(_("With Currency"),
+ help="It adds the currency column on report if the currency differs from the company currency.")
+ reconciled = fields.Boolean(_('Reconciled Entries'))
+
+ # def _print_report(self, data):
+ # data = self.pre_print_report(data)
+ # data['form'].update({'reconciled': self.reconciled, 'amount_currency': self.amount_currency})
+ # return self.env.ref('partner_report.action_report_partnerledger').report_action(self, data=data)
+ #
+ result_selection = fields.Selection([('customer', _('Receivable Accounts')),
+ ('supplier', _('Payable Accounts')),
+ ('customer_supplier', _('Receivable and Payable Accounts'))
+ ], string=_("Partner's"), required=True, default='customer')
+
+ def _build_contexts(self, data):
+ result = {}
+ result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
+ result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
+ result['date_from'] = data['form']['date_from'] or False
+ result['date_to'] = data['form']['date_to'] or False
+ result['strict_range'] = True if result['date_from'] else False
+ return result
+
+ # def _print_report(self, data):
+ # raise NotImplementedError()
+
+ def check_report(self):
+ self.ensure_one()
+ data = {}
+ data['ids'] = self.env.context.get('active_ids', [])
+ data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
+ data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move'])[0]
+ context = self._context
+ data = self.pre_print_report(data)
+ data['form'].update({'reconciled': self.reconciled, 'amount_currency': self.amount_currency,
+ 'partner_ids': self.partner_ids.ids})
+ # # ..........................
+ # data = self.pre_print_report(data)
+ # data['form'].update({'reconciled': self.reconciled, 'amount_currency': self.amount_currency})
+ # # ...............................................................
+ used_context = self._build_contexts(data)
+ data['form']['used_context'] = dict(used_context, lang=self.env.context.get('lang') or 'en_US')
+ # return self.with_context(discard_logo_check=True)._print_report(data)
+ return {
+ 'type': 'ir.actions.report',
+ 'data': {'model': 'account.report.partner.ledger.xlsx',
+ 'options': json.dumps(data, default=date_utils.json_default),
+ 'output_format': 'xlsx',
+ 'report_name': 'partner ledger report',
+ },
+ 'report_type': 'xlsx'
+ }
+
+ def get_xlsx_report(self, options, response):
+ output = io.BytesIO()
+ workbook = xlsxwriter.Workbook(output, {'in_memory': True})
+ data = {}
+ data['form'] = options
+ # data['form'] = vals.read([])[0]
+ data['model'] = 'ir.ui.menu'
+ data['ids'] = []
+ data['form']['used_context'] = {}
+ data['form']['used_context']['date_to'] = options['form']['date_to']
+ data['form']['used_context']['date_from'] = options['form']['date_from']
+ data['form']['used_context']['journal_ids'] = options['form']['journal_ids']
+ data['form']['used_context']['state'] = 'posted'
+ data['form']['used_context']['strict_range'] = True
+ env_obj = self.search([('id','=',options['form']['id'])]).env['report.account_reports_xlsx.report_partnerledger']
+ data['computed'] = {}
+ obj_partner = env_obj.env['res.partner']
+ query_get_data = env_obj.env['account.move.line'].with_context(
+ data['form'].get('used_context', {}))._query_get()
+ data['computed']['move_state'] = ['draft', 'posted']
+ if data['form'].get('target_move', 'all') == 'posted':
+ data['computed']['move_state'] = ['posted']
+ result_selection = data['form'].get('result_selection', 'customer')
+ if result_selection == 'supplier':
+ data['computed']['ACCOUNT_TYPE'] = ['payable']
+ elif result_selection == 'customer':
+ data['computed']['ACCOUNT_TYPE'] = ['receivable']
+ else:
+ data['computed']['ACCOUNT_TYPE'] = ['payable', 'receivable']
+ env_obj.env.cr.execute("""
+ SELECT a.id
+ FROM account_account a
+ WHERE a.internal_type IN %s
+ AND NOT a.deprecated""", (tuple(data['computed']['ACCOUNT_TYPE']),))
+ data['computed']['account_ids'] = [a for (a,) in env_obj.env.cr.fetchall()]
+ params = [tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2]
+ reconcile_clause = "" if data['form']['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL '
+ query = """
+ SELECT DISTINCT "account_move_line".partner_id
+ FROM """ + query_get_data[0] + """, account_account AS account, account_move AS am
+ WHERE "account_move_line".partner_id IS NOT NULL
+ AND "account_move_line".account_id = account.id
+ AND am.id = "account_move_line".move_id
+ AND am.state IN %s
+ AND "account_move_line".account_id IN %s
+ AND NOT account.deprecated
+ AND """ + query_get_data[1] + reconcile_clause
+ env_obj.env.cr.execute(query, tuple(params))
+ # # ---------------------Taking only selected partners---------------------------
+ if data['form']['form']['partner_ids']:
+ partner_ids = data['form']['form']['partner_ids']
+ else:
+ partner_ids = [res['partner_id'] for res in env_obj.env.cr.dictfetchall()]
+ # # -----------------------------------------------------------------------------
+ # partner_ids = [res['partner_id'] for res in self.env.cr.dictfetchall()]
+ partners = obj_partner.browse(partner_ids)
+ partners = sorted(partners, key=lambda x: (x.name or ''))
+ # partners = sorted(partners, key=lambda x: (x.uniqueid or '', x.name or ''))
+ for items in partners:
+ partner_currency_balance = 0
+ sheet = workbook.add_worksheet(str(items.name))
+ format1 = workbook.add_format({'font_size': 16, 'align': 'center', 'bg_color': '#D3D3D3', 'bold': True})
+ format1.set_font_color('#000080')
+ format2 = workbook.add_format({'font_size': 12, 'bold': True})
+ format3 = workbook.add_format({'font_size': 10, 'bold': True})
+ format4 = workbook.add_format({'font_size': 10})
+ format5 = workbook.add_format({'font_size': 10})
+ format6 = workbook.add_format({'font_size': 10, 'bold': True})
+ format7 = workbook.add_format({'font_size': 10, 'bold': True})
+ format8 = workbook.add_format({'font_size': 10})
+ format9 = workbook.add_format({'font_size': 10})
+ format10 = workbook.add_format({'font_size': 10, 'bold': True})
+ format1.set_align('center')
+ format3.set_align('center')
+ format4.set_align('center')
+ format6.set_align('right')
+ currency = self.env.user.company_id.currency_id.symbol
+ format7.set_num_format('0.00 ' + currency)
+ format8.set_num_format('0.00 ' + currency)
+ logged_users = self.env['res.company']._company_default_get('account.account')
+ sheet.merge_range('A1:B1', logged_users.name, format4)
+ if data['form']['form']['date_from']:
+ sheet.write('E2', _('Date from:'), format6)
+ sheet.write('F2', data['form']['form']['date_from'], format5)
+ if data['form']['form']['date_to']:
+ sheet.write('E3', _('Date to:'), format6)
+ sheet.write('F3', data['form']['form']['date_to'], format5)
+ sheet.merge_range('I2:J2', _('Target Moves:'), format6)
+ if data['form']['form']['target_move'] == 'all':
+ sheet.merge_range('K2:L2', _('All Entries'), format4)
+ if data['form']['form']['target_move'] == 'posted':
+ sheet.merge_range('K2:L2', _('All Posted Entries'), format4)
+ sheet.merge_range(5, 0, 5, 1, _("Date"), format3)
+ sheet.merge_range(5, 2, 5, 3, _("JRNL"), format3)
+ sheet.merge_range(5, 4, 5, 5, _("Account"), format3)
+ sheet.merge_range(5, 6, 5, 7, _("Ref"), format3)
+ sheet.merge_range(5, 8, 5, 9, _("Debit"), format3)
+ sheet.merge_range(5, 10, 5, 11, _("Credit"), format3)
+ sheet.merge_range(5, 12, 5, 13, _("Balance"), format3)
+ if data['form']['form']['amount_currency']:
+ sheet.merge_range(5, 14, 5, 15, _("Currency"), format3)
+ sheet.merge_range(3, 0, 4, 15, _("Partner Ledger Report"), format1)
+ else:
+ sheet.merge_range(3, 0, 4, 13, _("Partner Ledger Report"), format1)
+ partner_name = ''
+ # if items.uniqueid:
+ # partner_name = str(items.uniqueid)
+ if items.name:
+ partner_name = partner_name + str(items.name)
+ sheet.merge_range(6, 0, 6, 6, partner_name, format2)
+ debit = env_obj._sum_partner(data, items, 'debit')
+ credit = env_obj._sum_partner(data, items, 'credit')
+ balance = env_obj._sum_partner(data, items, 'debit - credit')
+ sheet.merge_range(6, 8, 6, 9, debit, format7)
+ sheet.merge_range(6, 10, 6, 11, credit, format7)
+ sheet.merge_range(6, 12, 6, 13, balance, format7)
+ row_value = 7
+ for values in env_obj._lines(data, items):
+ sheet.merge_range(row_value, 0, row_value, 1, values['date'], format4)
+ sheet.merge_range(row_value, 2, row_value, 3, values['code'], format4)
+ sheet.merge_range(row_value, 4, row_value, 5, values['a_code'], format4)
+ sheet.merge_range(row_value, 6, row_value, 7, values['displayed_name'], format4)
+ sheet.merge_range(row_value, 8, row_value, 9, values['debit'], format8)
+ sheet.merge_range(row_value, 10, row_value, 11, values['credit'], format8)
+ sheet.merge_range(row_value, 12, row_value, 13, values['progress'], format8)
+ if data['form']['form']['amount_currency']:
+ if values['currency_id']:
+ partner_currency = values['currency_id'].symbol
+ format9.set_num_format('0.00 ' + partner_currency)
+ format10.set_num_format('0.00 ' + partner_currency)
+ sheet.merge_range(row_value, 14, row_value, 15, values['amount_currency'], format9)
+ partner_currency_balance += values['amount_currency']
+ sheet.merge_range(6, 14, 6, 15, partner_currency_balance, format10)
+ row_value += 1
+ workbook.close()
+ output.seek(0)
+ response.stream.write(output.read())
+ output.close() \ No newline at end of file
diff --git a/addons/account_reports_xlsx/wizard/partner_ledger_wizard_view.xml b/addons/account_reports_xlsx/wizard/partner_ledger_wizard_view.xml
new file mode 100755
index 0000000..d4d9bf9
--- /dev/null
+++ b/addons/account_reports_xlsx/wizard/partner_ledger_wizard_view.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="account_common_report_view" model="ir.ui.view">
+ <field name="name">Common Report</field>
+ <field name="model">account.common.report</field>
+ <field name="arch" type="xml">
+ <form string="Report Options">
+ <field name="company_id" invisible="1"/>
+ <group col="4">
+ <field name="target_move" widget="radio"/>
+ <field name="date_from"/>
+ <field name="date_to"/>
+ </group>
+ <group>
+ <field name="journal_ids" widget="many2many_tags" options="{'no_create': True}"/>
+ </group>
+ <footer>
+ <button name="check_report" string="Print" type="object" default_focus="1" class="oe_highlight"/>
+ <button string="Cancel" class="btn btn-default" special="cancel" />
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <record id="action_account_common_menu" model="ir.actions.act_window">
+ <field name="name">Common Report</field>
+ <field name="res_model">account.common.report</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="account_common_report_view"/>
+ <field name="target">new</field>
+ </record>
+
+ <record id="account_report_partner_ledger_view" model="ir.ui.view">
+ <field name="name">Partner Ledger</field>
+ <field name="model">account.report.partner.ledger.xlsx</field>
+ <field name="inherit_id" ref="account.account_common_report_view"/>
+ <field name="arch" type="xml">
+ <data>
+ <xpath expr="//field[@name='target_move']" position="after">
+ <field name="result_selection"/>
+ <field name="amount_currency" groups="base.group_multi_currency"/>
+ <newline/>
+ <field name="reconciled"/>
+ <newline/>
+ </xpath>
+ </data>
+ </field>
+ </record>
+
+ <record id="action_view_partner_report" model="ir.actions.act_window">
+ <field name="name">Partner Ledger</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">account.report.partner.ledger.xlsx</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="account_report_partner_ledger_view"/>
+ <field name="target">new</field>
+ <field name="binding_model_id" ref="account.model_account_account" />
+ <field name="binding_type">report</field>
+ </record>
+
+
+<menuitem id="partner_report_child_menu" name="Partner Ledger" action="action_view_partner_report" parent="account.account_reports_management_menu" sequence="100"/>
+</odoo> \ No newline at end of file
diff --git a/addons/banner_sale/__init__.py b/addons/banner_sale/__init__.py
new file mode 100644
index 0000000..9a7e03e
--- /dev/null
+++ b/addons/banner_sale/__init__.py
@@ -0,0 +1 @@
+from . import models \ No newline at end of file
diff --git a/addons/banner_sale/__manifest__.py b/addons/banner_sale/__manifest__.py
new file mode 100644
index 0000000..71be794
--- /dev/null
+++ b/addons/banner_sale/__manifest__.py
@@ -0,0 +1,22 @@
+{
+ 'name': 'Banner in Sale',
+ 'version': '1.0',
+ 'category': 'Sales',
+ 'sequence': 1,
+ 'summary': 'Banner in Sale',
+ 'description': '',
+ 'author': 'Rafi Zadanly',
+ 'website': '',
+ 'depends': ['product_brand_sale', 'coupon'],
+ 'data': [
+ 'security/ir.model.access.csv',
+ 'views/banner.xml',
+ 'views/banner_category.xml',
+ 'views/product_brand.xml',
+ ],
+ 'demo': [],
+ 'css': [],
+ 'installable': True,
+ 'auto_install': False,
+ 'license': '',
+}
diff --git a/addons/banner_sale/models/__init__.py b/addons/banner_sale/models/__init__.py
new file mode 100644
index 0000000..8ff01f5
--- /dev/null
+++ b/addons/banner_sale/models/__init__.py
@@ -0,0 +1,4 @@
+from . import banner
+from . import banner_category
+from . import product_brand
+from . import coupon_program \ No newline at end of file
diff --git a/addons/banner_sale/models/banner.py b/addons/banner_sale/models/banner.py
new file mode 100644
index 0000000..4728452
--- /dev/null
+++ b/addons/banner_sale/models/banner.py
@@ -0,0 +1,16 @@
+from odoo import fields, models
+
+class Banner(models.Model):
+ _name = "banner"
+ _description = "Banner"
+
+ name = fields.Char(string="Name")
+ url_banner = fields.Char(string="URL Banner")
+ status = fields.Selection([
+ ("tayang", "Tayang"),
+ ("tidak tayang", "Tidak tayang")
+ ], string="Status")
+ banner_image = fields.Binary(string="Banner Image")
+ banner_category_id = fields.Many2one('banner.category', string="Banner Category")
+ product_brand_id = fields.Many2one('product.brand', string="Product Brand")
+ coupon_program_id = fields.Many2one('coupon.program', string="Coupon Program") \ No newline at end of file
diff --git a/addons/banner_sale/models/banner_category.py b/addons/banner_sale/models/banner_category.py
new file mode 100644
index 0000000..85dff40
--- /dev/null
+++ b/addons/banner_sale/models/banner_category.py
@@ -0,0 +1,11 @@
+from odoo import fields, models
+
+class BannerCategory(models.Model):
+ _name = "banner.category"
+ _description = "Banner Category"
+
+ name = fields.Char(string="Name")
+ url = fields.Char(string="URL")
+ sub_title = fields.Char(string="Sub Title")
+
+
diff --git a/addons/banner_sale/models/coupon_program.py b/addons/banner_sale/models/coupon_program.py
new file mode 100644
index 0000000..e8d3004
--- /dev/null
+++ b/addons/banner_sale/models/coupon_program.py
@@ -0,0 +1,10 @@
+from odoo import fields, models
+
+class CouponProgram(models.Model):
+ _inherit = "coupon.program"
+
+ banner_ids = fields.One2many(
+ comodel_name="banner",
+ inverse_name="coupon_program_id",
+ string="Banners"
+ ) \ No newline at end of file
diff --git a/addons/banner_sale/models/product_brand.py b/addons/banner_sale/models/product_brand.py
new file mode 100644
index 0000000..b865ed8
--- /dev/null
+++ b/addons/banner_sale/models/product_brand.py
@@ -0,0 +1,10 @@
+from odoo import fields, models
+
+class ProductBrand(models.Model):
+ _inherit = "product.brand"
+
+ banner_ids = fields.One2many(
+ comodel_name="banner",
+ inverse_name="product_brand_id",
+ string="Banners"
+ ) \ No newline at end of file
diff --git a/addons/banner_sale/security/ir.model.access.csv b/addons/banner_sale/security/ir.model.access.csv
new file mode 100644
index 0000000..36c04dd
--- /dev/null
+++ b/addons/banner_sale/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_banner_category,access.banner.category,model_banner_category,,1,1,1,1
+access_banner,access.banner,model_banner,,1,1,1,1 \ No newline at end of file
diff --git a/addons/banner_sale/views/banner.xml b/addons/banner_sale/views/banner.xml
new file mode 100644
index 0000000..4a10f58
--- /dev/null
+++ b/addons/banner_sale/views/banner.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <record id="banner_tree" model="ir.ui.view">
+ <field name="name">banner.tree</field>
+ <field name="model">banner</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="name"/>
+ <field name="banner_category_id"/>
+ <field name="product_brand_id"/>
+ <field name="coupon_program_id"/>
+ <field name="url_banner"/>
+ <field name="status"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="banner_form" model="ir.ui.view">
+ <field name="name">banner.form</field>
+ <field name="model">banner</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet>
+ <group>
+ <group>
+ <field name="name"/>
+ <field name="banner_category_id"/>
+ <field name="product_brand_id"/>
+ <field name="url_banner"/>
+ <field name="status"/>
+ <field name="coupon_program_id"/>
+ </group>
+ <group>
+ <field name="banner_image" widget="image"/>
+ </group>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="banner_action" model="ir.actions.act_window">
+ <field name="name">Banner</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">banner</field>
+ <field name="view_mode">tree,form</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Add Banner!
+ </p>
+ </field>
+ </record>
+
+ <menuitem
+ id="menu_banner"
+ name="Banner"
+ parent="sale.product_menu_catalog"
+ sequence="4"
+ action="banner_action"
+ />
+</odoo> \ No newline at end of file
diff --git a/addons/banner_sale/views/banner_category.xml b/addons/banner_sale/views/banner_category.xml
new file mode 100644
index 0000000..ef6ce0a
--- /dev/null
+++ b/addons/banner_sale/views/banner_category.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <record id="banner_category_tree" model="ir.ui.view">
+ <field name="name">banner.category.tree</field>
+ <field name="model">banner.category</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="name"/>
+ <field name="sub_title"/>
+ <field name="url"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="banner_category_form" model="ir.ui.view">
+ <field name="name">banner.category.form</field>
+ <field name="model">banner.category</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet>
+ <group>
+ <group>
+ <field name="name"/>
+ <field name="sub_title"/>
+ <field name="url"/>
+ </group>
+ <group></group>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="banner_category_action" model="ir.actions.act_window">
+ <field name="name">Banner Category</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">banner.category</field>
+ <field name="view_mode">tree,form</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Add Banner Category!
+ </p>
+ </field>
+ </record>
+
+ <menuitem
+ id="menu_banner_category"
+ name="Banner Category"
+ parent="sale.product_menu_catalog"
+ sequence="4"
+ action="banner_category_action"
+ />
+</odoo> \ No newline at end of file
diff --git a/addons/banner_sale/views/product_brand.xml b/addons/banner_sale/views/product_brand.xml
new file mode 100644
index 0000000..b3ea0ce
--- /dev/null
+++ b/addons/banner_sale/views/product_brand.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <record id="product_brand_form_view_inherit" model="ir.ui.view">
+ <field name="name">product.brand.inherited</field>
+ <field name="model">product.brand</field>
+ <field name="inherit_id" ref="product_brand_sale.product_brand_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//page[@name='products']" position="after">
+ <page string="Banners" name="banners">
+ <field name="banner_ids">
+ <form>
+ <group>
+ <field name="banner_image" widget="image" style="max-width:240px"/>
+ <field name="name"/>
+ <field name="banner_category_id"/>
+ <field name="url_banner"/>
+ <field name="status"/>
+ <field name="coupon_program_id"/>
+ </group>
+ </form>
+ </field>
+ </page>
+ </xpath>
+ </field>
+ </record>
+</odoo> \ No newline at end of file
diff --git a/addons/mail_reply_to_sender/__init__.py b/addons/mail_reply_to_sender/__init__.py
new file mode 100644
index 0000000..cde864b
--- /dev/null
+++ b/addons/mail_reply_to_sender/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import models
diff --git a/addons/mail_reply_to_sender/__manifest__.py b/addons/mail_reply_to_sender/__manifest__.py
new file mode 100644
index 0000000..6c98f92
--- /dev/null
+++ b/addons/mail_reply_to_sender/__manifest__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# This file is part of OpenERP. The COPYRIGHT file at the top level of
+# this module contains the full copyright notices and license terms.
+{
+ 'name': 'Mail Reply To sender/reply to field(mail template)',
+ 'version': '1.0',
+ 'author': 'PPTS [India] Pvt.Ltd.',
+ 'website': 'https://www.pptssolutions.com',
+ 'license': 'LGPL-3',
+ 'category': 'Mail',
+ 'support': 'business@pptservices.com',
+ 'summary': 'Mail Reply to the sender',
+ 'description': """ This module provides a functionality to reply to sender's email address or the mail address given in 'Reply To' field of email template""",
+ 'depends': [
+ 'mail',
+ ],
+ 'data': [
+ ],
+ 'installable': True,
+ 'application': False,
+ 'images': ['static/description/banner.png'],
+}
diff --git a/addons/mail_reply_to_sender/models/__init__.py b/addons/mail_reply_to_sender/models/__init__.py
new file mode 100644
index 0000000..f024d4e
--- /dev/null
+++ b/addons/mail_reply_to_sender/models/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+from . import ir_mail_server
diff --git a/addons/mail_reply_to_sender/models/ir_mail_server.py b/addons/mail_reply_to_sender/models/ir_mail_server.py
new file mode 100644
index 0000000..d471587
--- /dev/null
+++ b/addons/mail_reply_to_sender/models/ir_mail_server.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+from odoo import models,api
+
+class MailComposer(models.TransientModel):
+ _inherit = 'mail.compose.message'
+
+ def get_mail_values(self, res_ids):
+ res = super(MailComposer, self).get_mail_values(res_ids)
+ if self.composition_mode == 'comment':
+ mail_reply_to = self.template_id.reply_to
+ if mail_reply_to:
+ for f, x in res.items():
+ if 'reply_to' not in x:
+ x['reply_to'] = mail_reply_to
+ return res
diff --git a/addons/mail_reply_to_sender/static/description/banner.png b/addons/mail_reply_to_sender/static/description/banner.png
new file mode 100644
index 0000000..c64571c
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/banner.png
Binary files differ
diff --git a/addons/mail_reply_to_sender/static/description/icon.png b/addons/mail_reply_to_sender/static/description/icon.png
new file mode 100644
index 0000000..0c90ea3
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/icon.png
Binary files differ
diff --git a/addons/mail_reply_to_sender/static/description/index.html b/addons/mail_reply_to_sender/static/description/index.html
new file mode 100644
index 0000000..a2e60b2
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/index.html
@@ -0,0 +1,87 @@
+<section class="oe_container">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan" style="color:#875A7B;">Mail Reply to sender/reply to(Email template field)</h2>
+ <p class="oe_mt32 text-center">
+ This module provides a functionality to reply to sender's email address or the mail address given in 'Reply To' field of email template. This will replace default <b>catchall@domain.com</b>
+ </p>
+ </div>
+</section>
+
+
+<section class="oe_container">
+ <div class="oe_row oe_spaced">
+ <div class="oe_span12">
+ <h4 class="oe_mt32 oe_mb8 text-center">
+ <b>Step:</b>
+ </h4>
+ <p class="oe_mt32 text-center">
+ Go to the Email templates and add any email address(or use placeholder) in reply to field. If the sender address and reply to address are same reply will be sent to the sender.
+ If the sender address and reply to is different reply will be sent to reply to address.
+ </p>
+ <img class="oe_picture oe_screenshot" src="mail_reply_to_1.png">
+ <br/>
+ <img class="oe_picture oe_screenshot" src="mail_reply_to_2.png">
+ </div>
+ </div>
+</section>
+
+<section class="oe_container">
+ <div class="oe_spaced" style="padding-right:10%;padding-left:10%;">
+ <div class="oe_span12">
+ <h3 style="margin-top:20px;font-size:30px;font-weight:500;text-align:center;">Looking for support? We are here to help you!</h3>
+ <p class="oe_mt32" style="font-size:14px;">
+ As an official <b>Odoo Gold Partner</b>, <a href="http://www.pptssolutions.com">PPTS</a>, with its 9+ years of Expertise and Experienced niche in Odoo Projects, can assist you in enhancing your business processes and work system by
+ automating and streamlining the business functionalities through the advanced and customized latest technological solutions.
+ </p>
+ </div>
+ <div class="oe_span12">
+ <h3 style="margin-top:20px;font-size:25px;font-weight:500;">Our Odoo Services</h3>
+ <div class="row" style="margin-top:20px;">
+ <div style="width: 33%; text-align: center;">
+ <img src="ppts/odoo-erp-customization.svg" style="width: 100px; height:100px; margin-bottom: 20px;" class="center-block"/>
+ <p><a href="https://www.pptssolutions.com/odoo-erp-implementation/" style="font-size:14px;">Odoo ERP Implementation</a></p>
+ </div>
+ <div style="width: 33%; text-align: center;">
+ <img src="ppts/odoo-erp-implementation.svg" style="width: 100px; height:100px; margin-bottom: 20px;" class="center-block"/>
+ <p><a href="https://www.pptssolutions.com/odoo-erp-customization/" style="font-size:14px;">Odoo ERP Customization</a></p>
+ </div>
+ <div style="width: 33%; text-align: center;">
+ <img src="ppts/odoo-erp-integration.svg" style="width: 100px; height:100px; margin-bottom: 20px;" class="center-block"/>
+ <p><a href="https://www.pptssolutions.com/odoo-erp-integration/" style="font-size:14px;">Odoo ERP Integration</a></p>
+ </div>
+ </div>
+ <div class="row" style="margin-top:30px;">
+ <div style="width: 60%;text-align: center;">
+ <img src="ppts/odoo-erp-migration.svg" style="width: 100px; height:100px; margin-bottom: 20px;" class="center-block"/>
+ <p><a href="https://www.pptssolutions.com/odoo-erp-migration/" style="font-size:14px;">Odoo ERP Migration</a></p>
+ </div>
+ <div style="width: 15%;text-align: center;">
+ <img src="ppts/odoo-erp-support.svg" style="width: 100px; height:100px; margin-bottom: 20px;" class="center-block"/>
+ <p><a href="https://www.pptssolutions.com/odoo-erp-support-and-maintenance/" style="font-size:14px;">Odoo ERP Support</a></p>
+ </div>
+ </div>
+ </div>
+ <div class="oe_span12">
+ <h3 style="margin-top:20px;font-size:25px;font-weight:500;">Other Services</h3>
+ <ul style="font-size: 14px;line-height: 28px;">
+ <li>Artificial Intelligence</li>
+ <li>Data Analytics </li>
+ <li>Web Application Development</li>
+ <li>Mobile Application Development </li>
+ </ul>
+ </div>
+ <div class="oe_span12">
+ <h3 style="margin-top:20px;font-size:20px;font-weight:500;text-align:center;"> Feel free to contact us for any queries</h3>
+ <p style="text-align:center;font-size:20px;text-decoration: underline;">
+ <a style="background: #fffd67;" href="https://www.pptssolutions.com/contact-us/">Contact Us Now</a></p>
+ </div>
+ <div class="oe_span12" style="margin-top:30px;">
+ <p style="font-weight:600;font-size:14px;"><i>Stay Connected with Us! Let's Grow Together!</i></p>
+ <p style="font-size: 14px; margin-top: 10px;">Email us to: <a href="mailto:rajeshrao.r@pptservices.com"><i class="fa fa-envelope-o"/> rajeshrao.r@pptservices.com</a></p>
+ <p style="font-size: 14px; margin-top: 10px;">Skype ID:<a href="skype:live:.cid.f085c4326c1bd3d?chat"> <i class="fa fa-skype"/> Rajesh Rao</a></p>
+ <p style="font-size: 14px; margin-top: 10px;">Explore more about us: www.pptssolutions.com </p>
+ </div>
+ </div>
+</section>
+<section class="oe_container oe_separator">
+</section>
diff --git a/addons/mail_reply_to_sender/static/description/mail_reply_to_1.png b/addons/mail_reply_to_sender/static/description/mail_reply_to_1.png
new file mode 100644
index 0000000..8295469
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/mail_reply_to_1.png
Binary files differ
diff --git a/addons/mail_reply_to_sender/static/description/mail_reply_to_2.png b/addons/mail_reply_to_sender/static/description/mail_reply_to_2.png
new file mode 100644
index 0000000..0dda799
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/mail_reply_to_2.png
Binary files differ
diff --git a/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-customization.svg b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-customization.svg
new file mode 100644
index 0000000..213a3cc
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-customization.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" data-name="Layer 1" viewBox="0 0 98.56 77.9"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}.cls-3{fill:url(#linear-gradient-3);}.cls-4{fill:url(#linear-gradient-4);}.cls-5{fill:url(#linear-gradient-5);}.cls-6,.cls-7,.cls-8{fill:none;stroke-miterlimit:10;}.cls-6{stroke-width:0.71px;stroke:url(#linear-gradient-6);}.cls-7,.cls-8{stroke-width:0.93px;}.cls-7{stroke:url(#linear-gradient-7);}.cls-8{stroke:url(#linear-gradient-8);}.cls-9{fill:url(#linear-gradient-9);}.cls-10{opacity:0.5;fill:url(#linear-gradient-10);}</style><linearGradient id="linear-gradient" x1="30.9" y1="26.96" x2="50.13" y2="26.96" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e54f25"></stop><stop offset="1" stop-color="#e57925"></stop></linearGradient><linearGradient id="linear-gradient-2" x1="44.07" y1="38.94" x2="60.93" y2="38.94" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-3" x1="34.5" y1="51.9" x2="44.58" y2="51.9" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-4" x1="30.9" y1="38.95" x2="74.12" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-5" x1="59.91" y1="50.46" x2="68.13" y2="50.46" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-6" x1="13.56" y1="38.95" x2="91.46" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-7" x1="72.55" y1="11.45" x2="85.32" y2="11.45" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-8" x1="0" y1="59.93" x2="23.42" y2="59.93" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-9" x1="83.64" y1="56.15" x2="98.56" y2="56.15" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-10" x1="0.34" y1="25.02" x2="27.49" y2="25.02" xlink:href="#linear-gradient"></linearGradient></defs><title>odoo_page</title><path class="cls-1" d="M31,21.3l2.88,5a.71.71,0,0,0,.45.34l2.68.67,9.22,9.22,1-1-9.36-9.36a.77.77,0,0,0-.34-.19L35,25.35l-2.45-4.29,2.1-2.1,4.3,2.45L39.56,24a.81.81,0,0,0,.19.34l9.36,9.36,1-1-9.21-9.21-.68-2.69a.7.7,0,0,0-.34-.45l-5-2.88a.71.71,0,0,0-.86.12l-2.88,2.87A.73.73,0,0,0,31,21.3Z"></path><path class="cls-2" d="M60.93,31.53,45.09,47.37l-1-1L59.91,30.51Z"></path><path class="cls-3" d="M42.32,47.93a.72.72,0,0,0-.62-.35H37.38a.72.72,0,0,0-.62.35l-2.16,3.6a.75.75,0,0,0,0,.74l2.16,3.6a.72.72,0,0,0,.62.35H41.7a.72.72,0,0,0,.62-.35l2.16-3.6a.75.75,0,0,0,0-.74Zm-1,6.85h-3.5L36.06,51.9,37.79,49h3.5L43,51.9Z"></path><path class="cls-4" d="M65.46,34.62a8.59,8.59,0,0,0,8.37-10.73.71.71,0,0,0-.87-.52.61.61,0,0,0-.33.19L68.14,28l-3.55-1.19L63.4,23.3l4.48-4.49a.71.71,0,0,0,0-1,.84.84,0,0,0-.33-.19,8.63,8.63,0,0,0-10.47,6.24A9.08,9.08,0,0,0,56.82,26,8.73,8.73,0,0,0,57,27.67L41.23,43.43a8.64,8.64,0,1,0,7,8.47A8,8,0,0,0,48,50.21l3.78-3.77,1.65,1.65a.72.72,0,0,0,1,0l.36-.36A.81.81,0,0,1,56,48.87h0l-.36.36a.72.72,0,0,0,0,1l8.59,8.59a5.81,5.81,0,0,0,8.25-8.18l0,0L63.81,42a.72.72,0,0,0-1,0l-.36.36a.81.81,0,0,1-1.14,0,.8.8,0,0,1,0-1.14h0l.36-.36a.72.72,0,0,0,0-1L60,38.22l3.77-3.78A8,8,0,0,0,65.46,34.62ZM68.29,59.1a4.41,4.41,0,0,1-1.53-.28l5.62-5.62a4.36,4.36,0,0,1-2.55,5.62A4.51,4.51,0,0,1,68.29,59.1ZM60.13,40.39a2.25,2.25,0,0,0,3.17,3.16l8.08,8.09a3.2,3.2,0,0,1,.25.27l-6.16,6.16a3.2,3.2,0,0,1-.27-.25l-8.09-8.09a2.25,2.25,0,0,0-3.17-3.16l-1.15-1.15L59,39.24ZM63,33.15,46.71,49.47a.71.71,0,0,0-.19.69,7.25,7.25,0,1,1-5.24-5.24.7.7,0,0,0,.68-.19L58.29,28.4a.72.72,0,0,0,.19-.68A7.17,7.17,0,0,1,63.65,19a7.51,7.51,0,0,1,2.22-.21l-3.8,3.8a.72.72,0,0,0-.17.74l1.44,4.32a.72.72,0,0,0,.45.45l4.32,1.44a.72.72,0,0,0,.74-.17l3.8-3.8c0,.14,0,.27,0,.41a7.16,7.16,0,0,1-7.13,7.2A7.35,7.35,0,0,1,63.72,33a.73.73,0,0,0-.69.18h0Z"></path><path class="cls-5" d="M68.13,53.55l-1,1-7.2-7.2,1-1Z"></path><circle class="cls-6" cx="52.51" cy="38.95" r="38.59"></circle><circle class="cls-7" cx="78.94" cy="11.45" r="5.92"></circle><circle class="cls-8" cx="11.71" cy="59.93" r="11.24"></circle><circle class="cls-9" cx="91.1" cy="56.15" r="7.46"></circle><circle class="cls-10" cx="13.92" cy="25.02" r="13.57"></circle></svg> \ No newline at end of file
diff --git a/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-implementation.svg b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-implementation.svg
new file mode 100644
index 0000000..2ea9689
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-implementation.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" data-name="Layer 1" viewBox="0 0 95.41 77.9"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}.cls-3{fill:url(#linear-gradient-3);}.cls-4,.cls-5,.cls-6{fill:none;stroke-miterlimit:10;}.cls-4{stroke-width:0.71px;stroke:url(#linear-gradient-4);}.cls-5,.cls-6{stroke-width:0.93px;}.cls-5{stroke:url(#linear-gradient-5);}.cls-6{stroke:url(#linear-gradient-6);}.cls-7{fill:url(#linear-gradient-7);}.cls-8{opacity:0.5;fill:url(#linear-gradient-8);}</style><linearGradient id="linear-gradient" x1="20.73" y1="38.95" x2="63.95" y2="38.95" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e54f25"></stop><stop offset="1" stop-color="#e57925"></stop></linearGradient><linearGradient id="linear-gradient-2" x1="44.03" y1="59.71" x2="45.71" y2="59.71" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-3" x1="41.5" y1="28.32" x2="48.25" y2="28.32" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-4" x1="3.39" y1="38.95" x2="81.29" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-5" x1="1.08" y1="15.32" x2="13.85" y2="15.32" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-6" x1="71.98" y1="53.78" x2="95.41" y2="53.78" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-7" x1="0" y1="58.87" x2="14.93" y2="58.87" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-8" x1="62.66" y1="19.06" x2="89.81" y2="19.06" xlink:href="#linear-gradient"></linearGradient></defs><title>odoo_page</title><path class="cls-1" d="M48.42,60.55l-.16-.12a.84.84,0,0,1,.45-1.56H62.23V34.23H54.51a.56.56,0,0,0-.58.35c-.23.44-.48.86-.73,1.28a.88.88,0,0,1-1.38.37c-.57-.32-1.13-.67-1.72-1a.59.59,0,0,0-.47,0,9.8,9.8,0,0,0-1.13.66.5.5,0,0,0-.23.37c0,.64,0,1.29,0,1.94s-.29,1.05-1.08,1.06H45.75v3.88h6.4c.92,0,1.17.25,1.17,1.18v4.37l.44,0c1.21,0,2.42,0,3.62,0,.68,0,1,.31,1,1v4.81a.86.86,0,0,1-1,1H47.54c-.66,0-1-.33-1-1,0-1.57,0-3.15,0-4.72,0-.72.3-1,1-1,1.19,0,2.39,0,3.58,0h.44V44.89H38.15v3.85h3.13c.35,0,.7,0,1,0a.82.82,0,0,1,.85.82q0,2.55,0,5.1c0,.53-.38.83-1,.83H32.39c-.7,0-1-.31-1-1,0-1.57,0-3.15,0-4.72,0-.72.31-1,1-1,1.32,0,2.64,0,4,0V44.19c0-.72.31-1,1-1,2.17,0,4.33,0,6.53,0V39.29H42.51a.89.89,0,0,1-1-1c0-.65,0-1.29,0-1.94a.44.44,0,0,0-.3-.47,6.79,6.79,0,0,1-1-.59.47.47,0,0,0-.61,0c-.55.33-1.11.65-1.67,1a.86.86,0,0,1-1.32-.34c-.28-.47-.54-1-.83-1.42a.54.54,0,0,0-.37-.25H27.62l-.12,0V51.79c0,.92-.26,1.16-1.19,1.17a8.55,8.55,0,0,0-1.43,0,2.93,2.93,0,0,0-2.44,3.16,3,3,0,0,0,2.95,2.69H40.92c.66,0,1.13.43,1,1-.08.27-.37.49-.57.73H24.8a.6.6,0,0,0-.11-.06,4.71,4.71,0,0,1-4-4.82c0-6.2,0-12.4,0-18.6,0-1.66,0-3.32,0-5a4.53,4.53,0,0,1,1.91-3.72,5.82,5.82,0,0,1,4.14-.87.78.78,0,0,1,.69.83c0,.35,0,.7,0,1.06V32.5h7.12l-.36-.63c-.43-.75-.34-1.12.4-1.55.52-.3,1-.61,1.57-.9a.42.42,0,0,0,.24-.47,7.57,7.57,0,0,1,0-1.26.41.41,0,0,0-.24-.47c-.59-.33-1.18-.66-1.76-1A.82.82,0,0,1,34.14,25q1.23-2.16,2.48-4.31a.84.84,0,0,1,1.23-.32c.49.27,1,.54,1.46.85a.78.78,0,0,0,1.11,0,2.63,2.63,0,0,1,.77-.43.46.46,0,0,0,.32-.51c0-.66,0-1.32,0-2a.84.84,0,0,1,.94-.94c1.61,0,3.23,0,4.85,0a.85.85,0,0,1,1,1q0,1,0,2a.41.41,0,0,0,.27.45,4.93,4.93,0,0,1,1,.59.53.53,0,0,0,.68,0c.53-.33,1.08-.64,1.64-.95a.85.85,0,0,1,1.31.35q1.21,2.1,2.42,4.2a.83.83,0,0,1-.34,1.28c-.53.32-1.06.64-1.6.93a.55.55,0,0,0-.36.65c.06.38,0,.78,0,1.18a.58.58,0,0,0,.22.41c.54.35,1.11.65,1.67,1a.88.88,0,0,1,.38,1.37l-.44.8c2.61,0,5.14,0,7.67,0a1.14,1.14,0,0,1,1.15.6V60.55Zm5.33-29.06-1.76-1a1,1,0,0,1-.48-1,18.26,18.26,0,0,0,0-2.22c0-.6,0-.81.57-1.13l1.67-1-1.68-2.92c-.61.35-1.18.67-1.75,1a1,1,0,0,1-1.2-.1A18.48,18.48,0,0,0,47.25,22c-.52-.26-.68-.43-.68-1s0-1.29,0-2H43.19v2c0,.57-.18.76-.69,1a16.17,16.17,0,0,0-1.85,1.07,1,1,0,0,1-1.27.07l-1.7-1L36,25.14l1.75,1a1,1,0,0,1,.5,1,17.64,17.64,0,0,0,0,2.18c0,.69,0,.87-.63,1.23L36,31.5l1.69,2.92,1.72-1a.93.93,0,0,1,1.23.09,15.76,15.76,0,0,0,1.77,1c.64.32.78.46.78,1.19v1.82h3.38V35.67c0-.64.14-.81.71-1.09a13.84,13.84,0,0,0,1.75-1c.62-.43.78-.47,1.44-.09l1.6.92,1.57-2.7ZM25.8,29.19a3,3,0,0,0-3.36,3q0,9.95,0,19.9a.76.76,0,0,0,0,.16,11.63,11.63,0,0,1,1.61-.74,15.4,15.4,0,0,1,1.74-.29ZM41.48,50.45H33.1v3.33h8.38Zm15.21,0h-8.4v3.33h8.39c0-.09,0-.16,0-.22Z"></path><path class="cls-2" d="M44.63,60.55l-.21-.14a.8.8,0,0,1-.35-.95.84.84,0,0,1,1.6,0,.82.82,0,0,1-.34,1l-.2.14Z"></path><path class="cls-3" d="M41.5,28.3a3.38,3.38,0,1,1,3.37,3.39A3.39,3.39,0,0,1,41.5,28.3Zm5.07,0A1.69,1.69,0,1,0,44.88,30,1.71,1.71,0,0,0,46.57,28.31Z"></path><circle class="cls-4" cx="42.34" cy="38.95" r="38.59"></circle><circle class="cls-5" cx="7.46" cy="15.32" r="5.92"></circle><circle class="cls-6" cx="83.7" cy="53.78" r="11.24"></circle><circle class="cls-7" cx="7.46" cy="58.87" r="7.46"></circle><circle class="cls-8" cx="76.23" cy="19.06" r="13.57"></circle></svg> \ No newline at end of file
diff --git a/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-integration.svg b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-integration.svg
new file mode 100644
index 0000000..bdeac3c
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-integration.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" data-name="Layer 1" viewBox="0 0 95.26 91.11"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2,.cls-3,.cls-4{fill:none;stroke-miterlimit:10;}.cls-2{stroke-width:0.71px;stroke:url(#linear-gradient-2);}.cls-3,.cls-4{stroke-width:0.93px;}.cls-3{stroke:url(#linear-gradient-3);}.cls-4{stroke:url(#linear-gradient-4);}.cls-5{fill:url(#linear-gradient-5);}.cls-6{opacity:0.5;fill:url(#linear-gradient-6);}</style><linearGradient id="linear-gradient" x1="22.13" y1="38.95" x2="65.35" y2="38.95" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e54f25"></stop><stop offset="1" stop-color="#e57925"></stop></linearGradient><linearGradient id="linear-gradient-2" x1="4.79" y1="38.95" x2="82.69" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-3" x1="77.17" y1="70.54" x2="89.94" y2="70.54" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-4" x1="71.84" y1="17.23" x2="95.26" y2="17.23" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-5" x1="0" y1="15.29" x2="14.93" y2="15.29" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-6" x1="22.02" y1="77.54" x2="49.16" y2="77.54" xlink:href="#linear-gradient"></linearGradient></defs><title>odoo_page</title><path class="cls-1" d="M50.52,60.66A14.88,14.88,0,0,1,40.4,34.82a15.16,15.16,0,0,1,4.84-3,8.31,8.31,0,0,1-.07,1.49l-.33.15a13.52,13.52,0,0,0,.82,24.94,13.35,13.35,0,0,0,4.77.87h0A13.5,13.5,0,0,0,62,38.63l-1.13-1.81-1.5,1.51-.33.33h0c-.22-1-.46-2.07-.68-3.11l-.39-1.74-.11-.52,3.07.72,2.27.54-.17.17-.22.21-.07.07-.06.08c-.79,1-.19,1.86.29,2.56l0,0,.07.1a15.26,15.26,0,0,1,2.31,6.93A14.83,14.83,0,0,1,50.52,60.66ZM42.29,46a8.24,8.24,0,0,1,.07-1.22c0-.1,0-.2,0-.3.27-.11.54-.24.8-.37A13.52,13.52,0,0,0,41.36,19.3a13.32,13.32,0,0,0-4.3-.71,13.59,13.59,0,0,0-10.19,4.56,13.74,13.74,0,0,0-1.14,16.42l1.16,1.76,1.47-1.52.31-.34,0,0,.15.61h0c0,.19.09.39.14.59.26,1,.53,2.1.78,3.13l.25,1-.11,0-1.69-.36L26.16,44h0l-1.48-.3.07-.07.28-.29a1.86,1.86,0,0,0,0-2.48l-.46-.67,0,0-.25-.35a14.42,14.42,0,0,1-1.45-3.24,14.87,14.87,0,0,1,14.24-19.3,14.37,14.37,0,0,1,4.24.63,14.88,14.88,0,0,1,1,28.16Z"></path><circle class="cls-2" cx="43.74" cy="38.95" r="38.59"></circle><circle class="cls-3" cx="83.55" cy="70.54" r="5.92"></circle><circle class="cls-4" cx="83.55" cy="17.23" r="11.24"></circle><circle class="cls-5" cx="7.46" cy="15.29" r="7.46"></circle><circle class="cls-6" cx="35.59" cy="77.54" r="13.57"></circle></svg> \ No newline at end of file
diff --git a/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-migration.svg b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-migration.svg
new file mode 100644
index 0000000..c107d9e
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-migration.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" data-name="Layer 1" viewBox="0 0 89.34 91.11"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}.cls-3{fill:url(#linear-gradient-3);}.cls-4{fill:url(#linear-gradient-4);}.cls-5{fill:url(#linear-gradient-5);}.cls-6{fill:url(#linear-gradient-6);}.cls-7{fill:url(#linear-gradient-7);}.cls-8{fill:url(#linear-gradient-8);}.cls-10,.cls-11,.cls-9{fill:none;stroke-miterlimit:10;}.cls-9{stroke-width:0.71px;stroke:url(#linear-gradient-9);}.cls-10,.cls-11{stroke-width:0.93px;}.cls-10{stroke:url(#linear-gradient-10);}.cls-11{stroke:url(#linear-gradient-11);}.cls-12{fill:url(#linear-gradient-12);}.cls-13{opacity:0.5;fill:url(#linear-gradient-13);}</style><linearGradient id="linear-gradient" x1="45.02" y1="58.6" x2="50.76" y2="58.6" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e54f25"></stop><stop offset="1" stop-color="#e57925"></stop></linearGradient><linearGradient id="linear-gradient-2" x1="36.31" y1="38.95" x2="59.67" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-3" x1="26.11" y1="28.86" x2="35.34" y2="28.86" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-4" x1="60.65" y1="49.04" x2="69.87" y2="49.04" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-5" x1="26.02" y1="48.84" x2="35.21" y2="48.84" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-6" x1="60.77" y1="29.05" x2="69.96" y2="29.05" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-7" x1="45.2" y1="19.31" x2="50.97" y2="19.31" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-8" x1="43.19" y1="38.91" x2="52.87" y2="38.91" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-9" x1="9.04" y1="38.95" x2="86.94" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-10" x1="5.33" y1="25.28" x2="18.1" y2="25.28" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-11" x1="0" y1="76.98" x2="23.42" y2="76.98" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-12" x1="74.42" y1="16.19" x2="89.34" y2="16.19" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-13" x1="56.85" y1="77.54" x2="83.99" y2="77.54" xlink:href="#linear-gradient"></linearGradient></defs><title>odoo_page</title><path class="cls-1" d="M47.42,63.28l-.4-.13a2.83,2.83,0,0,1-2-2.47,2.75,2.75,0,0,1,1.64-2.8.56.56,0,0,0,.4-.63c0-1.08,0-2.15,0-3.23a.37.37,0,0,1,0-.11h1.49c0,.12,0,.26,0,.39,0,1,0,2,0,3a.56.56,0,0,0,.23.43,2.84,2.84,0,0,1-.44,5.46l-.08.05Zm.51-4.09a1.26,1.26,0,1,0,1.28,1.26A1.31,1.31,0,0,0,47.93,59.19Z"></path><path class="cls-2" d="M51.48,30.56l1-1a1.52,1.52,0,0,1,2.37-.06L57.43,32a1.45,1.45,0,0,1,0,2.32c-.32.33-.67.62-1,.93l.07.13H58a1.46,1.46,0,0,1,1.67,1.65c0,1.17,0,2.34.05,3.52A1.46,1.46,0,0,1,58.1,42.2c-.5,0-1,0-1.5,0l0,.13,1,.94a1.55,1.55,0,0,1,0,2.41c-.84.84-1.67,1.69-2.52,2.52a1.49,1.49,0,0,1-2.3,0L51.6,47.16v1.6A1.47,1.47,0,0,1,50,50.35l-3.85,0a1.44,1.44,0,0,1-1.53-1.51c0-.5,0-1,0-1.66l-1.13,1.12a1.51,1.51,0,0,1-2.34,0l-2.61-2.49a1.45,1.45,0,0,1,0-2.32c.32-.33.66-.64,1.1-1.07H38.21c-1.32,0-1.82-.46-1.84-1.77l-.06-3.42a1.47,1.47,0,0,1,1.53-1.62c.5,0,1,0,1.52,0l.07-.12-1-1a1.44,1.44,0,0,1,0-2.31L41,29.68a1.51,1.51,0,0,1,2.28-.05c.36.33.71.67,1.15,1.1,0-.52,0-.93,0-1.34,0-1.29.52-1.83,1.79-1.84s2.38,0,3.57,0a1.42,1.42,0,0,1,1.58,1.54c0,.49,0,1,0,1.47ZM46,29.08V30.2c0,1.77.09,1.46-1.27,2.08a.94.94,0,0,1-1.19-.21c-.45-.45-.91-.87-1.33-1.27l-2.64,2.63c.2.22.42.47.65.7,1,1,1.3.91.58,2.39a.92.92,0,0,1-.92.65H38V40.9a7.54,7.54,0,0,0,1.17,0,1.56,1.56,0,0,1,2,1.19c.19.64.26.81-.23,1.3s-.87.85-1.32,1.28l2.8,2.67c.29-.32.57-.58.8-.88a1.54,1.54,0,0,1,2.27-.54c.57.34.73.4.73,1.06s0,1.22,0,1.79H50V47.41c0-1-.18-1.27,1.06-1.68a.68.68,0,0,0,.21-.1.88.88,0,0,1,1.17.16c.45.45.93.89,1.37,1.31l2.66-2.65c-.26-.25-.53-.54-.81-.81-1-1-1-1-.53-2.28a1,1,0,0,1,1-.7c.63,0,1.25,0,1.85,0V37H56.89c-1.65.05-1.53,0-2-1.2-.25-.59-.26-.79.19-1.23s.9-.87,1.36-1.32l-2.79-2.65c-.28.31-.52.58-.78.84-1.08,1.08-.92,1.11-2.34.53a1,1,0,0,1-.7-1c0-.61,0-1.22,0-1.86l-.39,0Z"></path><path class="cls-3" d="M31,30.2a3,3,0,0,1-3.34.41,2.8,2.8,0,0,1-1.38-3.43,2.88,2.88,0,0,1,3.35-1.83,2.77,2.77,0,0,1,2.23,2.93.82.82,0,0,0,.46.9c1,.62,2,1.28,3,1.94l-.84,1.31Zm-2-.83a1.26,1.26,0,1,0-1.32-1.26A1.28,1.28,0,0,0,29,29.37Z"></path><path class="cls-4" d="M60.65,46.77l.84-1.31,3.42,2.17A10.38,10.38,0,0,1,66.42,47a2.83,2.83,0,0,1,2.74,4.63,2.93,2.93,0,0,1-3.34.72,2.75,2.75,0,0,1-1.69-2.85.67.67,0,0,0-.37-.76C62.72,48.12,61.71,47.45,60.65,46.77ZM67,51a1.26,1.26,0,1,0-1.33-1.26A1.29,1.29,0,0,0,67,51Z"></path><path class="cls-5" d="M34.37,45.24l.84,1.32c-.88.56-1.71,1.13-2.58,1.64a1.4,1.4,0,0,0-.9,1.51,2.62,2.62,0,0,1-2.15,2.65,2.89,2.89,0,0,1-3.23-1.42,2.82,2.82,0,0,1,.5-3.33,2.93,2.93,0,0,1,3.54-.42l.45.29Zm-4.16,4.43A1.3,1.3,0,0,0,29,48.35a1.26,1.26,0,1,0-.16,2.52A1.29,1.29,0,0,0,30.21,49.67Z"></path><path class="cls-6" d="M65.14,30.41l-3.53,2.25-.84-1.32.93-.6c.61-.39,1.21-.82,1.85-1.17a1.09,1.09,0,0,0,.68-1.24,2.73,2.73,0,0,1,2.07-2.78,2.91,2.91,0,0,1,3.28,1.32,2.83,2.83,0,0,1-.44,3.41,2.94,2.94,0,0,1-3.59.4C65.41,30.6,65.29,30.5,65.14,30.41Zm2-3.39a1.26,1.26,0,1,0,1.3,1.29A1.3,1.3,0,0,0,67.1,27Z"></path><path class="cls-7" d="M48.85,24H47.33c0-.92,0-1.8,0-2.68,0-.67,0-1.17-.79-1.55a2.62,2.62,0,0,1-1.2-3.23,2.9,2.9,0,0,1,5.58.36A2.79,2.79,0,0,1,49.32,20a.59.59,0,0,0-.41.67c0,1.06,0,2.12,0,3.18A1.47,1.47,0,0,1,48.85,24Zm-.76-5.31a1.26,1.26,0,1,0-1.32-1.27A1.3,1.3,0,0,0,48.09,18.71Z"></path><path class="cls-8" d="M48.05,34.16a4.75,4.75,0,1,1-4.86,4.73A4.74,4.74,0,0,1,48.05,34.16Zm0,7.93a3.19,3.19,0,1,0-3.26-3.2A3.21,3.21,0,0,0,48,42.09Z"></path><circle class="cls-9" cx="47.99" cy="38.95" r="38.59"></circle><circle class="cls-10" cx="11.71" cy="25.28" r="5.92"></circle><circle class="cls-11" cx="11.71" cy="76.98" r="11.24"></circle><circle class="cls-12" cx="81.88" cy="16.19" r="7.46"></circle><circle class="cls-13" cx="70.42" cy="77.54" r="13.57"></circle></svg> \ No newline at end of file
diff --git a/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-support.svg b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-support.svg
new file mode 100644
index 0000000..315b925
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/ppts/odoo-erp-support.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" data-name="Layer 1" viewBox="0 0 97.58 91.11"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}.cls-3{fill:url(#linear-gradient-3);}.cls-4{fill:url(#linear-gradient-4);}.cls-5{fill:url(#linear-gradient-5);}.cls-6{fill:url(#linear-gradient-6);}.cls-7{fill:url(#linear-gradient-7);}.cls-8{fill:url(#linear-gradient-8);}.cls-9{fill:url(#linear-gradient-9);}.cls-10,.cls-11,.cls-12{fill:none;stroke-miterlimit:10;}.cls-10{stroke-width:0.71px;stroke:url(#linear-gradient-10);}.cls-11,.cls-12{stroke-width:0.93px;}.cls-11{stroke:url(#linear-gradient-11);}.cls-12{stroke:url(#linear-gradient-12);}.cls-13{fill:url(#linear-gradient-13);}.cls-14{opacity:0.5;fill:url(#linear-gradient-14);}</style><linearGradient id="linear-gradient" x1="64.38" y1="58.45" x2="68.49" y2="58.45" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e54f25"></stop><stop offset="1" stop-color="#e57925"></stop></linearGradient><linearGradient id="linear-gradient-2" x1="26.06" y1="19.44" x2="30.16" y2="19.44" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-3" x1="29.48" y1="39.29" x2="65.07" y2="39.29" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-4" x1="27.43" y1="24.23" x2="28.8" y2="24.23" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-5" x1="27.43" y1="27.66" x2="28.8" y2="27.66" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-6" x1="27.43" y1="31.08" x2="28.8" y2="31.08" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-7" x1="65.75" y1="46.82" x2="67.12" y2="46.82" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-8" x1="65.75" y1="50.24" x2="67.12" y2="50.24" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-9" x1="65.75" y1="53.66" x2="67.12" y2="53.66" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-10" x1="8.33" y1="38.95" x2="86.22" y2="38.95" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-11" x1="61.64" y1="7.21" x2="74.41" y2="7.21" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-12" x1="74.15" y1="60.5" x2="97.58" y2="60.5" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-13" x1="0" y1="37.92" x2="14.93" y2="37.92" xlink:href="#linear-gradient"></linearGradient><linearGradient id="linear-gradient-14" x1="18.65" y1="77.54" x2="45.79" y2="77.54" xlink:href="#linear-gradient"></linearGradient></defs><title>odoo_page</title><path class="cls-1" d="M66.43,56.4a2.05,2.05,0,1,0,2.06,2.05A2.05,2.05,0,0,0,66.43,56.4Zm0,2.74a.69.69,0,0,1-.68-.69.69.69,0,0,1,1.37,0A.69.69,0,0,1,66.43,59.14Z"></path><path class="cls-2" d="M30.16,19.44a2.05,2.05,0,1,0-2.05,2.06A2.05,2.05,0,0,0,30.16,19.44Zm-2.73,0a.68.68,0,0,1,.68-.68.69.69,0,1,1-.68.68Z"></path><path class="cls-3" d="M62.82,44.51l-1.35-2.7a13.93,13.93,0,0,0,.73-1.76l2.87-.95V31.27l-2.87-1a14.44,14.44,0,0,0-.73-1.75l1.35-2.71-5.53-5.53-2.71,1.35a14.44,14.44,0,0,0-1.75-.73l-1-2.86H44l-.95,2.86a14.57,14.57,0,0,0-1.76.73l-2.7-1.35-5.54,5.53,1.35,2.71a16.24,16.24,0,0,0-.73,1.75l-2.86,1V39.1l2.86.95a13.68,13.68,0,0,0,.73,1.74l-.88,1.61H29.48V57.08h4.79V55h5.19l2,2h3.71v.69a2.74,2.74,0,0,0,5.47,0v-.69h4.8a2.05,2.05,0,0,0,2-2A2.09,2.09,0,0,0,57,53.66a2,2,0,0,0,0-2.74,2.1,2.1,0,0,0,.5-1.05Zm-27-3a13.53,13.53,0,0,1-.92-2.18L34.8,39l-2.58-.86V32.26l2.58-.87.1-.33a13.53,13.53,0,0,1,.92-2.18l.16-.31-1.22-2.45L38.9,22l2.44,1.23.31-.17a14.42,14.42,0,0,1,2.18-.91l.34-.1L45,19.44h5.86L51.75,22l.33.1a14.42,14.42,0,0,1,2.18.91l.31.16L57,22l4.14,4.14-1.22,2.45.16.31A14.42,14.42,0,0,1,61,31.06l.1.33,2.59.87v5.85L61.12,39l-.11.34a14.42,14.42,0,0,1-.91,2.18l-.16.31,1.22,2.44-4,4.08a1.47,1.47,0,0,0-.1-.13,2.09,2.09,0,0,0,.53-1.37,2.05,2.05,0,0,0-1.87-2,12.32,12.32,0,1,0-15.45,0H34.37L36,41.81Zm20.35,10.8a.69.69,0,0,1-.68.69H50a.68.68,0,0,1-.68-.69.67.67,0,0,1,.68-.68h5.48A.68.68,0,0,1,56.17,52.29ZM46.31,35.18h3.3l1.08-1.08v-3a1.37,1.37,0,0,1,1.37,1.37v3.13l-2.33,2.34H46.19l-2.34-2.34V32.45a1.37,1.37,0,0,1,1.37-1.37v3Zm.28,4.11h2.74V42H46.59Zm4.1-.4,2.74-2.74v-3.7a2.74,2.74,0,0,0-2.74-2.74H49.33v3.82l-.29.29H46.87l-.28-.29V29.71H45.22a2.74,2.74,0,0,0-2.74,2.74v3.7l2.74,2.74V42H43.57l0,0a8.21,8.21,0,1,1,8.94,0H50.69Zm6.85-3.71a9.58,9.58,0,1,0-15,7.89l-1,1a10.95,10.95,0,1,1,13.23-.29,2.07,2.07,0,0,0-.68-1.22A9.53,9.53,0,0,0,57.54,35.18Zm-2,11a.69.69,0,0,1,.68.69.68.68,0,0,1-.68.68H50a.67.67,0,0,1-.68-.68.68.68,0,0,1,.68-.69ZM50,50.24a.69.69,0,0,1,0-1.37h5.48a.69.69,0,0,1,0,1.37ZM32.9,55.71h-2v-11h2Zm9.18,0-2-2.05H34.27V46.13H41.4l2.73-2.73h8.62a.68.68,0,0,1,0,1.36H45.62L42.68,47.7l1,1,1.57-1.57v8.61ZM48,59.14a1.37,1.37,0,0,1-1.37-1.37V46.13h1.49a2.27,2.27,0,0,0-.12.69,2,2,0,0,0,.53,1.37,2,2,0,0,0,0,2.73,2,2,0,0,0,0,2.74,2,2,0,0,0,.84,3.3v.81A1.38,1.38,0,0,1,48,59.14Zm7.53-3.43H50a.68.68,0,0,1,0-1.36h5.48a.68.68,0,0,1,0,1.36Z"></path><path class="cls-4" d="M27.43,23.55H28.8v1.37H27.43Z"></path><path class="cls-5" d="M27.43,27H28.8v1.37H27.43Z"></path><path class="cls-6" d="M27.43,30.39H28.8v1.37H27.43Z"></path><path class="cls-7" d="M65.75,46.13h1.37V47.5H65.75Z"></path><path class="cls-8" d="M65.75,49.55h1.37v1.37H65.75Z"></path><path class="cls-9" d="M65.75,53h1.37v1.37H65.75Z"></path><circle class="cls-10" cx="47.27" cy="38.95" r="38.59"></circle><circle class="cls-11" cx="68.03" cy="7.21" r="5.92"></circle><circle class="cls-12" cx="85.87" cy="60.5" r="11.24"></circle><circle class="cls-13" cx="7.46" cy="37.92" r="7.46"></circle><circle class="cls-14" cx="32.22" cy="77.54" r="13.57"></circle></svg> \ No newline at end of file
diff --git a/addons/mail_reply_to_sender/static/description/reply_to.png b/addons/mail_reply_to_sender/static/description/reply_to.png
new file mode 100644
index 0000000..e51166b
--- /dev/null
+++ b/addons/mail_reply_to_sender/static/description/reply_to.png
Binary files differ
diff --git a/addons/product_brand_sale/README.md b/addons/product_brand_sale/README.md
new file mode 100644
index 0000000..538048d
--- /dev/null
+++ b/addons/product_brand_sale/README.md
@@ -0,0 +1,32 @@
+Product Brand in Sales
+======================
+
+Installation
+============
+- www.odoo.com/documentation/14.0/setup/install.html
+- Install our custom addon
+
+License
+=======
+GNU AFFERO GENERAL PUBLIC LICENSE, Version 3 (AGPLv3)
+(http://www.gnu.org/licenses/agpl.html)
+
+Bug Tracker
+===========
+Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
+
+Credits
+=======
+* Cybrosys Techno Solutions <https://www.cybrosys.com>
+
+
+Developer: Afras Habis - odoo@cybrosys.com
+ Version14 Muhammed Nafih - odoo@cybrosys.com
+
+Maintainer
+----------
+
+This module is maintained by Cybrosys Technologies.
+
+For support and more information, please visit https://www.cybrosys.com.
+
diff --git a/addons/product_brand_sale/__init__.py b/addons/product_brand_sale/__init__.py
new file mode 100644
index 0000000..7f0969e
--- /dev/null
+++ b/addons/product_brand_sale/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/addons/product_brand_sale/__manifest__.py b/addons/product_brand_sale/__manifest__.py
new file mode 100644
index 0000000..94bb198
--- /dev/null
+++ b/addons/product_brand_sale/__manifest__.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+###################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
+# This program is free software: you can modify
+# it under the terms of the GNU Affero General Public License (AGPL) as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+###################################################################################
+{
+ 'name': 'Product Brand in Sale',
+ 'version': '14.0.1.0.0',
+ 'category': 'Sales',
+ 'summary': 'Product Brand in Sales',
+ 'description': 'Product Brand in Sales,brand,sale, odoo13',
+ 'author': 'Cybrosys Techno Solutions',
+ 'company': 'Cybrosys Techno Solutions',
+ 'maintainer': 'Cybrosys Techno Solutions',
+ 'images': ['static/description/banner.png'],
+ 'website': 'https://www.cybrosys.com',
+ 'depends': ['sale_management'],
+ 'data': [
+ 'views/brand_views.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'license': 'AGPL-3',
+ 'installable': True,
+ 'auto_install': False,
+ 'application': False,
+
+}
diff --git a/addons/product_brand_sale/doc/RELEASE_NOTES.md b/addons/product_brand_sale/doc/RELEASE_NOTES.md
new file mode 100644
index 0000000..e69996c
--- /dev/null
+++ b/addons/product_brand_sale/doc/RELEASE_NOTES.md
@@ -0,0 +1,6 @@
+## Module <product_brand_sale>
+
+#### 29.11.2019
+#### Version 14.0.1.0.0
+#### ADD
+Initial Commit
diff --git a/addons/product_brand_sale/models/__init__.py b/addons/product_brand_sale/models/__init__.py
new file mode 100644
index 0000000..79145f8
--- /dev/null
+++ b/addons/product_brand_sale/models/__init__.py
@@ -0,0 +1 @@
+from . import brand \ No newline at end of file
diff --git a/addons/product_brand_sale/models/brand.py b/addons/product_brand_sale/models/brand.py
new file mode 100644
index 0000000..a49c284
--- /dev/null
+++ b/addons/product_brand_sale/models/brand.py
@@ -0,0 +1,36 @@
+from odoo import models, fields, api
+
+
+class ProductBrand(models.Model):
+ _inherit = 'product.template'
+
+ brand_id = fields.Many2one('product.brand', string='Brand')
+
+class BrandProduct(models.Model):
+ _name = 'product.brand'
+ _description = "Product Brand"
+
+ name = fields.Char(String="Name")
+ brand_image = fields.Binary()
+ member_ids = fields.One2many('product.template', 'brand_id')
+ product_count = fields.Char(String='Product Count', compute='get_count_products', store=True)
+ negara_asal = fields.Char(string="Negara Asal")
+ short_desc = fields.Text(string="Short Description")
+
+ @api.depends('member_ids')
+ def get_count_products(self):
+ self.product_count = len(self.member_ids)
+
+
+class BrandPivot(models.Model):
+ _inherit = 'sale.report'
+
+ brand_id = fields.Many2one('product.brand', string='Brand')
+
+ def _query(self):
+ res = super(BrandPivot, self)._query()
+ query = res.split('t.categ_id as categ_id,', 1)
+ query = query[0] + 't.categ_id as categ_id,t.brand_id as brand_id,' + query[1]
+ split = query.split('t.categ_id,', 1)
+ res = split[0] + 't.categ_id,t.brand_id,' + split[1]
+ return res
diff --git a/addons/product_brand_sale/security/ir.model.access.csv b/addons/product_brand_sale/security/ir.model.access.csv
new file mode 100644
index 0000000..939dcdf
--- /dev/null
+++ b/addons/product_brand_sale/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_product_brand,access_product_brand,model_product_brand,,1,1,1,1 \ No newline at end of file
diff --git a/addons/product_brand_sale/static/description/banner.png b/addons/product_brand_sale/static/description/banner.png
new file mode 100644
index 0000000..4077005
--- /dev/null
+++ b/addons/product_brand_sale/static/description/banner.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/icon.png b/addons/product_brand_sale/static/description/icon.png
new file mode 100644
index 0000000..d672816
--- /dev/null
+++ b/addons/product_brand_sale/static/description/icon.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/1.jpeg b/addons/product_brand_sale/static/description/images/1.jpeg
new file mode 100644
index 0000000..ccb8e15
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/1.jpeg
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/2.jpeg b/addons/product_brand_sale/static/description/images/2.jpeg
new file mode 100644
index 0000000..2625f77
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/2.jpeg
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/3.jpeg b/addons/product_brand_sale/static/description/images/3.jpeg
new file mode 100644
index 0000000..5dfdf2c
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/3.jpeg
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/4.jpeg b/addons/product_brand_sale/static/description/images/4.jpeg
new file mode 100644
index 0000000..ec8264c
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/4.jpeg
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/5.jpeg b/addons/product_brand_sale/static/description/images/5.jpeg
new file mode 100644
index 0000000..e10c287
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/5.jpeg
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/6.jpeg b/addons/product_brand_sale/static/description/images/6.jpeg
new file mode 100644
index 0000000..529143e
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/6.jpeg
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/checked.png b/addons/product_brand_sale/static/description/images/checked.png
new file mode 100644
index 0000000..578cedb
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/checked.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/cybrosys.png b/addons/product_brand_sale/static/description/images/cybrosys.png
new file mode 100644
index 0000000..d76b5ba
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/cybrosys.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand1.png b/addons/product_brand_sale/static/description/images/productbrand1.png
new file mode 100644
index 0000000..23be892
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand1.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand2.png b/addons/product_brand_sale/static/description/images/productbrand2.png
new file mode 100644
index 0000000..c309298
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand2.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand3.png b/addons/product_brand_sale/static/description/images/productbrand3.png
new file mode 100644
index 0000000..f3b1d71
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand3.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand4.png b/addons/product_brand_sale/static/description/images/productbrand4.png
new file mode 100644
index 0000000..c7d40f9
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand4.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand5.png b/addons/product_brand_sale/static/description/images/productbrand5.png
new file mode 100644
index 0000000..6530977
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand5.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand6.png b/addons/product_brand_sale/static/description/images/productbrand6.png
new file mode 100644
index 0000000..a00b9cf
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand6.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/images/productbrand7.png b/addons/product_brand_sale/static/description/images/productbrand7.png
new file mode 100644
index 0000000..149dcd7
--- /dev/null
+++ b/addons/product_brand_sale/static/description/images/productbrand7.png
Binary files differ
diff --git a/addons/product_brand_sale/static/description/index.html b/addons/product_brand_sale/static/description/index.html
new file mode 100644
index 0000000..a687151
--- /dev/null
+++ b/addons/product_brand_sale/static/description/index.html
@@ -0,0 +1,327 @@
+<div class="row" style="margin: 0;position: relative;color: #000;background-position: center;background: #ffffff;border-bottom: 1px solid #e4e4e4;text-align: center; margin: auto; display: flex;justify-content: center;"> <a href="https://www.cybrosys.com/" target="_blank"><img src="images/cybrosys.png" style=" width: 293px; padding: 1rem 0rem; margin: auto" alt="cybrosys-logo"></a> </div>
+<div class="row" style="margin:75px 0;position: relative;color: #000;background-position: center;background: #ffffff;border-bottom: 1px solid #e4e4e4; padding-bottom: 30px;">
+ <div class="col-md-7 col-sm-12 col-xs-12" style="padding: 0px">
+ <div style=" margin: 0 0 0px;padding: 20px 0 10;font-size: 23px;line-height: 35px;font-weight: 400;color: #000;border-top: 1px solid rgba(255,255,255,0.1);border-bottom: 1px solid rgba(255,255,255,0.11);text-align: left;">
+ <h1 style="font-size: 39px;font-weight: 600;margin: 0px !important;">Product Brand in Sales</h1>
+ </div>
+ <h2 style="font-weight: 600;font-size: 1.8rem;margin-top: 15px;">Key Highlights</h2>
+ <ul style=" padding: 0 1px; list-style: none; ">
+ <li style="display: flex;align-items: center;padding: 8px 0;font-size: 18px;"><i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Manage the Product Brands Easily</li>
+ </ul>
+ </div>
+ <div class="col-md-5 col-sm-12 col-xs-12"> <img src="images/task_timer.gif" class="img-responsive" alt=""> </div>
+</div>
+<div>
+ <section class="oe_container" style="padding: 1rem 0rem 1rem; background-color: #ffffff !important;">
+ <div class="row py-4 px-3">
+ <div class="w-100" style="padding-top:30px;padding-bottom:45px;border-radius: 10px;">
+ <ul role="tablist" class="nav nav-pills justify-content-center" data-tabs="tabs" id="pills-tab" style="border: none;background: unset;">
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true" class="nav-link active show" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400;text-align: center;
+ color: #fff;">Overview </a> </li>
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #d31c22;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a id="pills-home-tab" data-toggle="pill" href="#pills-home1" role="tab" aria-controls="pills-home" aria-selected="true" class="nav-link " style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center;
+ color: #fff;" >Features </a> </li>
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center;
+ color: #fff;">Screenshots </a> </li>
+ <li class="nav-item mr-1 mb-3" style="font-size: 1.05rem;font-weight: 400;transition: all .15s ease;color: #ffffff;background-color: #d31c22;box-shadow: 0 4px 6px rgba(50,50,93,.11), 0 1px 3px rgba(0,0,0,.08);border: 0;font-family: 'Open Sans',sans-serif;width: 140px;border-radius: 0.30rem;"> <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-video" role="tab" aria-controls="pills-profile" aria-selected="false" style="color: #000000;line-height: 33px;border: 0;border-radius: .25rem;font-weight: 400; text-align: center;
+ color: #fff;">Video </a> </li>
+ </ul>
+ <div class="tab-content" id="pills-tabContent"
+ style="padding-top: 30px; padding-bottom: 30px; padding: 30px;">
+ <div class="px-3 pt-1 tab-pane fade active show" id="pills-home" role="tabpanel" aria-labelledby="
+ pills-home-tab">
+ <!-- Overview-->
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Overview</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <h3 class="oe_slogan" style="text-align: center;font-size: 19px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 31px;font-weight: 400;letter-spacing: .5px;margin-bottom: 21px;">
+ This module allows the odoo users to manage their product brands easily .
+ </h3>
+ </div>
+ <div class="px-3 pt-1 tab-pane fade " id="pills-home1" role="tabpanel" aria-labelledby="
+ pills-home-tab">
+ <!-- feature tab-->
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Product Brand</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <ul>
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Easy adding of products to Product Brand.
+ </li>
+ </ul>
+ <ul>
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Product Brand inside Products.
+ </li>
+ </ul>
+ <ul>
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Group By Product Brand.
+ </li>
+ </ul>
+ <ul>
+ <li class="mb8" style="font-family: Roboto;color: #000;list-style-type: square;font-size: 19px;line-height: 50px; background-color: #3a34380d;padding-left: 20px;border-radius: 7px;list-style: none;">
+ <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Product Brand in Pivot view.
+ </li>
+ </ul>
+ </div>
+ <!-- Screenshot tab-->
+ <div class="px-3 tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" >
+ <div class="tab-pane">
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Screenshots</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <div>
+ <section class="oe_container">
+ <div id="demo" class="row carousel slide mb32" data-ride="carousel">
+ <div class="carousel-inner">
+ <div class="carousel-item active" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i> Product Brand Menu</h3>
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/productbrand1.png"> </div>
+ </div>
+ </div>
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i> Create a new Product Brand . We can add products directly from here itself.</h3>
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/productbrand2.png"> </div>
+ </div>
+ </div>
+
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+ <h3 class="mb32 alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px; "> <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i> Also we can add the brand inside the product form.</h3>
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/productbrand3.png"> </div>
+ </div>
+ </div>
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i> Product Brand in Pivot view</h3>
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/productbrand6.png"> </div>
+ </div>
+ </div>
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16" style="float: left;">
+ <h3 class="alert" style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;"> <i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i> Filtered by Product Brand</h3>
+ <div style=""> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/productbrand7.png"> </div>
+ </div>
+ </div>
+ </div>
+ <a class="carousel-control-prev" href="#demo" data-slide="prev" style="left:-25px;width: 35px;color: #000;"> <span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span> </a> <a class="carousel-control-next" href="#demo" data-slide="next" style="right:-25px;width: 35px;color: #000;"> <span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span> </a>
+ </div>
+ </section>
+ </div>
+ </div>
+ </div>
+ <div class="px-3 pt-1 tab-pane fade" id="pills-video" role="tabpanel" aria-labelledby="
+ pills-home-tab">
+ <!-- Video-->
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Video</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <center>
+ <p>Product Brand Manager</p>
+ <!--<a href="https://www.youtube.com/watch?v=57QWXrMYe84&feature=youtu.be" target="_blank"> <img src="addon-youtube.png" style="width:80%;"></a>-->
+ <div class="s_panel_video" data-video-id="7PFB7FpMFyM?rel=0" style="cursor:pointer;">
+ <img class="img-fluid s_tooltip_tabs_tooltip_image s_figure_link pb0" src="images/task_timer_youtube.png" alt="Cybrosys Cover Video" style="max-width:100%;">
+ </div>
+ </center>
+ </div>
+ <!-- faq tab-->
+ <div class="px-2 px-lg-4 pt-3 tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">
+ <ul class="list-unstyled">
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section class="oe_container" style="padding: 2rem 3rem 1rem;">
+ <h2 style="font-weight: 600;text-align: center;margin-bottom: 25px;width: 100%;">Suggested Products</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <div id="demo1" class="row carousel slide" data-ride="carousel">
+ <!-- The slideshow -->
+ <div class="carousel-inner">
+ <div class="carousel-item active" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/sale_discount_total/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/1.jpeg"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/12.0/sale_promotion/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/2.jpeg"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/export_stockinfo_xls/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/3.jpeg"> </div>
+ </a>
+ </div>
+ </div>
+ <div class="carousel-item" style="min-height: 0px;">
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/12.0/website_sale_advanced_search/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/4.jpeg"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/12.0/task_deadline_reminder/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/5.jpeg"> </div>
+ </a>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
+ <a href="https://apps.odoo.com/apps/modules/13.0/barcode_scanning_sale_purchase/" target="_blank">
+ <div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;"> <img class="img img-responsive center-block" style="border-top-left-radius: 10px;border-top-right-radius: 10px;" src="images/6.jpeg"> </div>
+ </a>
+ </div>
+ </div>
+ </div>
+ <!-- Left and right controls -->
+ <a class="carousel-control-prev" href="#demo1" data-slide="prev" style="left:-25px;width: 35px;color: #000;"> <span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span> </a> <a class="carousel-control-next" href="#demo1" data-slide="next" style="right:-25px;width: 35px;color: #000;"> <span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span> </a>
+ </div>
+ </section>
+ <section class="row" style="padding: 2rem 3rem 1rem;margin:0px">
+ <h2 style="font-weight: 600;margin-bottom: 20px;text-align: center;width: 100%;">Our Service</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <div class="row" style=" display: flex; justify-content: center; flex-wrap: wrap;width: 100%; ">
+ <!-- <div style="display:flex;padding-top: 20px;justify-content: space-between;"> -->
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-customization.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Customization </a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-erp-implementation.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Implementation </a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-erp-integration.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Integration </a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-erp-support.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Odoo Support</a> </h3>
+ </div>
+ <div class="col-md-2 col-sm-6 col-xs-12">
+ <div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> <a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank"> <img src="https://www.cybrosys.com/images/hire-odoo-developer.png" style="width: 100%;border-radius: 100%;"/> </a> </div>
+ <h3 class="oe_slogan" style="font-weight: 800;text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> <a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Hire Odoo Developers</a> </h3>
+ </a>
+ </div>
+ <!-- </div> -->
+ </div>
+ </section>
+ <section class="row" style="padding: 2rem 3rem 1rem;margin:0px">
+ <div class="row" style="margin: 0">
+ <h2 style="font-weight: 600;margin-bottom: 20px;text-align: center;width: 100%;">Our Industries</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <!-- <div style="display:flex;justify-content: space-between;flex-wrap:wrap;"> -->
+ <div class="row" style="width: 100%">
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-1.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> Trading </a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> Easily procure and sell your products. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-2.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;" style=" margin-bottom: 10px; ">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> Manufacturing</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;font-family: 'Montserrat',sans-serif;"> Plan, track and schedule your operations. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-3.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> Restaurant</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;font-family: 'Montserrat',sans-serif;"> Run your bar or restaurant methodical. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-4.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank" style="list-style: none; color:#000; text-decoration: none;font-family: 'Montserrat',sans-serif;"> POS</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;font-family: 'Montserrat',sans-serif;"> Easy configuring and convivial selling. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-5.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 0px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> E-commerce & Website</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> Mobile friendly, awe-inspiring product pages. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-6.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Hotel Management</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> An all-inclusive hotel management application. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-7.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Education</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> A Collaborative platform for educational management. </h3>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-6 col-xs-12" style=" margin-bottom: 10px; ">
+ <div >
+ <div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> <a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank"> <img src="https://www.cybrosys.com/images/odoo-index-industry-8.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> </a> </div>
+ </div>
+ <div style="width:70%;float:left;">
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:800;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> <a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank" style="list-style: none; color:#000; text-decoration: none; font-family: 'Montserrat',sans-serif;"> Service Management</a> </h3>
+ <h3 class="oe_slogan" style=" text-align: left;font-size: 12px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px; font-family: 'Montserrat',sans-serif;"> Keep track of services and invoice accordingly. </h3>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</section>
+<section class="oe_container" style="padding: 0% 0% 6% 0%;">
+ <center>
+ <div class="col-md-12" style="margin: auto !important;
+ width: 70%;
+ padding: 30px;">
+ <h2 style="font-weight: 600;text-align: center;width: 100%;">Need Any Help?</h2>
+ <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">
+ <h4 style="font-size:16px;"> If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support. </h4>
+ <div class="col-md-6" style="float:left; padding:20px;">
+ <h4><i class="fa fa-envelope"></i>Email us </h4>
+ <p>odoo@cybrosys.com</p>
+ </div>
+ <div class="col-md-6" style="float:left; padding:20px;">
+ <h4><i class="fa fa-phone"></i> Contact Us </h4>
+ <a href="https://www.cybrosys.com/contact/" target="_blank"> www.cybrosys.com</a>
+ </div>
+ </div>
+ </center>
+</section>
+<section class="oe_container" style="padding: 0% 0% 6% 0%;">
+ <div class="oe_slogan" style="margin-bottom: 0px;">
+ <div style=" display: flex; justify-content: center; flex-wrap: wrap; ">
+ </div>
+ <br>
+ <img src="https://www.cybrosys.com/images/logo.png" style="width: 190px; margin-bottom: 25px;margin-top: 30px;" class="center-block">
+ <div style=" display: flex; justify-content: center; flex-wrap: wrap; "> <a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ <a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ <a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px; height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ <a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a>
+ </td>
+ </div>
+ </div>
+</section>
+</div> \ No newline at end of file
diff --git a/addons/product_brand_sale/views/brand_views.xml b/addons/product_brand_sale/views/brand_views.xml
new file mode 100644
index 0000000..041169c
--- /dev/null
+++ b/addons/product_brand_sale/views/brand_views.xml
@@ -0,0 +1,108 @@
+<odoo>
+ <data>
+ <record id="product_brand_id" model="ir.ui.view">
+ <field name="name">Brand Name</field>
+ <field name="model">product.template</field>
+ <field name="inherit_id" ref="product.product_template_form_view"/>
+ <field name="arch" type="xml">
+ <field name="categ_id" position="after">
+ <field name="brand_id"/>
+ </field>
+ </field>
+ </record>
+
+ <record id="brand_group_by" model="ir.ui.view">
+ <field name="name">product.template.search.inherit</field>
+ <field name="model">product.template</field>
+ <field name="inherit_id" ref="product.product_template_search_view"/>
+ <field name="arch" type="xml">
+ <xpath expr="//search" position="inside">
+ <filter string="Brand" name="Brand" context="{'group_by':'brand_id'}"/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="product_brand_action" model="ir.actions.act_window">
+ <field name="name">Product Brand</field>
+ <field name="res_model">product.brand</field>
+ <field name="view_mode">tree,form</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Add Product Brand!
+ </p>
+ </field>
+ </record>
+
+ <record id="product_brand_tree" model="ir.ui.view">
+ <field name="name">Product Brand</field>
+ <field name="model">product.brand</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="id"/>
+ <field name="name"/>
+ <field name="negara_asal"/>
+ <field name="short_desc"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="product_brand_form" model="ir.ui.view">
+ <field name="name">Product Brand</field>
+ <field name="model">product.brand</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet>
+ <field name="brand_image" widget="image" class="oe_avatar"/>
+ <div class="oe_title">
+ <label for="name" class="oe_edit_only" string="Brand Name"/>
+ <h1>
+ <field name="name"/>
+ </h1>
+ <div name="options_active"/>
+ </div>
+ <group>
+ <group>
+ <field name="negara_asal"/>
+ <field name="short_desc"/>
+<!-- <field name="product_count" style="width:40px;"/>-->
+ </group>
+ <group></group>
+ </group>
+ <notebook>
+ <page string="Products" name="products">
+ <field name="member_ids" widget="many2many" options="{'not_delete': True}">
+ <kanban quick_create="false" create="true" delete="true">
+ <field name="id"/>
+ <field name="name"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div class="oe_kanban_global_click" style="max-width: 200px">
+ <div class="o_kanban_record_top">
+ <img t-att-src="kanban_image('product.template', 'image_128', record.id.raw_value)"
+ class="oe_avatar oe_kanban_avatar_smallbox o_image_40_cover mb0"
+ alt="Avatar"/>
+ <div class="o_kanban_record_headings ml8">
+ <strong class="o_kanban_record_title">
+ <field name="name"/>
+ </strong>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </page>
+ </notebook>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <menuitem id="brand_product_sale"
+ name="Product Brands"
+ parent="sale.product_menu_catalog"
+ sequence="3"
+ action="product_brand_action"/>
+ </data>
+</odoo> \ No newline at end of file