Browse Source

[ADD] Initial Commit

pull/192/merge
Ajmal Cybro 3 years ago
parent
commit
ae35bee843
  1. 41
      sale_report_advanced/README.rst
  2. 24
      sale_report_advanced/__init__.py
  3. 61
      sale_report_advanced/__manifest__.py
  4. 22
      sale_report_advanced/controllers/__init__.py
  5. 55
      sale_report_advanced/controllers/profit.py
  6. 6
      sale_report_advanced/doc/RELEASE_NOTES.md
  7. 95
      sale_report_advanced/report/invoice_analysis_template.xml
  8. 345
      sale_report_advanced/report/sale_profit_template.xml
  9. 53
      sale_report_advanced/report/sale_reports.xml
  10. 167
      sale_report_advanced/report/sales_analysis_template.xml
  11. 111
      sale_report_advanced/report/sales_category_template.xml
  12. 59
      sale_report_advanced/report/sales_indent_template.xml
  13. 66
      sale_report_advanced/report/sales_weekly_template.xml
  14. 7
      sale_report_advanced/security/ir.model.access.csv
  15. BIN
      sale_report_advanced/static/description/assets/icons/check.png
  16. BIN
      sale_report_advanced/static/description/assets/icons/chevron.png
  17. BIN
      sale_report_advanced/static/description/assets/icons/cogs.png
  18. BIN
      sale_report_advanced/static/description/assets/icons/consultation.png
  19. BIN
      sale_report_advanced/static/description/assets/icons/ecom-black.png
  20. BIN
      sale_report_advanced/static/description/assets/icons/education-black.png
  21. BIN
      sale_report_advanced/static/description/assets/icons/hotel-black.png
  22. BIN
      sale_report_advanced/static/description/assets/icons/license.png
  23. BIN
      sale_report_advanced/static/description/assets/icons/lifebuoy.png
  24. BIN
      sale_report_advanced/static/description/assets/icons/logo.png
  25. BIN
      sale_report_advanced/static/description/assets/icons/manufacturing-black.png
  26. BIN
      sale_report_advanced/static/description/assets/icons/pos-black.png
  27. BIN
      sale_report_advanced/static/description/assets/icons/puzzle.png
  28. BIN
      sale_report_advanced/static/description/assets/icons/restaurant-black.png
  29. BIN
      sale_report_advanced/static/description/assets/icons/service-black.png
  30. BIN
      sale_report_advanced/static/description/assets/icons/trading-black.png
  31. BIN
      sale_report_advanced/static/description/assets/icons/training.png
  32. BIN
      sale_report_advanced/static/description/assets/icons/update.png
  33. BIN
      sale_report_advanced/static/description/assets/icons/user.png
  34. BIN
      sale_report_advanced/static/description/assets/icons/wrench.png
  35. BIN
      sale_report_advanced/static/description/assets/modules/budget_image.png
  36. BIN
      sale_report_advanced/static/description/assets/modules/credit_image.png
  37. BIN
      sale_report_advanced/static/description/assets/modules/employee_image.png
  38. BIN
      sale_report_advanced/static/description/assets/modules/export_image.png
  39. BIN
      sale_report_advanced/static/description/assets/modules/gantt_image.png
  40. BIN
      sale_report_advanced/static/description/assets/modules/quotation_image.png
  41. BIN
      sale_report_advanced/static/description/assets/screenshots/1.png
  42. BIN
      sale_report_advanced/static/description/assets/screenshots/10.png
  43. BIN
      sale_report_advanced/static/description/assets/screenshots/11.png
  44. BIN
      sale_report_advanced/static/description/assets/screenshots/12.png
  45. BIN
      sale_report_advanced/static/description/assets/screenshots/13.png
  46. BIN
      sale_report_advanced/static/description/assets/screenshots/14.png
  47. BIN
      sale_report_advanced/static/description/assets/screenshots/15.png
  48. BIN
      sale_report_advanced/static/description/assets/screenshots/16.png
  49. BIN
      sale_report_advanced/static/description/assets/screenshots/17.png
  50. BIN
      sale_report_advanced/static/description/assets/screenshots/18.png
  51. BIN
      sale_report_advanced/static/description/assets/screenshots/2.png
  52. BIN
      sale_report_advanced/static/description/assets/screenshots/3.png
  53. BIN
      sale_report_advanced/static/description/assets/screenshots/4.png
  54. BIN
      sale_report_advanced/static/description/assets/screenshots/5.png
  55. BIN
      sale_report_advanced/static/description/assets/screenshots/6.png
  56. BIN
      sale_report_advanced/static/description/assets/screenshots/7.png
  57. BIN
      sale_report_advanced/static/description/assets/screenshots/8.png
  58. BIN
      sale_report_advanced/static/description/assets/screenshots/9.png
  59. BIN
      sale_report_advanced/static/description/assets/screenshots/hero.gif
  60. BIN
      sale_report_advanced/static/description/banner.png
  61. BIN
      sale_report_advanced/static/description/icon.png
  62. BIN
      sale_report_advanced/static/description/images/checked.png
  63. BIN
      sale_report_advanced/static/description/images/cybrosys.png
  64. 707
      sale_report_advanced/static/description/index.html
  65. 22
      sale_report_advanced/static/src/js/action_manager.js
  66. 32
      sale_report_advanced/views/report_view.xml
  67. 28
      sale_report_advanced/wizard/__init__.py
  68. 367
      sale_report_advanced/wizard/sale_analysis.py
  69. 39
      sale_report_advanced/wizard/sale_analysis.xml
  70. 260
      sale_report_advanced/wizard/sale_category.py
  71. 31
      sale_report_advanced/wizard/sale_category.xml
  72. 230
      sale_report_advanced/wizard/sale_indent.py
  73. 37
      sale_report_advanced/wizard/sale_indent.xml
  74. 271
      sale_report_advanced/wizard/sale_invoice.py
  75. 35
      sale_report_advanced/wizard/sale_invoice.xml
  76. 428
      sale_report_advanced/wizard/sale_report.py
  77. 35
      sale_report_advanced/wizard/sale_report.xml
  78. 219
      sale_report_advanced/wizard/weekly_wise.py
  79. 32
      sale_report_advanced/wizard/weekly_wise.xml
  80. 41
      serial_no_from_mo/README.rst
  81. 23
      serial_no_from_mo/__init__.py
  82. 44
      serial_no_from_mo/__manifest__.py
  83. 6
      serial_no_from_mo/doc/RELEASE_NOTES.md
  84. 23
      serial_no_from_mo/models/__init__.py
  85. 81
      serial_no_from_mo/models/product_template.py
  86. 50
      serial_no_from_mo/models/res_settings.py
  87. BIN
      serial_no_from_mo/static/description/assets/icons/check.png
  88. BIN
      serial_no_from_mo/static/description/assets/icons/chevron.png
  89. BIN
      serial_no_from_mo/static/description/assets/icons/cogs.png
  90. BIN
      serial_no_from_mo/static/description/assets/icons/consultation.png
  91. BIN
      serial_no_from_mo/static/description/assets/icons/ecom-black.png
  92. BIN
      serial_no_from_mo/static/description/assets/icons/education-black.png
  93. BIN
      serial_no_from_mo/static/description/assets/icons/hotel-black.png
  94. BIN
      serial_no_from_mo/static/description/assets/icons/license.png
  95. BIN
      serial_no_from_mo/static/description/assets/icons/lifebuoy.png
  96. BIN
      serial_no_from_mo/static/description/assets/icons/logo.png
  97. BIN
      serial_no_from_mo/static/description/assets/icons/manufacturing-black.png
  98. BIN
      serial_no_from_mo/static/description/assets/icons/pos-black.png
  99. BIN
      serial_no_from_mo/static/description/assets/icons/puzzle.png
  100. BIN
      serial_no_from_mo/static/description/assets/icons/restaurant-black.png

41
sale_report_advanced/README.rst

@ -0,0 +1,41 @@
Advanced Sales Reports
=======================
* Advanced Sales Reports for Odoo 15
Installation
============
- www.odoo.com/documentation/15.0/setup/install.html
- Install our custom addon
License
-------
General Public License, Version 3 (LGPL v3).
(https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html)
Company
-------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer:
Athul @ Cybrosys
Contacts
--------
* Mail Contact : odoo@cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
This module is maintained by Cybrosys Technologies.
For support and more information, please visit https://www.cybrosys.com
Further information
===================
HTML Description: `<static/description/index.html>`__

24
sale_report_advanced/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import wizard
from . import controllers

61
sale_report_advanced/__manifest__.py

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'Advanced Sales Reports',
'version': '15.0.1.0.0',
'summary': 'Advanced sales reports for Odoo 15',
'description': """module helps you to print reports like Sales Analysis, Sales By Category,
Sales Indent, Sales Invoice ,Product Profit ,Hourly Sales in PDF and XLSX format.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'category': 'Sales',
'website': 'https://www.cybrosys.com',
'depends': ['sale_management', 'base','account'],
'data': [
'security/ir.model.access.csv',
'wizard/sale_report.xml',
'wizard/sale_invoice.xml',
'wizard/sale_analysis.xml',
'wizard/weekly_wise.xml',
'wizard/sale_category.xml',
'wizard/sale_indent.xml',
'views/report_view.xml',
'report/sale_reports.xml',
'report/invoice_analysis_template.xml',
'report/sales_indent_template.xml',
'report/sale_profit_template.xml',
'report/sales_category_template.xml',
'report/sales_analysis_template.xml',
'report/sales_weekly_template.xml',
],
'images': ['static/description/banner.png'],
'installable': True,
'application': True,
'license': 'LGPL-3',
'assets': {
'web.assets_backend': [
'sale_report_advanced/static/src/js/action_manager.js',
],
},
}

22
sale_report_advanced/controllers/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import profit

55
sale_report_advanced/controllers/profit.py

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
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, report_name, **kw):
uid = request.session.uid
options = json.loads(options)
report_obj = request.env[model].sudo(uid)
token = 'dummy-because-api-expects-one'
try:
if output_format == 'xlsx':
response = request.make_response(
None,
headers=[('Content-Type', 'application/vnd.ms-excel'),
('Content-Disposition', content_disposition(report_name + '.xlsx'))
]
)
report_obj.get_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)))

6
sale_report_advanced/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <advanced sales report>
#### 8.4.2022
#### Version 15.0.1.0.0
##### ADD
- Initial Commit for sale_report_advanced

95
sale_report_advanced/report/invoice_analysis_template.xml

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="invoice_analysis_view">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<t class="page">
<div class="oe_structure"/>
<center>
<b>
<h3>Invoice Analysis Report</h3>
</b>
</center>
<t t-if="start_date and end_date">
<center>
<span t-esc="start_date"/>
To
<span t-esc="end_date"/>
</center>
</t>
<t t-foreach="partner_id" t-as="partner">
<center>
<b>
<span t-esc="partner['name']"/>
</b>
</center>
<br/>
<t t-set="t_invoiced" t-value="0"/>
<t t-set="t_paid" t-value="0"/>
<t t-set="t_due" t-value="0"/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order Number</th>
<th>Order Date</th>
<th>Invoice Number</th>
<th>Invoice Date</th>
<th>Amount Invoiced</th>
<th>Amount Paid</th>
<th>Amount Due</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['partner_id'] == partner['id']">
<td>
<span t-esc="order['so']"/>
</td>
<td>
<span t-esc="order['order_date']" t-options='{"widget": "date"}'/>
</td>
<td>
<span t-esc="order['invoice']"/>
</td>
<td>
<span t-esc="order['date']"/>
</td>
<td>
<span t-esc="order['invoiced']"/>
<t t-set="t_invoiced" t-value="t_invoiced + order['invoiced']"></t>
</td>
<td>
<span t-esc="order['paid']"/>
<t t-set="t_paid" t-value="t_paid + order['paid']"></t>
</td>
<td>
<span t-esc="order['due']"/>
<t t-set="t_due" t-value="t_due + order['due']"></t>
</td>
</t>
</tr>
<tr>
<td>
<span>Total invoiced</span>
<t t-esc="t_invoiced"/>
</td>
<td>
<span>Total paid:</span>
<t t-esc="t_paid"/>
</td>
<td>
<span>Total due:</span>
<t t-esc="t_due"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
</t>
</t>
</template>
</odoo>

345
sale_report_advanced/report/sale_profit_template.xml

@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sale_report_view">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<t class="page">
<div class="oe_structure"/>
<center>
<b>
<h3>Sales Profit Report</h3>
</b>
</center>
<t t-if="start_date and end_date">
<center>
<span t-esc="start_date"/>
To
<span t-esc="end_date"/>
</center>
</t>
<t t-if="type=='customer'">
<t t-foreach="partner_id" t-as="partner">
<center>
<b>
<span t-esc="partner['name']"/>
</b>
</center>
<t t-set="t_cost" t-value="0"/>
<t t-set="t_price" t-value="0"/>
<t t-set="t_profit" t-value="0"/>
<t t-set="t_margin" t-value="0"/>
<br/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order</th>
<th>Date</th>
<th>Product</th>
<th>Quantity</th>
<th>Cost</th>
<th>Sale Price</th>
<th>Profit</th>
<th>Margin(%)</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['partner_id'] == partner['id']">
<td>
<span t-esc="order['sequence']"/>
</td>
<td>
<span t-esc="order['date']" t-options='{"widget": "date"}'/>
</td>
<td>
<span t-esc="order['product']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
</td>
<td>
<span t-esc="order['cost']"/>
<t t-set="t_cost" t-value="t_cost + order['cost']"></t>
</td>
<td>
<span t-esc="order['price']"/>
<t t-set="t_price" t-value="t_price + order['price']"></t>
</td>
<td>
<span t-esc="order['profit']"/>
<t t-set="t_profit" t-value="t_profit + order['profit']"></t>
</td>
<td>
<span t-esc="order['margin']"/>
<t t-set="t_margin" t-value="t_margin + order['margin']"></t>
</td>
</t>
</tr>
<tr>
<td>
<span>Total cost</span>
<t t-esc="t_cost"/>
</td>
<td>
<span>Total Price:</span>
<t t-esc="t_price"/>
</td>
<td>
<span>Total Profit:</span>
<t t-esc="t_profit"/>
</td>
<td>
<span>Total margin:</span>
<t t-esc="t_margin"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
<t t-if="type=='product'">
<t t-foreach="product_id" t-as="product">
<center>
<b>
<span t-esc="product['name']"/>
</b>
</center>
<t t-set="t_cost" t-value="0"/>
<t t-set="t_price" t-value="0"/>
<t t-set="t_profit" t-value="0"/>
<t t-set="t_margin" t-value="0"/>
<br/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order</th>
<th>Date</th>
<th>Customer</th>
<th>Quantity</th>
<th>Cost</th>
<th>Sale Price</th>
<th>Profit</th>
<th>Margin(%)</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['product_id'] == product['id']">
<td>
<span t-esc="order['sequence']"/>
</td>
<td>
<span t-esc="order['date']" t-options='{"widget": "date"}'/>
</td>
<td>
<span t-esc="order['partner']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
</td>
<td>
<span t-esc="order['cost']"/>
<t t-set="t_cost" t-value="t_cost + order['cost']"></t>
</td>
<td>
<span t-esc="order['price']"/>
<t t-set="t_price" t-value="t_price + order['price']"></t>
</td>
<td>
<span t-esc="order['profit']"/>
<t t-set="t_profit" t-value="t_profit + order['profit']"></t>
</td>
<td>
<span t-esc="order['margin']"/>
<t t-set="t_margin" t-value="t_margin + order['margin']"></t>
</td>
</t>
</tr>
<tr>
<td>
<span>Total cost</span>
<t t-esc="t_cost"/>
</td>
<td>
<span>Total Price:</span>
<t t-esc="t_price"/>
</td>
<td>
<span>Total Profit:</span>
<t t-esc="t_profit"/>
</td>
<td>
<span>Total margin:</span>
<t t-esc="t_margin"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
<t t-if="type=='both'">
<table class="table table-condensed">
<t t-set="t_cost" t-value="0"/>
<t t-set="t_price" t-value="0"/>
<t t-set="t_profit" t-value="0"/>
<t t-set="t_margin" t-value="0"/>
<thead>
<tr>
<th>Order</th>
<th>Date</th>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Cost</th>
<th>Sale Price</th>
<th>Profit</th>
<th>Margin(%)</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<td>
<span t-esc="order['sequence']"/>
</td>
<td>
<span t-esc="order['date']" t-options='{"widget": "date"}'/>
</td>
<td>
<span t-esc="order['partner']"/>
</td>
<td>
<span t-esc="order['product']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
</td>
<td>
<span t-esc="order['cost']"/>
<t t-set="t_cost" t-value="t_cost + order['cost']"></t>
</td>
<td>
<span t-esc="order['price']"/>
<t t-set="t_price" t-value="t_price + order['price']"></t>
</td>
<td>
<span t-esc="order['profit']"/>
<t t-set="t_profit" t-value="t_profit + order['profit']"></t>
</td>
<td>
<span t-esc="order['margin']"/>
<t t-set="t_margin" t-value="t_margin + order['margin']"></t>
</td>
</tr>
<tr>
<td>
<span>Total cost</span>
<t t-esc="t_cost"/>
</td>
<td>
<span>Total Price:</span>
<t t-esc="t_price"/>
</td>
<td>
<span>Total Profit:</span>
<t t-esc="t_profit"/>
</td>
<td>
<span>Total margin:</span>
<t t-esc="t_margin"/>
</td>
</tr>
</tbody>
</table>
</t>
<t t-if="no_value == True">
<table class="table table-condensed">
<t t-set="t_cost" t-value="0"/>
<t t-set="t_price" t-value="0"/>
<t t-set="t_profit" t-value="0"/>
<t t-set="t_margin" t-value="0"/>
<thead>
<tr>
<th>Order</th>
<th>Date</th>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Cost</th>
<th>Sale Price</th>
<th>Profit</th>
<th>Margin(%)</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<td>
<span t-esc="order['sequence']"/>
</td>
<td>
<span t-esc="order['date']" t-options='{"widget": "date"}'/>
</td>
<td>
<span t-esc="order['partner']"/>
</td>
<td>
<span t-esc="order['product']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
</td>
<td>
<span t-esc="order['cost']"/>
<t t-set="t_cost" t-value="t_cost + order['cost']"></t>
</td>
<td>
<span t-esc="order['price']"/>
<t t-set="t_price" t-value="t_price + order['price']"></t>
</td>
<td>
<span t-esc="order['profit']"/>
<t t-set="t_profit" t-value="t_profit + order['profit']"></t>
</td>
<td>
<span t-esc="order['margin']"/>
<t t-set="t_margin" t-value="t_margin + order['margin']"></t>
</td>
</tr>
<tr>
<td>
<span>Total cost</span>
<t t-esc="t_cost"/>
</td>
<td>
<span>Total Price:</span>
<t t-esc="t_price"/>
</td>
<td>
<span>Total Profit:</span>
<t t-esc="t_profit"/>
</td>
<td>
<span>Total margin:</span>
<t t-esc="t_margin"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
</t>
</t>
</template>
</odoo>

53
sale_report_advanced/report/sale_reports.xml

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<report
id="action_sale_report"
string="Sales"
model="sale.report.advance"
report_type="qweb-pdf"
file="sale_report_advanced.sale_report_view"
name="sale_report_advanced.sale_report_view"
/>
<report
id="action_invoice_analysis"
string="Invoice Analysis"
model="sale.report.invoice"
report_type="qweb-pdf"
file="sale_report_advanced.invoice_analysis_view"
name="sale_report_advanced.invoice_analysis_view"
/>
</data>
<report
id="action_sale_category"
string="Sales Category"
model="sale.report.category"
report_type="qweb-pdf"
file="sale_report_advanced.sales_category_view"
name="sale_report_advanced.sales_category_view"
/>
<report
id="action_sale_indent"
string="Product Sales Indent"
model="sale.report.indent"
report_type="qweb-pdf"
file="sale_report_advanced.sales_indent_view"
name="sale_report_advanced.sales_indent_view"
/>
<report
id="action_sales_analysis"
string="Sales Analysis Report"
model="sale.report.analysis"
report_type="qweb-pdf"
file="sale_report_advanced.sales_analysis_view"
name="sale_report_advanced.sales_analysis_view"
/>
<report
id="action_sales_weekly"
string="Hourly Sales Report"
model="sale.report.weekly"
report_type="qweb-pdf"
file="sale_report_advanced.sales_hourly_view"
name="sale_report_advanced.sales_hourly_view"
/>
</odoo>

167
sale_report_advanced/report/sales_analysis_template.xml

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sales_analysis_view">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<style>
</style>
<t class="page">
<div class="oe_structure"/>
<center>
<b>
<h3>Sales Analysis Report</h3>
</b>
</center>
<t t-if="start_date and end_date">
<center>
<span t-esc="start_date"/>
To
<span t-esc="end_date"/>
</center>
</t>
<t t-foreach="partner_id" t-as="partner">
<center>
<b>
<span t-esc="partner['name']" style="font-size:22px;"/>
</b>
</center>
<t t-if="type =='sale'">
<t t-set="t_amt" t-value="0"/>
<t t-set="t_paid" t-value="0"/>
<t t-set="t_balance" t-value="0"/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order Number</th>
<th>Order Date</th>
<th>Sales Person</th>
<th>Sales Amount</th>
<th>Amount Paid</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['partner_id'] == partner['id']">
<td>
<span t-esc="order['so']"/>
</td>
<td>
<span t-esc="order['date']"/>
</td>
<td>
<span t-esc="order['sales_person']"/>
</td>
<td>
<span t-esc="order['s_amt']"/>
<t t-set="t_amt" t-value="t_amt + order['s_amt']"></t>
</td>
<td>
<span t-esc="order['p_amt']"/>
<t t-set="t_paid" t-value="t_paid + order['p_amt']"></t>
</td>
<td>
<span t-esc="order['balance']"/>
<t t-set="t_balance" t-value="t_balance + order['balance']"></t>
</td>
</t>
</tr>
<tr>
<td colsapn="3">
<span>Total Amount</span>
<t t-esc="t_amt"/>
</td>
<td>
<span>Total Paid:</span>
<t t-esc="t_paid"/>
</td>
<td>
<span>Total Balance:</span>
<t t-esc="t_balance"/>
</td>
</tr>
</tbody>
</table>
</t>
<t t-else="">
<t t-set="t_total" t-value="0"/>
<t t-set="t_price" t-value="0"/>
<t t-set="t_disc" t-value="0"/>
<t t-set="t_qty" t-value="0"/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order</th>
<th>Date</th>
<th>Product</th>
<th>Quantity</th>
<th>price</th>
<th>Discount(%)</th>
<th>Tax(%)</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['partner_id'] == partner['id']">
<td>
<span t-esc="order['so']"/>
</td>
<td>
<span t-esc="order['date']"/>
</td>
<td>
<span t-esc="order['product_id']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
<t t-set="t_qty" t-value="t_qty + order['quantity']"></t>
</td>
<td>
<span t-esc="order['price']"/>
<t t-set="t_price" t-value="t_price + order['price']"></t>
</td>
<td>
<span t-esc="order['discount']"/>
<t t-set="t_disc" t-value="t_disc + order['discount']"></t>
</td>
<td>
<span t-esc="order['tax']"/>
</td>
<td>
<span t-esc="order['total']"/>
<t t-set="t_total" t-value="t_total + order['total']"></t>
</td>
</t>
</tr>
<tr>
<td colsapn="3">
<span>Total Quantity</span>
<t t-esc="t_qty"/>
</td>
<td>
<span>Total Price:</span>
<t t-esc="t_price"/>
</td>
<td>
<span>Total Discount:</span>
<t t-esc="t_disc"/>
</td>
<td>
<span>Subtotal</span>
<t t-esc="t_total"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
</t>
</t>
</t>
</template>
</odoo>

111
sale_report_advanced/report/sales_category_template.xml

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sales_category_view">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<t class="page">
<div class="oe_structure"/>
<center>
<b>
<h3>Sales category Report</h3>
</b>
</center>
<t t-if="start_date and end_date">
<center>
<span t-esc="start_date"/>
To
<span t-esc="end_date"/>
</center>
</t>
<t t-if="categ_id">
<t t-foreach="categ_id" t-as="categ">
<center>
<b>
<span t-esc="categ['name']"/>
</b>
</center>
<br/>
<t t-set="t_qty" t-value="0"/>
<t t-set="t_price" t-value="0"/>
<t t-set="t_total" t-value="0"/>
<t t-set="t_subtotal" t-value="0"/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order</th>
<th>Date</th>
<th>Product</th>
<th>Quantity</th>
<th>UOM</th>
<th>Price</th>
<th>Tax(%)</th>
<th>Subtotal</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['category_id'] == categ['id']">
<td>
<span t-esc="order['so']"/>
</td>
<td>
<span t-esc="order['date']" t-options='{"widget": "date"}'/>
</td>
<td>
<span t-esc="order['product_id']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
<t t-set="t_qty" t-value="t_qty + order['quantity']"></t>
</td>
<td>
<span t-esc="order['uom']"/>
</td>
<td>
<span t-esc="order['price']"/>
<t t-set="t_price" t-value="t_price + order['price']"></t>
</td>
<td>
<span t-esc="order['tax']"/>
</td>
<td>
<span t-esc="order['subtotal']"/>
<t t-set="t_subtotal" t-value="t_subtotal + order['subtotal']"></t>
</td>
<td>
<span t-esc="order['total']"/>
<t t-set="t_total" t-value="t_total + order['total']"></t>
</td>
</t>
</tr>
<tr>
<td colsapn="3">
<span>Total Quantity</span>
<t t-esc="t_qty"/>
</td>
<td>
<span>Total Price:</span>
<t t-esc="t_price"/>
</td>
<td>
<span>Total Subtotal:</span>
<t t-esc="t_subtotal"/>
</td>
<td>
<span>Total Total:</span>
<t t-esc="t_total"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
</t>
</t>
</t>
</template>
</odoo>

59
sale_report_advanced/report/sales_indent_template.xml

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sales_indent_view">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<t class="page">
<div class="oe_structure"/>
<center>
<b>
<h3>Product Sales Indent Report</h3>
</b>
</center>
<t t-if="start_date and end_date">
<center>
<span t-esc="start_date"/>
To
<span t-esc="end_date"/>
</center>
</t>
<t t-foreach="partner_id" t-as="partner">
<center>
<b>
<span t-esc="partner['name']" style="font-size:22px;"/>
</b>
</center>
<t t-foreach="categ_id" t-as="categ">
<center>
<b>
<span t-esc="categ['name']" style="font-size:17px;"/>
</b>
</center>
<table class="table table-condensed">
<thead>
<tr>
<th>Product</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['category_id'] == categ['id'] and order['partner_id'] == partner['id']">
<td>
<span t-esc="order['product_id']"/>
</td>
<td>
<span t-esc="order['quantity']"/>
</td>
</t>
</tr>
</tbody>
</table>
</t>
</t>
</t>
</t>
</t>
</template>
</odoo>

66
sale_report_advanced/report/sales_weekly_template.xml

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sales_hourly_view">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<style>
</style>
<t class="page">
<div class="oe_structure"/>
<center>
<b>
<h3>Hourly Sales Report</h3>
</b>
</center>
<t t-foreach="times" t-as="t">
<center>
<b>
<span t-esc="t['name']" style="font-size:21px;"/>
</b>
</center>
<t t-set="t_amt" t-value="0"/>
<table class="table table-condensed">
<thead>
<tr>
<th>Order Number</th>
<th>Order Date</th>
<t t-if="type=='untax'">
<th>Untaxed Total</th>
</t>
<t t-else="">
<th>Total</th>
</t>
</tr>
</thead>
<tbody>
<tr t-foreach="form" t-as="order">
<t t-if="order['time'] == t['id']">
<td>
<span t-esc="order['order']"/>
</td>
<td>
<span t-esc="order['date']"/>
</td>
<td>
<span t-esc="order['amount']"/>
<t t-set="t_amt" t-value="t_amt + order['amount']"></t>
</td>
</t>
</tr>
<tr>
<td colsapn="3">
<b>
<span>Total Amount</span>
</b>
<t t-esc="t_amt"/>
</td>
</tr>
</tbody>
</table>
</t>
</t>
</t>
</t>
</template>
</odoo>

7
sale_report_advanced/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_sale_report_advance,access.sale.report.advance,model_sale_report_advance,,1,1,1,1
access_sale_report_invoice,access.sale.report.invoice,model_sale_report_invoice,,1,1,1,1
access_sale_report_category,access.sale.report.category,model_sale_report_category,,1,1,1,1
access_sale_report_indent,access.sale.report.indent,model_sale_report_indent,,1,1,1,1
access_sale_report_analysis,access.sale.report.analysis,model_sale_report_analysis,,1,1,1,1
access_sale_report_weekly,access.sale.report.weekly,model_sale_report_weekly,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sale_report_advance access.sale.report.advance model_sale_report_advance 1 1 1 1
3 access_sale_report_invoice access.sale.report.invoice model_sale_report_invoice 1 1 1 1
4 access_sale_report_category access.sale.report.category model_sale_report_category 1 1 1 1
5 access_sale_report_indent access.sale.report.indent model_sale_report_indent 1 1 1 1
6 access_sale_report_analysis access.sale.report.analysis model_sale_report_analysis 1 1 1 1
7 access_sale_report_weekly access.sale.report.weekly model_sale_report_weekly 1 1 1 1

BIN
sale_report_advanced/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
sale_report_advanced/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
sale_report_advanced/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
sale_report_advanced/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
sale_report_advanced/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
sale_report_advanced/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
sale_report_advanced/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
sale_report_advanced/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sale_report_advanced/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sale_report_advanced/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
sale_report_advanced/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
sale_report_advanced/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
sale_report_advanced/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
sale_report_advanced/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
sale_report_advanced/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
sale_report_advanced/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
sale_report_advanced/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
sale_report_advanced/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sale_report_advanced/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
sale_report_advanced/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sale_report_advanced/static/description/assets/modules/budget_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
sale_report_advanced/static/description/assets/modules/credit_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
sale_report_advanced/static/description/assets/modules/employee_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
sale_report_advanced/static/description/assets/modules/export_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
sale_report_advanced/static/description/assets/modules/gantt_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
sale_report_advanced/static/description/assets/modules/quotation_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/17.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/18.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
sale_report_advanced/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

BIN
sale_report_advanced/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
sale_report_advanced/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
sale_report_advanced/static/description/images/checked.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
sale_report_advanced/static/description/images/cybrosys.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

707
sale_report_advanced/static/description/index.html

@ -0,0 +1,707 @@
<div class="container" style="padding: 1rem !important; margin-bottom: 1rem !important;">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between"
style="border-bottom: 1px solid #d5d5d5;">
<div class="my-3">
<img src="/assets/icons/logo.png" style="width: auto !important; height: 40px !important;">
</div>
<div class="my-3 d-flex align-items-center">
<div
style="background-color: #7C7BAD !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Community
</div>
<div
style="background-color: #875A7B !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
</div>
</div>
</div>
</div>
<div class="container" style="padding: 0rem 1.5rem 4rem !important">
<div class="row" style="height: 900px !important;">
<div class="col-sm-12 col-md-12 col-lg-12"
style="padding: 4rem 1rem !important; background-color: #714B67 !important; height: 600px !important; border-radius: 20px !important;">
<h1
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #FFFFFF !important; font-size: 4rem !important; text-align: center !important;">
Advanced Sales Reports </h1>
<p
style="font-family: 'Montserrat', sans-serif !important; font-weight: 300 !important; color: #FFFFFF !important; font-size: 1.4rem !important; text-align: center !important;">
</p>
<img src="/assets/screenshots/hero.gif" class="img-responsive" width="100%" height="auto"/>
</div>
</div>
<div class="row">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin-bottom: 2rem !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-compass mr-2"></i>Explore this module
</h2>
</div>
<div class="col-md-6">
<a href="#overview" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Overview</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
Learn more about this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="col-md-6">
<a href="#features" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Features</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
View features of this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="col-md-6">
<a href="#screenshots" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Screenshots</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
See key screenshots of this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="row" id="overview">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-pie-chart mr-2"></i>Overview
</h2>
</div>
<div class="col-mg-12 pl-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important; line-height: 30px !important;">
The module helps you to print reports like Sales Analysis, Sales By Category, Sales Indent, Sales
Invoice ,Product Profit ,Hourly Sales in PDF and XLSX format.
</p>
</div>
</div>
<div class="row" id="features">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-star mr-2"></i>Features
</h2>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="./assets/icons/chevron.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Analysis Report </h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
</p>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="./assets/icons/chevron.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Category Report</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="./assets/icons/chevron.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Indent Report</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="./assets/icons/chevron.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Invoice Analysis Report</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="./assets/icons/chevron.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Product Profit Report</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="./assets/icons/chevron.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Hourly Sales Report</h4>
</div>
</div>
</div>
<div class="row" id="screenshots">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-image mr-2"></i>Screenshots
</h2>
</div>
<div class="col-lg-12 my-2">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Product Profit Report
</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<img src="assets/screenshots/1.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
PDF report
<img src="assets/screenshots/2.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
XLSX report
<img src="assets/screenshots/3.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-2">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Invoice Analysis Report
</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<img src="assets/screenshots/4.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
PDF report
<img src="assets/screenshots/5.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
XLSX report
<img src="assets/screenshots/6.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-2">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Category Report
</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<img src="assets/screenshots/7.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
PDF report
<img src="assets/screenshots/8.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
XLSX report
<img src="assets/screenshots/9.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-2">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Indent Report
</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<img src="assets/screenshots/10.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
PDF report
<img src="assets/screenshots/11.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
XLSX report
<img src="assets/screenshots/12.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-2">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sales Analysis Report
</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<img src="assets/screenshots/13.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
PDF report
<img src="assets/screenshots/14.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
XLSX report
<img src="assets/screenshots/15.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-2">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Hourly Sales Report
</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<img src="assets/screenshots/16.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
PDF report
<img src="assets/screenshots/17.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
XLSX report
<img src="assets/screenshots/18.png" class="img-responsive img-thumbnail border"
width="100%"
height="auto"/>
</div>
</div>
<!-- SUGGESTED PRODUCTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 2.5rem 1rem !important;">
<h2 style="color: #212529 !important;">Suggested Products</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
<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/15.0/export_stockinfo_xls/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/export_image.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/15.0/custom_gantt_view/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/gantt_image.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/15.0/sales_credit_limit/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/credit_image.png">
</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/15.0/base_account_budget/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/budget_image.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/15.0/product_to_quotation/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/quotation_image.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/15.0/employee_documents_expiry/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/employee_image.png">
</div>
</a>
</div>
</div>
</div>
<!-- END OF SUGGESTED PRODUCTS -->
<!-- OUR SERVICES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Services</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive" height="48px"
width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</section>
<!-- END OF END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Industries</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/trading-black.png" class="img-responsive mb-3"
height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/pos-black.png" class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/education-black.png" class="img-responsive mb-3"
height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/manufacturing-black.png" class="img-responsive mb-3"
height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/service-black.png" class="img-responsive mb-3"
height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/restaurant-black.png" class="img-responsive mb-3"
height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</section>
<!-- END OF END OF OUR INDUSTRIES -->
<!-- FOOTER -->
<!-- Footer Section -->
<section class="container" style="margin: 5rem auto 2rem;">
<div class="row" style="max-width:1540px;">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Need Help?</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
</div>
</div>
<!-- Contact Cards -->
<div class="row d-flex justify-content-center align-items-center"
style="max-width:1540px; margin: 0 auto 2rem auto;">
<div class="col-lg-12"
style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; ">
<div class="row mt-4">
<div class="col-lg-6">
<a href="mailto:odoo@cybrosys.com" target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a>
</div>
<div class="col-lg-6">
<a href="https://api.whatsapp.com/send?phone=918606827707" target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i
class="fa fa-whatsapp mr-2"></i>+91 86068 27707</a>
</div>
</div>
</div>
</div>
<!-- End of Contact Cards -->
</section>
<!-- Footer -->
<section class="container" style="padding: 2rem 3rem 1rem;">
<div class="row" style="max-width:1540px; margin: 0 auto; margin-right: 3rem; ">
<!-- Logo -->
<div class="col-lg-12 d-flex justify-content-center align-items-center"
style="margin-top: 3rem;">
<img src="https://www.cybrosys.com/images/logo.png" width="200px" height="auto"/>
</div>
<!-- End of Logo -->
<div class="col-lg-12">
<hr
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;">
<!-- End of Footer Section -->
</div>
</div>
</section>
<!-- END OF FOOTER -->
</div>
</div>
</div>

22
sale_report_advanced/static/src/js/action_manager.js

@ -0,0 +1,22 @@
/** @odoo-module */
import { registry } from "@web/core/registry";
import { download } from "@web/core/network/download";
import framework from 'web.framework';
import session from 'web.session';
registry.category("ir.actions.report handlers").add("xlsx", async (action) => {
if (action.report_type === 'xlsx') {
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;
}
});

32
sale_report_advanced/views/report_view.xml

@ -0,0 +1,32 @@
<odoo>
<menuitem id="sale_advanced_report"
parent="sale.menu_sale_report"
name="Sale Product Profit"
action="sale_report_advance"
sequence="2"/>
<menuitem id="sale_report_invoice"
parent="sale.menu_sale_report"
name="Invoice analysis"
action="sale_invoice_report"
sequence="3"/>
<menuitem id="category_report"
parent="sale.menu_sale_report"
name="Sales category"
action="sale_category_report"
sequence="4"/>
<menuitem id="indent_report"
parent="sale.menu_sale_report"
name="Product Sales Indent"
action="sale_indent_report"
sequence="5"/>
<menuitem id="analysis_report"
parent="sale.menu_sale_report"
name="Sales Anaysis"
action="sale_analysis_report"
sequence="6"/>
<menuitem id="sales_weekly_report"
parent="sale.menu_sale_report"
name="Sales Hourly Wise"
action="sale_weekly_report"
sequence="7"/>
</odoo>

28
sale_report_advanced/wizard/__init__.py

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import sale_report
from . import sale_invoice
from . import sale_category
from . import sale_indent
from . import sale_analysis
from . import weekly_wise

367
sale_report_advanced/wizard/sale_analysis.py

@ -0,0 +1,367 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
import io
from xlsxwriter import workbook
from odoo.tools import date_utils
from odoo import fields, models
from odoo.exceptions import UserError, ValidationError
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class SaleReportAdvance(models.TransientModel):
_name = "sale.report.analysis"
customer_ids = fields.Many2many('res.partner', string="Customers", required=True)
product_ids = fields.Many2many('product.product', string='Products')
from_date = fields.Date(string="Start Date")
to_date = fields.Date(string="End Date")
status = fields.Selection(
[('all', 'All'), ('draft', 'Draft'), ('sent', 'Quotation Sent'), ('sale', 'Sale Order'), ('done', 'Locked')],
string='Status', default='all', reqired=True)
print_type = fields.Selection(
[('sale', 'Sale Order'), ('product', 'Products')],
string='Print By', default='sale', reqired=True)
today_date = fields.Date(default=fields.Date.today())
def get_analysis_report(self):
datas = self._get_data()
return self.env.ref('sale_report_advanced.action_sales_analysis').report_action([], data=datas)
def _get_data(self):
result = []
if self.print_type == 'sale':
if not self.status == 'all':
sale_order = self.env['sale.order'].sudo().search([('state', '=', self.status),('state','!=','cancel')])
filtered = self._get_filtered(sale_order)
else:
sale_order = self.env['sale.order'].search([('state','!=','cancel')])
filtered = self._get_filtered(sale_order)
for rec in filtered:
paid = self._get_total_paid_amount(rec.invoice_ids)
res = {
'so': rec.name,
'date': rec.date_order,
'sales_person': rec.user_id.name,
's_amt': rec.amount_total,
'p_amt': paid,
'balance': rec.amount_total - paid,
'partner_id': rec.partner_id,
}
result.append(res)
else:
if not self.status == 'all':
sale_order_line = self.env['sale.order.line'].search([('order_id.state', '=', self.status),('order_id.state','!=','cancel')])
filtered = self._get_filtered_order_line(sale_order_line)
else:
sale_order_line = self.env['sale.order.line'].search([('order_id.state','!=','cancel')])
filtered = self._get_filtered_order_line(sale_order_line)
for rec in filtered:
res = {
'so': rec.order_id.name,
'date': rec.order_id.date_order,
'product_id': rec.product_id.name,
'price': rec.product_id.list_price,
'quantity': rec.product_uom_qty,
'discount': rec.discount,
'tax': rec.product_id.taxes_id.amount,
'total': rec.price_subtotal,
'partner_id': rec.order_id.partner_id,
}
result.append(res)
datas = {
'ids': self,
'model': 'sale.report.analysis',
'form': result,
'partner_id': self._get_customers(),
'start_date': self.from_date,
'end_date': self.to_date,
'type': self.print_type
}
return datas
def _get_total_paid_amount(self, invoices):
total = 0
for inv in invoices:
if inv.payment_state == 'paid':
total += inv.amount_total
return total
def _get_filtered_order_line(self, sale_order_line):
if self.from_date and self.to_date:
filtered = list(filter(lambda
x: x.order_id.date_order.date() >= self.from_date and x.order_id.date_order.date() <= self.to_date and x.order_id.partner_id in self.customer_ids and x.product_id in self.product_ids,
sale_order_line))
elif not self.from_date and self.to_date:
filtered = list(filter(lambda
x: x.order_id.date_order.date() <= self.to_date and x.order_id.partner_id in self.customer_ids and x.product_id in self.product_ids,
sale_order_line))
elif self.from_date and not self.to_date:
filtered = list(filter(lambda
x: x.order_id.date_order.date() >= self.from_date and x.order_id.partner_id in self.customer_ids and x.product_id in self.product_ids,
sale_order_line))
else:
filtered = list(filter(lambda
x: x.order_id.partner_id in self.customer_ids and x.product_id in self.product_ids,
sale_order_line))
return filtered
def _get_filtered(self, sale_order):
if self.from_date and self.to_date:
filtered = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.date_order.date() <= self.to_date and x.partner_id in self.customer_ids,
sale_order))
elif not self.from_date and self.to_date:
filtered = list(filter(lambda
x: x.date_order.date() <= self.to_date and x.partner_id in self.customer_ids,
sale_order))
elif self.from_date and not self.to_date:
filtered = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.partner_id in self.customer_ids,
sale_order))
else:
filtered = list(filter(lambda
x: x.partner_id in self.customer_ids,
sale_order))
return filtered
def _get_customers(self):
customers = []
for rec in self.customer_ids:
a = {
'id': rec,
'name': rec.name
}
customers.append(a)
return customers
def get_excel_analysis_report(self):
datas = self._get_data()
return {
'type': 'ir.actions.report',
'report_type': 'xlsx',
'data': {'model': 'sale.report.analysis',
'output_format': 'xlsx',
'options': json.dumps(datas, default=date_utils.json_default),
'report_name': 'Excel Report Name',
},
}
def get_xlsx_report(self, data, response):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
record = []
cell_format = workbook.add_format({'font_size': '12px', })
head = workbook.add_format({'align': 'center', 'bold': True, 'font_size': '20px'})
txt = workbook.add_format({'font_size': '10px', 'align': 'center'})
if data['type'] == 'sale':
sheet.merge_range('G2:L3', 'Sales Analysis Report', head)
if data['start_date'] and data['end_date']:
sheet.write('G6', 'From:', cell_format)
sheet.merge_range('H6:I6', data['start_date'], txt)
sheet.write('J6', 'To:', cell_format)
sheet.merge_range('K6:L6', data['end_date'], txt)
h_col = 9
else:
sheet.merge_range('G2:N3', 'Sales Analysis Report', head)
if data['start_date'] and data['end_date']:
sheet.write('G6', 'From:', cell_format)
sheet.merge_range('H6:I6', data['start_date'], txt)
sheet.write('K6', 'To:', cell_format)
sheet.merge_range('L6:N6', data['end_date'], txt)
h_col = 10
format1 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bg_color': '#f5f9ff', 'border': 1})
format2 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,
'bg_color': '#6BA6FE', 'border': 1})
format3 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True, 'bg_color': '#95ff63', 'border': 1})
format4 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True})
if data['partner_id']:
record = data['partner_id']
h_row = 7
count = 0
row = 5
row_number = 6
t_row = 6
for rec in record:
if data['type'] == 'sale':
sheet.merge_range(h_row, h_col - 3, h_row, h_col + 2, rec['name'], format1)
row = row + count + 3
col = 6
sheet.write(row, col, 'Order', format2)
col += 1
sheet.write(row, col, 'Date', format2)
sheet.set_column('H:H', 17)
col += 1
sheet.write(row, col, 'Sales Person', format2)
sheet.set_column('I:I', 15)
col += 1
sheet.write(row, col, 'Sales Amount', format2)
sheet.set_column('J:J', 13)
col += 1
sheet.write(row, col, 'Amount Paid', format2)
sheet.set_column('K:K', 12)
col += 1
sheet.write(row, col, 'Balance', format2)
sheet.set_column('L:L', 10)
# col = 6
count = 0
row_number = row_number + count + 3
t_samt = 0
t_pamt = 0
t_bal = 0
t_col = 8
for val in data['form']:
if val['partner_id'] == rec['id']:
count += 1
column_number = 6
sheet.write(row_number, column_number, val['so'], format1)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('H:H', 17)
column_number += 1
sheet.write(row_number, column_number, val['sales_person'], format1)
sheet.set_column('I:I', 15)
column_number += 1
sheet.write(row_number, column_number, val['s_amt'], format1)
sheet.set_column('J:J', 13)
t_samt += val['s_amt']
column_number += 1
sheet.write(row_number, column_number, val['p_amt'], format1)
sheet.set_column('K:K', 12)
t_pamt += val['p_amt']
column_number += 1
sheet.write(row_number, column_number, val['balance'], format1)
sheet.set_column('L:L', 10)
t_bal += val['balance']
column_number += 1
row_number += 1
t_row = t_row + count + 3
sheet.write(t_row, t_col, 'Total', format4)
t_col += 1
sheet.write(t_row, t_col, t_samt, format4)
t_col += 1
sheet.write(t_row, t_col, t_pamt, format4)
t_col += 1
sheet.write(t_row, t_col, t_bal, format4)
h_row = h_row + count + 3
if data['type'] == 'product':
sheet.merge_range(h_row, h_col - 4, h_row, h_col + 3, rec['name'], format1)
row = row + count + 3
col = 6
sheet.write(row, col, 'Order', format2)
col += 1
sheet.write(row, col, 'Date', format2)
sheet.set_column('H:H', 17)
col += 1
sheet.write(row, col, 'Product', format2)
sheet.set_column('I:I', 17)
col += 1
sheet.write(row, col, 'Quantity', format2)
sheet.set_column('J:J', 7)
col += 1
sheet.write(row, col, 'Price', format2)
sheet.set_column('K:K', 12)
col += 1
sheet.write(row, col, 'Discount(%)', format2)
sheet.set_column('L:L', 12)
col += 1
sheet.write(row, col, 'Tax(%)', format2)
sheet.set_column('M:M', 10)
col += 1
sheet.write(row, col, 'Subtotal', format2)
sheet.set_column('N:N', 10)
col += 1
count = 0
row_number = row_number + count + 3
t_qty = 0
t_price = 0
t_tax = 0
t_total = 0
t_col = 8
for val in data['form']:
if val['partner_id'] == rec['id']:
count += 1
column_number = 6
sheet.write(row_number, column_number, val['so'], format1)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('H:H', 17)
column_number += 1
sheet.write(row_number, column_number, val['product_id'], format1)
sheet.set_column('I:I', 17)
column_number += 1
sheet.write(row_number, column_number, val['quantity'], format1)
sheet.set_column('J:J', 7)
t_qty += val['quantity']
column_number += 1
sheet.write(row_number, column_number, val['price'], format1)
sheet.set_column('K:K', 12)
t_price += val['price']
column_number += 1
sheet.write(row_number, column_number, val['discount'], format1)
sheet.set_column('L:L', 12)
column_number += 1
sheet.write(row_number, column_number, val['tax'], format1)
sheet.set_column('M:M', 10)
t_tax += val['tax']
column_number += 1
sheet.write(row_number, column_number, val['total'], format1)
sheet.set_column('N:N', 10)
t_total += val['total']
column_number += 1
row_number += 1
t_row = t_row + count + 3
sheet.write(t_row, t_col, 'Total', format4)
t_col += 1
sheet.write(t_row, t_col, t_qty, format4)
t_col += 1
sheet.write(t_row, t_col, t_price, format4)
t_col += 2
sheet.write(t_row, t_col, t_tax, format4)
t_col += 1
sheet.write(t_row, t_col, t_total, format4)
h_row = h_row + count + 3
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

39
sale_report_advanced/wizard/sale_analysis.xml

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="analysis_wizard" model="ir.ui.view">
<field name="name">Sales Analysis report</field>
<field name="model">sale.report.analysis</field>
<field name="arch" type="xml">
<form>
<group col="1">
<field name="from_date"/>
<field name="to_date"/>
</group>
<group>
<field name="customer_ids" widget="many2many_tags"/>
<field name="status" widget="radio"/>
</group>
<group>
<field name="product_ids" widget="many2many_tags" attrs="{'invisible': [('print_type', '=', 'sale')]}"/>
<field name="print_type" widget="radio"/>
</group>
<footer>
<button name="get_analysis_report" string="PDF Report"
type="object" class="btn-primary"/>
<button name="get_excel_analysis_report" string="XLSX Report"
type="object" class="btn-primary"/>
</footer>
</form>
</field>
</record>
<record id="sale_analysis_report" model="ir.actions.act_window">
<field name="name">Sales Analysis Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.report.analysis</field>
<field name="view_mode">form</field>
<field name="view_id" ref="analysis_wizard"/>
<field name="target">new</field>
</record>
</odoo>

260
sale_report_advanced/wizard/sale_category.py

@ -0,0 +1,260 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
import io
from xlsxwriter import workbook
from odoo.tools import date_utils
from odoo import fields, models
from odoo.exceptions import UserError, ValidationError
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class SaleReportAdvance(models.TransientModel):
_name = "sale.report.category"
category_ids = fields.Many2many('product.category', string="Categories",required=True)
from_date = fields.Date(string="Start Date")
to_date = fields.Date(string="End Date")
company_ids = fields.Many2many('res.company', string='Companies')
today_date = fields.Date(default=fields.Date.today())
def get_category_report(self):
datas = self._get_data()
return self.env.ref('sale_report_advanced.action_sale_category').report_action([], data=datas)
def _get_data(self):
sale_order_line = self.env['sale.order.line'].search([('order_id.state','!=','cancel')])
if self.from_date and self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: self.from_date >= x.order_id.date_order.date() <= self.to_date and x.order_id.company_id in self.company_ids,
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
elif not self.from_date and self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() <= self.to_date and x.order_id.company_id in self.company_ids,
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
elif self.from_date and not self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: self.from_date >= x.order_id.date_order.date() and x.order_id.company_id in self.company_ids,
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
elif self.from_date and self.to_date and not self.company_ids:
order_lines = list(filter(lambda
x: self.from_date >= x.order_id.date_order.date() <= self.to_date,
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
elif not self.from_date and not self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.company_id in self.company_ids,
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
elif not self.from_date and self.to_date and not self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() <= self.to_date,
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
elif self.from_date and not self.to_date and not self.company_ids:
order_lines = list(filter(lambda
x: self.from_date >= x.order_id.date_order.date(),
sale_order_line))
category = self._get_category()
res = self._get_category_wise(order_lines, category)
else:
category = self._get_category()
res = self._get_category_wise(sale_order_line, category)
datas = {
'ids': self,
'model': 'sale.report.category',
'form': res,
'categ_id': category,
'start_date': self.from_date,
'end_date': self.to_date,
}
return datas
def _get_category_wise(self, order_lines, category):
result = []
for cat in category:
for lines in order_lines:
if cat['id'] == lines.product_id.categ_id:
total = lines.product_id.taxes_id.amount +lines.price_subtotal
res = {
'so': lines.order_id.name,
'date': lines.order_id.date_order,
'product_id': lines.product_id.name,
'quantity': lines.product_uom_qty,
'tax': lines.product_id.taxes_id.amount,
'uom':lines.product_id.uom_id.name,
'price': lines.product_id.list_price,
'subtotal': lines.price_subtotal,
'total': total,
'category_id': lines.product_id.categ_id,
}
result.append(res)
return result
def _get_category(self):
category = []
for rec in self.category_ids:
a = {
'id': rec,
'name': rec.complete_name
}
category.append(a)
return category
def get_excel_category_report(self):
datas = self._get_data()
return {
'type': 'ir.actions.report',
'report_type': 'xlsx',
'data': {'model': 'sale.report.category',
'output_format': 'xlsx',
'options': json.dumps(datas, default=date_utils.json_default),
'report_name': 'Excel Report Name',
},
}
def get_xlsx_report(self, data, response):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
record = []
cell_format = workbook.add_format({'font_size': '12px', })
head = workbook.add_format({'align': 'center', 'bold': True, 'font_size': '20px'})
txt = workbook.add_format({'font_size': '10px', 'align': 'center'})
sheet.merge_range('G2:O3', 'Sales Category Report', head)
if data['start_date'] and data['end_date']:
sheet.write('G6', 'From:', cell_format)
sheet.merge_range('H6:I6', data['start_date'], txt)
sheet.write('M6', 'To:', cell_format)
sheet.merge_range('N6:O6', data['end_date'], txt)
format1 = workbook.add_format(
{'font_size': 10, 'align': 'center','bg_color':'#bbd5fc','border': 1})
format2 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,
'bg_color': '#6BA6FE', 'border': 1})
format3 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,'border': 1})
format4 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,'bg_color':'#c0dbfa'})
h_row = 7
h_col = 10
count = 0
row = 5
col = 6
row_number = 6
t_row = 6
if data['categ_id']:
record = data['categ_id']
for rec in record:
sheet.merge_range(h_row,h_col-4,h_row,h_col+4,rec['name'], format4)
row = row + count + 3
sheet.write(row, col, 'Order', format2)
col += 1
sheet.write(row, col, 'Date', format2)
sheet.set_column('H:H',15)
col += 1
sheet.write(row, col, 'Product', format2)
sheet.set_column('I:I',20)
col += 1
sheet.write(row, col, 'UOM', format2)
col += 1
sheet.write(row, col, 'Quantity', format2)
col += 1
sheet.write(row, col, 'Price', format2)
col += 1
sheet.write(row, col, 'Tax(%)', format2)
col += 1
sheet.write(row, col, 'Subtotal', format2)
col += 1
sheet.write(row, col, 'Total', format2)
col += 1
col = 6
count = 0
row_number = row_number + count + 3
t_qty = 0
t_price = 0
t_subtotal = 0
t_total = 0
t_col = 9
for val in data['form']:
if val['category_id'] == rec['id']:
count += 1
column_number = 6
sheet.write(row_number, column_number, val['so'], format1)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('H:H', 15)
column_number += 1
sheet.write(row_number, column_number, val['product_id'], format1)
sheet.set_column('I:I', 20)
column_number += 1
sheet.write(row_number, column_number, val['uom'], format1)
column_number += 1
sheet.write(row_number, column_number, val['quantity'], format1)
t_qty += val['quantity']
column_number += 1
sheet.write(row_number, column_number, val['price'], format1)
t_price += val['price']
column_number += 1
sheet.write(row_number, column_number, val['tax'], format1)
column_number += 1
sheet.write(row_number, column_number, val['subtotal'], format1)
t_subtotal += val['subtotal']
column_number += 1
sheet.write(row_number, column_number, val['total'], format1)
t_total += val['total']
column_number += 1
row_number += 1
t_row = t_row + count + 3
sheet.write(t_row, t_col, 'Total', format3)
t_col += 1
sheet.write(t_row, t_col, t_qty, format3)
t_col += 1
sheet.write(t_row, t_col, t_price, format3)
t_col += 2
sheet.write(t_row, t_col, t_subtotal, format3)
t_col += 1
sheet.write(t_row, t_col, t_total, format3)
t_col += 1
h_row = h_row + count + 3
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

31
sale_report_advanced/wizard/sale_category.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="category_wizard" model="ir.ui.view">
<field name="name">Sales Report Category</field>
<field name="model">sale.report.category</field>
<field name="arch" type="xml">
<form>
<group col="1">
<field name="from_date"/>
<field name="to_date"/>
<field name="category_ids" widget="many2many_tags"/>
<field name="company_ids" widget="many2many_tags"/>
</group>
<footer>
<button name="get_category_report" string="PDF Report"
type="object" class="btn-primary"/>
<button name="get_excel_category_report" string="XLSX Report"
type="object" class="btn-primary"/>
</footer>
</form>
</field>
</record>
<record id="sale_category_report" model="ir.actions.act_window">
<field name="name">Sales Category Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.report.category</field>
<field name="view_mode">form</field>
<field name="view_id" ref="category_wizard"/>
<field name="target">new</field>
</record>
</odoo>

230
sale_report_advanced/wizard/sale_indent.py

@ -0,0 +1,230 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
import io
from xlsxwriter import workbook
from odoo.tools import date_utils
from odoo import fields, models
from odoo.exceptions import UserError, ValidationError
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class SaleReportAdvance(models.TransientModel):
_name = "sale.report.indent"
customer_ids = fields.Many2many('res.partner', string="Customers", required=True)
category_ids = fields.Many2many('product.category', string="Categories", required=True)
from_date = fields.Date(string="Start Date")
to_date = fields.Date(string="End Date")
status = fields.Selection(
[('all', 'All'), ('draft', 'Draft'), ('sent', 'Quotation Sent'), ('sale', 'Sale Order'), ('done', 'Locked')],
string='Status', default='all', reqired=True)
company_ids = fields.Many2many('res.company', string='Companies')
today_date = fields.Date(default=fields.Date.today())
def get_category_report(self):
datas = self._get_data()
return self.env.ref('sale_report_advanced.action_sale_indent').report_action([], data=datas)
def _get_data(self):
sale_order_line = self.env['sale.order.line'].search([('order_id.state','!=','cancel')])
if self.from_date and self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() >= self.from_date and x.order_id.date_order.date() <= self.to_date and x.order_id.company_id in self.company_ids,
sale_order_line))
res = self._get_orders(order_lines)
elif not self.from_date and self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() <= self.to_date and x.order_id.company_id in self.company_ids,
sale_order_line))
res = self._get_orders(order_lines)
elif self.from_date and not self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() >= self.from_date and x.order_id.company_id in self.company_ids,
sale_order_line))
res = self._get_orders(order_lines)
elif self.from_date and self.to_date and not self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() >= self.from_date and x.order_id.date_order.date()<= self.to_date,
sale_order_line))
res = self._get_orders(order_lines)
elif not self.from_date and not self.to_date and self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.company_id in self.company_ids,
sale_order_line))
res = self._get_orders(order_lines)
elif not self.from_date and self.to_date and not self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() <= self.to_date,
sale_order_line))
res = self._get_orders(order_lines)
elif self.from_date and not self.to_date and not self.company_ids:
order_lines = list(filter(lambda
x: x.order_id.date_order.date() >= self.from_date,
sale_order_line))
res = self._get_orders(order_lines)
else:
res = self._get_orders(sale_order_line)
datas = {
'ids': self,
'model': 'sale.report.indent',
'form': res,
'categ_id': self._get_category(),
'partner_id': self._get_customers(),
'start_date': self.from_date,
'end_date': self.to_date,
}
return datas
def _get_orders(self, sale_order_line):
if self.status == 'all':
filtered_order = list(filter(lambda
x: x.order_id.partner_id in self.customer_ids and x.product_id.categ_id in self.category_ids,
sale_order_line))
else:
filtered_order = list(filter(lambda
x: x.order_id.partner_id in self.customer_ids and x.order_id.state in self.status and x.product_id.categ_id in self.category_ids,
sale_order_line))
return self._get_customer_wise(filtered_order)
def _get_customer_wise(self, order):
result = []
for rec in order:
res = {
'product_id': rec.product_id.name,
'quantity': rec.product_uom_qty,
'partner_id': rec.order_id.partner_id,
'category_id': rec.product_id.categ_id,
}
result.append(res)
return result
def _get_category(self):
category = []
for rec in self.category_ids:
a = {
'id': rec,
'name': rec.complete_name
}
category.append(a)
return category
def _get_customers(self):
customers = []
for rec in self.customer_ids:
a = {
'id': rec,
'name': rec.name
}
customers.append(a)
return customers
def get_excel_category_report(self):
datas = self._get_data()
return {
'type': 'ir.actions.report',
'report_type': 'xlsx',
'data': {'model': 'sale.report.indent',
'output_format': 'xlsx',
'options': json.dumps(datas, default=date_utils.json_default),
'report_name': 'Excel Report Name',
},
}
def get_xlsx_report(self, data, response):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
cell_format = workbook.add_format({'font_size': '12px', })
head = workbook.add_format({'align': 'center', 'bold': True, 'font_size': '20px'})
txt = workbook.add_format({'font_size': '10px', 'align': 'center'})
sheet.merge_range('G2:N3', 'Product Sales Indent Report', head)
if data['start_date'] and data['end_date']:
sheet.write('G6', 'From:', cell_format)
sheet.merge_range('H6:I6', data['start_date'], txt)
sheet.write('L6', 'To:', cell_format)
sheet.merge_range('M6:N6', data['end_date'], txt)
format1 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bg_color': '#f5f9ff', 'border': 1})
format3 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True, 'bg_color': '#6BA6FE', 'border': 1})
format4 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True, 'bg_color': '#b6d0fa', 'border': 1})
if data['categ_id']:
categ = data['categ_id']
if data['partner_id']:
partner = data['partner_id']
h_row = 6
h_col = 10
c_row = 6
row = 7
row_number = 6
for rec in partner:
count = 0
h_row += 1
sheet.merge_range(h_row, h_col - 1, h_row, h_col, rec['name'], format3)
c_row = c_row + 2
row += 2
row_number += 2
for cat in categ:
count += 2
c_col = 10
col = 9
sheet.merge_range(c_row, c_col - 1, c_row, c_col, cat['name'], format1)
sheet.write(row, col, 'Product', format4)
sheet.set_column('J:J', 17)
col += 1
sheet.write(row, col, 'Quantity', format4)
sheet.set_column('K:K', 17)
row_number += 2
c_count = 0
for val in data['form']:
if val['category_id'] == cat['id'] and val['partner_id'] == rec['id']:
c_count += 1
count += 1
column_number = 9
sheet.write(row_number, column_number, val['product_id'], format1)
sheet.set_column('J:J', 17)
column_number += 1
sheet.write(row_number, column_number, val['quantity'], format1)
sheet.set_column('K:K', 17)
row_number += 1
row = row + c_count + 2
c_row = c_row + c_count + 2
h_row = h_row + count + 1
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

37
sale_report_advanced/wizard/sale_indent.xml

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="indent_wizard" model="ir.ui.view">
<field name="name">Product Sales Indent</field>
<field name="model">sale.report.indent</field>
<field name="arch" type="xml">
<form>
<group col="1">
<field name="from_date"/>
<field name="to_date"/>
<field name="customer_ids" widget="many2many_tags"/>
</group>
<group>
<field name="category_ids" widget="many2many_tags"/>
<field name="status" widget="radio"/>
<field name="company_ids" widget="many2many_tags"/>
</group>
<footer>
<button name="get_category_report" string="PDF Report"
type="object" class="btn-primary"/>
<button name="get_excel_category_report" string="XLSX Report"
type="object" class="btn-primary"/>
</footer>
</form>
</field>
</record>
<record id="sale_indent_report" model="ir.actions.act_window">
<field name="name">Product Sales Indent Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.report.indent</field>
<field name="view_mode">form</field>
<field name="view_id" ref="indent_wizard"/>
<field name="target">new</field>
</record>
</odoo>

271
sale_report_advanced/wizard/sale_invoice.py

@ -0,0 +1,271 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
import io
from xlsxwriter import workbook
from odoo.tools import date_utils
from odoo import fields, models
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class SaleReportAdvance(models.TransientModel):
_name = "sale.report.invoice"
customer_ids = fields.Many2many('res.partner', string="Customers",required=True)
from_date = fields.Date(string="Start Date")
to_date = fields.Date(string="End Date")
status = fields.Selection([('open', 'Open'), ('paid', 'Paid'), ('both', 'Both')],
string='Status', default='open', reqired=True)
company_ids = fields.Many2many('res.company', string='Companies')
today_date = fields.Date(default=fields.Date.today())
def get_invoice_report(self):
datas = self._get_data()
return self.env.ref('sale_report_advanced.action_invoice_analysis').report_action([], data=datas)
def _get_data(self):
sale = self.env['sale.order'].search([('state','!=','cancel')])
if self.from_date and self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.date_order.date() <= self.to_date and x.company_id in self.company_ids,
sale))
elif not self.from_date and self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() <= self.to_date and x.company_id in self.company_ids,
sale))
elif self.from_date and not self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.company_id in self.company_ids,
sale))
elif self.from_date and self.to_date and not self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.date_order.date() <= self.to_date,
sale))
elif not self.from_date and not self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.company_id in self.company_ids,
sale))
elif not self.from_date and self.to_date and not self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() <= self.to_date,
sale))
elif self.from_date and not self.to_date and not self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date,
sale))
else:
sales_order = sale
result = []
customers = []
for rec in self.customer_ids:
a = {
'id': rec,
'name': rec.name
}
customers.append(a)
for so in sales_order:
for cust in customers:
if cust['id'] == so['partner_id']:
if so.invoice_ids:
if self.status == 'open':
for inv in so.invoice_ids:
if inv.payment_state != 'paid':
res = {
'so': so.name,
'partner_id': so.partner_id,
'order_date': so.date_order,
'invoice': inv.name,
'date': inv.invoice_date,
'invoiced': inv.amount_total,
'paid': inv.amount_total-inv.amount_residual,
'due': inv.amount_residual,
}
result.append(res)
elif self.status == 'paid':
for inv in so.invoice_ids:
if inv.payment_state == 'paid':
res = {
'so': so.name,
'partner_id': so.partner_id,
'order_date': so.date_order,
'invoice': inv.name,
'date': inv.invoice_date,
'invoiced': inv.amount_total,
'paid': inv.amount_total-inv.amount_residual,
'due': inv.amount_residual,
}
result.append(res)
else:
for inv in so.invoice_ids:
res = {
'so': so.name,
'partner_id': so.partner_id,
'order_date': so.date_order,
'invoice': inv.name,
'date': inv.invoice_date,
'invoiced': inv.amount_total,
'paid': inv.amount_total-inv.amount_residual,
'due': inv.amount_residual,
}
result.append(res)
datas = {
'ids': self,
'model': 'sale.report.invoice',
'form': result,
'partner_id': customers,
'start_date': self.from_date,
'end_date': self.to_date,
'status': self.status,
}
return datas
def get_excel_invoice_report(self):
datas = self._get_data()
return {
'type': 'ir.actions.report',
'report_type': 'xlsx',
'data': {'model': 'sale.report.invoice',
'output_format': 'xlsx',
'options': json.dumps(datas, default=date_utils.json_default),
'report_name': 'Excel Report Name',
},
}
def get_xlsx_report(self, data, response):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
record =[]
cell_format = workbook.add_format({'font_size': '12px',})
head = workbook.add_format({'align': 'center', 'bold': True, 'font_size': '20px'})
txt = workbook.add_format({'font_size': '10px','align': 'center'})
sheet.merge_range('G2:M3', 'Invoice Analysis Report', head)
if data['start_date'] and data['end_date']:
sheet.write('G6', 'From:', cell_format)
sheet.merge_range('H6:I6', data['start_date'], txt)
sheet.write('K6', 'To:', cell_format)
sheet.merge_range('L6:M6', data['end_date'], txt)
format1 = workbook.add_format(
{'font_size': 10, 'align': 'left','bg_color':'#bbd5fc','border': 1})
format4 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bg_color': '#bbd5fc', 'border': 1})
format2 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,
'bg_color': '#6BA6FE', 'border': 1})
format3 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True})
record = data['partner_id']
h_row = 7
h_col = 9
count = 0
row = 5
col = 6
row_number = 6
t_row = 6
if data['partner_id']:
for rec in record:
sheet.merge_range(h_row, h_col-3,h_row,h_col+3, rec['name'], format4)
row= row + count + 3
sheet.write(row, col, 'Order Number', format2)
sheet.set_column('G:G', 12)
col += 1
sheet.write(row, col, 'Order Date', format2)
sheet.set_column('H:H', 15)
col += 1
sheet.write(row, col, 'Invoice Number', format2)
sheet.set_column('I:I', 13)
col += 1
sheet.write(row, col, 'Invoice Date', format2)
sheet.set_column('J:J', 15)
col += 1
sheet.write(row, col, 'Amount Invoiced', format2)
sheet.set_column('K:K', 11)
col += 1
sheet.write(row, col, 'Amount Paid', format2)
sheet.set_column('L:L', 11)
col += 1
sheet.write(row, col, 'Amount Due', format2)
sheet.set_column('M:M', 11)
col += 1
col =6
count=0
t_invoiced = 0
t_paid = 0
t_due = 0
row_number=row_number + count + 3
t_col = 9
for val in data['form']:
if val['partner_id'] == rec['id']:
count +=1
column_number = 6
sheet.write(row_number, column_number, val['so'],format1)
sheet.set_column('G:G', 12)
column_number += 1
sheet.write(row_number, column_number, val['order_date'], format1)
sheet.set_column('H:H', 15)
column_number += 1
sheet.write(row_number, column_number, val['invoice'], format1)
sheet.set_column('I:I', 13)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('J:J', 15)
column_number += 1
sheet.write(row_number, column_number, val['invoiced'], format1)
sheet.set_column('K:K', 14)
t_invoiced += val['invoiced']
column_number += 1
sheet.write(row_number, column_number, val['paid'], format1)
sheet.set_column('L:L', 11)
t_paid += val['paid']
column_number += 1
sheet.write(row_number, column_number, val['due'], format1)
sheet.set_column('M:M', 11)
t_due += val['due']
row_number += 1
t_row = t_row + count + 3
sheet.write(t_row, t_col, 'Total', format3)
sheet.set_column('J:J', 15)
t_col += 1
sheet.write(t_row, t_col, t_invoiced, format3)
sheet.set_column('K:K', 14)
t_col += 1
sheet.write(t_row, t_col, t_paid, format3)
sheet.set_column('L:L', 11)
t_col += 1
sheet.write(t_row, t_col, t_due, format3)
sheet.set_column('M:M', 11)
h_row = h_row + count + 3
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

35
sale_report_advanced/wizard/sale_invoice.xml

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="invoice_wizard" model="ir.ui.view">
<field name="name">Sales Invoice Analysis</field>
<field name="model">sale.report.invoice</field>
<field name="arch" type="xml">
<form>
<group col="1">
<field name="from_date"/>
<field name="to_date"/>
<field name="customer_ids" widget="many2many_tags"/>
<field name="company_ids" widget="many2many_tags"/>
</group>
<group col="2">
<field name="status" widget="radio"></field>
</group>
<footer>
<button name="get_invoice_report" string="PDF Report"
type="object" class="btn-primary"/>
<button name="get_excel_invoice_report" string="XLSX Report"
type="object" class="btn-primary"/>
</footer>
</form>
</field>
</record>
<record id="sale_invoice_report" model="ir.actions.act_window">
<field name="name">Sale Invoice Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.report.invoice</field>
<field name="view_mode">form</field>
<field name="view_id" ref="invoice_wizard"/>
<field name="target">new</field>
</record>
</odoo>

428
sale_report_advanced/wizard/sale_report.py

@ -0,0 +1,428 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
import io
from datetime import datetime
from xlsxwriter import workbook
from odoo.tools import date_utils
from odoo import fields, models
from odoo.exceptions import UserError, ValidationError
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class SaleReportAdvance(models.TransientModel):
_name = "sale.report.advance"
customer_ids = fields.Many2many('res.partner', string="Customers")
product_ids = fields.Many2many('product.product', string='Products')
from_date = fields.Date(string="Start Date")
to_date = fields.Date(string="End Date")
type = fields.Selection([('customer', 'Customers'), ('product', 'Products'), ('both', 'Both')],
string='Report Print By', default='customer', reqired=True)
company_ids = fields.Many2many('res.company', string='Companies')
today_date = fields.Date(default=fields.Date.today())
def _get_data(self):
sale = self.env['sale.order'].search([('state','!=','cancel')])
sales_order_line = self.env['sale.order.line'].search([('order_id.state','!=','cancel')])
if self.from_date and self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.date_order.date() <= self.to_date and x.company_id in self.company_ids,
sale))
elif not self.from_date and self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() <= self.to_date and x.company_id in self.company_ids,
sale))
elif self.from_date and not self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.company_id in self.company_ids,
sale))
elif self.from_date and self.to_date and not self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date and x.date_order.date() <= self.to_date,
sale))
elif not self.from_date and not self.to_date and self.company_ids:
sales_order = list(filter(lambda
x: x.company_id in self.company_ids,
sale))
elif not self.from_date and self.to_date and not self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() <= self.to_date,
sale))
elif self.from_date and not self.to_date and not self.company_ids:
sales_order = list(filter(lambda
x: x.date_order.date() >= self.from_date,
sale))
else:
sales_order = sale
result = []
customers = []
products = []
for rec in self.customer_ids:
a = {
'id': rec,
'name': rec.name
}
customers.append(a)
for rec in self.product_ids:
a = {
'id': rec,
'name': rec.name
}
products.append(a)
if self.type == 'product':
for rec in products:
for lines in sales_order_line:
if lines.product_id == rec['id']:
profit = round(lines.product_id.list_price - lines.product_id.standard_price, 2)
if lines.product_id.standard_price != 0:
margin = round((profit * 100) / lines.product_id.standard_price, 2)
res = {
'sequence': lines.order_id.name,
'date': lines.order_id.date_order,
'product_id': lines.product_id,
'quantity': lines.product_uom_qty,
'cost': lines.product_id.standard_price,
'price': lines.product_id.list_price,
'profit': profit,
'margin': margin,
'partner': lines.order_id.partner_id.name,
}
result.append(res)
if self.type == 'customer':
for rec in customers:
for so in sales_order:
if so.partner_id == rec['id']:
for lines in so.order_line:
profit = round(lines.product_id.list_price - lines.product_id.standard_price, 2)
if lines.product_id.standard_price != 0:
margin = round((profit * 100) / lines.product_id.standard_price, 2)
res = {
'sequence': so.name,
'date': so.date_order,
'product': lines.product_id.name,
'quantity': lines.product_uom_qty,
'cost': lines.product_id.standard_price,
'price': lines.product_id.list_price,
'profit': profit,
'margin': margin,
'partner_id': so.partner_id,
}
result.append(res)
if self.type == 'both':
for rec in customers:
for p in products:
for so in sales_order:
if so.partner_id == rec['id']:
for lines in so.order_line:
if lines.product_id == p['id']:
profit = round(lines.product_id.list_price - lines.product_id.standard_price, 2)
if lines.product_id.standard_price != 0:
margin = round((profit * 100) / lines.product_id.standard_price, 2)
res = {
'sequence': so.name,
'date': so.date_order,
'product': lines.product_id.name,
'quantity': lines.product_uom_qty,
'cost': lines.product_id.standard_price,
'price': lines.product_id.list_price,
'profit': profit,
'margin': margin,
'partner': so.partner_id.name,
}
result.append(res)
if self.from_date and self.to_date and not self.customer_ids and not self.product_ids:
for so in sales_order:
for lines in so.order_line:
profit = round(lines.product_id.list_price - lines.product_id.standard_price, 2)
if lines.product_id.standard_price != 0:
margin = round((profit * 100) / lines.product_id.standard_price, 2)
res = {
'sequence': so.name,
'date': so.date_order,
'product': lines.product_id.name,
'quantity': lines.product_uom_qty,
'cost': lines.product_id.standard_price,
'price': lines.product_id.list_price,
'profit': profit,
'margin': margin,
'partner': so.partner_id.name,
}
result.append(res)
datas = {
'ids': self,
'model': 'sale.report.advance',
'form': result,
'partner_id': customers,
'product_id': products,
'start_date': self.from_date,
'end_date': self.to_date,
'type': self.type,
'no_value': False,
}
if self.from_date and self.to_date and not self.customer_ids and not self.product_ids:
datas['no_value']=True
return datas
def get_report(self):
datas = self._get_data()
return self.env.ref('sale_report_advanced.action_sale_report').report_action([], data=datas)
def get_excel_report(self):
datas = self._get_data()
return {
'type': 'ir.actions.report',
'report_type': 'xlsx',
'data': {'model': 'sale.report.advance',
'output_format': 'xlsx',
'options': json.dumps(datas, default=date_utils.json_default),
'report_name': 'Excel Report Name',
},
}
def get_xlsx_report(self, data, response):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
record = []
cell_format = workbook.add_format({'font_size': '12px', })
head = workbook.add_format({'align': 'center', 'bold': True, 'font_size': '20px'})
txt = workbook.add_format({'font_size': '10px', 'align': 'center'})
sheet.merge_range('G2:N3', 'Sales Profit Report', head)
if data['start_date'] and data['end_date']:
sheet.write('G6', 'From:', cell_format)
sheet.merge_range('H6:I6', data['start_date'], txt)
sheet.write('L6', 'To:', cell_format)
sheet.merge_range('M6:N6', data['end_date'], txt)
format1 = workbook.add_format(
{'font_size': 10, 'align': 'center','bg_color':'#bbd5fc','border': 1})
format2 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,
'bg_color': '#6BA6FE', 'border': 1})
format4 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,'border': 1})
format3 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True, 'bg_color': '#c0dbfa', 'border': 1})
if data['type'] == 'product':
record = data['product_id']
if data['type'] == 'customer':
record = data['partner_id']
h_row = 7
h_col = 9
count = 0
row = 5
col = 6
row_number = 6
t_row = 6
if data['type'] == 'product' or data['type'] == 'customer':
for rec in record:
sheet.merge_range(h_row, h_col-3,h_row,h_col+4,rec['name'], format3)
row = row + count + 3
sheet.write(row, col, 'Order', format2)
col += 1
sheet.write(row, col, 'Date', format2)
sheet.set_column('H:H', 15)
col += 1
if data['type'] == 'product':
sheet.write(row, col, 'Customer', format2)
sheet.set_column('I:I', 20)
col += 1
elif data['type'] == 'customer':
sheet.write(row, col, 'Product', format2)
sheet.set_column('I:I', 20)
col += 1
sheet.write(row, col, 'Quantity', format2)
col += 1
sheet.write(row, col, 'Cost', format2)
col += 1
sheet.write(row, col, 'Price', format2)
col += 1
sheet.write(row, col, 'Profit', format2)
col += 1
sheet.write(row, col, 'Margin(%)', format2)
col += 1
col = 6
count = 0
row_number = row_number + count + 3
t_qty = 0
t_cost = 0
t_price = 0
t_profit = 0
t_margin = 0
t_col = 8
for val in data['form']:
if data['type'] == 'customer':
if val['partner_id'] == rec['id']:
count += 1
column_number = 6
sheet.write(row_number, column_number, val['sequence'], format1)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('H:H', 15)
column_number += 1
sheet.write(row_number, column_number, val['product'], format1)
sheet.set_column('I:I', 20)
column_number += 1
sheet.write(row_number, column_number, val['quantity'], format1)
t_qty += val['quantity']
column_number += 1
sheet.write(row_number, column_number, val['cost'], format1)
t_cost += val['cost']
column_number += 1
sheet.write(row_number, column_number, val['price'], format1)
t_price += val['price']
column_number += 1
sheet.write(row_number, column_number, val['profit'], format1)
t_profit += val['profit']
column_number += 1
sheet.write(row_number, column_number, val['margin'], format1)
t_margin += val['margin']
column_number += 1
row_number += 1
if data['type'] == 'product':
if val['product_id'] == rec['id']:
count += 1
column_number = 6
sheet.write(row_number, column_number, val['sequence'], format1)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('H:H', 15)
column_number += 1
sheet.write(row_number, column_number, val['partner'], format1)
sheet.set_column('I:I', 20)
column_number += 1
sheet.write(row_number, column_number, val['quantity'], format1)
t_qty += val['quantity']
column_number += 1
sheet.write(row_number, column_number, val['cost'], format1)
t_cost += val['cost']
column_number += 1
sheet.write(row_number, column_number, val['price'], format1)
t_price += val['price']
column_number += 1
sheet.write(row_number, column_number, val['profit'], format1)
t_profit += val['profit']
column_number += 1
sheet.write(row_number, column_number, val['margin'], format1)
t_margin += val['margin']
column_number += 1
row_number += 1
t_row = t_row + count + 3
sheet.write(t_row, t_col, 'Total', format4)
t_col += 1
sheet.write(t_row, t_col, t_qty, format4)
t_col += 1
sheet.write(t_row, t_col, t_cost, format4)
t_col += 1
sheet.write(t_row, t_col, t_price, format4)
t_col += 1
sheet.write(t_row, t_col, t_profit, format4)
t_col += 1
sheet.write(t_row, t_col, t_margin, format4)
t_col += 1
h_row = h_row + count + 3
if data['type'] == 'both' or data['no_value'] == True:
row += 3
row_number += 2
t_qty = 0
t_cost = 0
t_price = 0
t_profit = 0
t_margin = 0
t_col = 9
sheet.write(row, col, 'Order', format2)
col += 1
sheet.write(row, col, 'Date', format2)
sheet.set_column('H:H', 15)
col += 1
sheet.write(row, col, 'Customer', format2)
sheet.set_column('I:I', 20)
col += 1
sheet.write(row, col, 'Product', format2)
sheet.set_column('J:J', 20)
col += 1
sheet.write(row, col, 'Quantity', format2)
col += 1
sheet.write(row, col, 'Cost', format2)
col += 1
sheet.write(row, col, 'Price', format2)
col += 1
sheet.write(row, col, 'Profit', format2)
col += 1
sheet.write(row, col, 'Margin', format2)
col += 1
row_number+=1
for val in data['form']:
column_number = 6
sheet.write(row_number, column_number, val['sequence'], format1)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column('H:H', 15)
column_number += 1
sheet.write(row_number, column_number, val['partner'], format1)
sheet.set_column('I:I', 20)
column_number += 1
sheet.write(row_number, column_number, val['product'], format1)
sheet.set_column('J:J', 20)
column_number += 1
sheet.write(row_number, column_number, val['quantity'], format1)
t_qty += val['quantity']
column_number += 1
sheet.write(row_number, column_number, val['cost'], format1)
t_cost += val['cost']
column_number += 1
sheet.write(row_number, column_number, val['price'], format1)
t_price += val['price']
column_number += 1
sheet.write(row_number, column_number, val['profit'], format1)
t_profit += val['profit']
column_number += 1
sheet.write(row_number, column_number, val['margin'], format1)
t_margin += val['margin']
column_number += 1
row_number += 1
sheet.write(row_number, t_col, 'Total', format4)
t_col += 1
sheet.write(row_number, t_col, t_qty, format4)
t_col += 1
sheet.write(row_number, t_col, t_cost, format4)
t_col += 1
sheet.write(row_number, t_col, t_price, format4)
t_col += 1
sheet.write(row_number, t_col, t_profit, format4)
t_col += 1
sheet.write(row_number, t_col, t_margin, format4)
t_col += 1
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

35
sale_report_advanced/wizard/sale_report.xml

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="report_view" model="ir.ui.view">
<field name="name">Sales Product Profit</field>
<field name="model">sale.report.advance</field>
<field name="arch" type="xml">
<form>
<group col="1">
<field name="from_date"/>
<field name="customer_ids" widget="many2many_tags" attrs="{'invisible': [('type', '=', 'product')]}"/>
<field name="type" widget="radio"></field>
<field name="company_ids" widget="many2many_tags"/>
<field name="product_ids" widget="many2many_tags" attrs="{'invisible': [('type', '=', 'customer')]}"/>
</group>
<group col="2">
<field name="to_date"/>
</group>
<footer>
<button name="get_report" string="PDF Report"
type="object" class="btn-primary"/>
<button name="get_excel_report" string="XLSX Report"
type="object" class="btn-primary"/>
</footer>
</form>
</field>
</record>
<record id="sale_report_advance" model="ir.actions.act_window">
<field name="name">Sale Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.report.advance</field>
<field name="view_mode">form</field>
<field name="view_id" ref="report_view"/>
<field name="target">new</field>
</record>
</odoo>

219
sale_report_advanced/wizard/weekly_wise.py

@ -0,0 +1,219 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
import io
import calendar
from datetime import timedelta, datetime
from dateutil import rrule
from reportlab.platypus.tableofcontents import delta
from xlsxwriter import workbook
from odoo.tools import date_utils
from odoo import fields, models,_
from calendar import monthrange
from odoo.exceptions import UserError, ValidationError
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class SaleReportAdvance(models.TransientModel):
_name = "sale.report.weekly"
date = fields.Date(string='Date', required=True)
invoice_status = fields.Selection(
[('invoiced', 'Fully Invoiced'),
('to invoice', 'To Invoice'),
('no', 'Nothing to Invoice')],
string='Invoice Status', default='no', required=True)
amount_type = fields.Selection(
[('total', 'Total Amount'), ('untax', 'Untaxed Amount')],
string='Total Amount', default='total')
today_date = fields.Date(default=fields.Date.today())
def get_weekly_report(self):
datas = self._get_data()
return self.env.ref('sale_report_advanced.action_sales_weekly').report_action([], data=datas)
def _get_data(self):
result = []
times=[{'id':'morning','name':'Morning (5:00-12:00)'}, {'id':'noon','name':'Noon (1:00-17:00)'},{'id':'evening','name':'Evening (18:00-23:00)'}]
if self.invoice_status == 'invoiced':
sale_order = self.env['sale.order'].sudo().search([('invoice_status', '=', self.invoice_status),('date_order','>',self.date),('state','!=','cancel')])
elif self.invoice_status == 'to invoice':
sale_order = self.env['sale.order'].sudo().search([('invoice_status', '=', self.invoice_status),('date_order','>',self.date),('state','!=','cancel')])
else:
sale_order = self.env['sale.order'].sudo().search([('invoice_status', '=', self.invoice_status),('date_order','>',self.date),('state','!=','cancel')])
for rec in sale_order:
if self.amount_type=='total':
if rec.date_order.hour > 5 and rec.date_order.hour <=12:
res = {
'order': rec.name,
'amount':rec.amount_total ,
'time':'morning',
'date':rec.date_order.date()
}
result.append(res)
if rec.date_order.hour > 12 and rec.date_order.hour <=17:
res = {
'order': rec.name,
'amount': rec.amount_total,
'time': 'noon',
'date': rec.date_order.date()
}
result.append(res)
if rec.date_order.hour > 17 and rec.date_order.hour <=23:
res = {
'order': rec.name,
'amount': rec.amount_total,
'time': 'evening',
'date': rec.date_order.date()
}
result.append(res)
else:
if rec.date_order.hour > 5 and rec.date_order.hour <= 12:
res = {
'order':rec.name,
'amount':rec.amount_untaxed,
'time':'morning',
'date': rec.date_order.date()
}
result.append(res)
if rec.date_order.hour > 12 and rec.date_order.hour <= 17:
res = {
'order': rec.name,
'amount': rec.amount_untaxed,
'time': 'noon',
'date': rec.date_order.date()
}
result.append(res)
if rec.date_order.hour > 17 and rec.date_order.hour <= 23:
res = {
'order': rec.name,
'amount': rec.amount_untaxed,
'time': 'evening',
'date': rec.date_order.date()
}
result.append(res)
datas = {
'ids': self,
'model': 'sale.report.weekly',
'form': result,
'date': self.date,
'type':self.amount_type,
'times':times
}
return datas
def get_excel_weekly_report(self):
datas = self._get_data()
return {
'type': 'ir.actions.report',
'report_type': 'xlsx',
'data': {'model': 'sale.report.weekly',
'output_format': 'xlsx',
'options': json.dumps(datas, default=date_utils.json_default),
'report_name': 'Excel Report Name',
},
}
def get_xlsx_report(self, data, response):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
head = workbook.add_format({'align': 'center', 'bold': True, 'font_size': '20px'})
sheet.merge_range('G2:I3', 'Hourly Sales Report', head)
format1 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bg_color': '#f5f9ff', 'border': 1})
format2 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,
'bg_color': '#6BA6FE', 'border': 1})
format3 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True,'bg_color':'#95ff63','border': 1})
format4 = workbook.add_format(
{'font_size': 10, 'align': 'center', 'bold': True, 'border': 1})
h_row = 7
h_col = 7
count = 0
row = 4
row_number = 5
for rec in data['times']:
col = 6
row = row + count + 4
sheet.merge_range(h_row,h_col-1,h_row,h_col+1,rec['name'] , format3)
sheet.write(row, col, 'Order', format2)
sheet.set_column(row, col, 15)
col += 1
sheet.write(row, col, 'Date', format2)
sheet.set_column(row, col, 15)
col += 1
if data['type'] =='total':
sheet.write(row, col, 'Total', format2)
sheet.set_column(row, col, 15)
col += 1
else:
sheet.write(row, col, 'Untaxed Total', format2)
sheet.set_column(row, col, 15)
col += 1
t_total = 0
row_number = row_number +4
count=0
t_col = 7
for val in data['form']:
if val['time'] == rec['id']:
count += 1
column_number = 6
sheet.write(row_number, column_number, val['order'], format1)
sheet.set_column(row_number, column_number, 15)
column_number += 1
sheet.write(row_number, column_number, val['date'], format1)
sheet.set_column(row_number, column_number, 15)
column_number += 1
sheet.write(row_number, column_number, val['amount'], format1)
t_total += val['amount']
sheet.set_column(row_number, column_number, 15)
row_number+=1
sheet.write(row_number, t_col, 'Total', format4)
sheet.set_column(row_number, t_col, 15)
t_col += 1
sheet.write(row_number, t_col, t_total, format4)
h_row= h_row+ count+4
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

32
sale_report_advanced/wizard/weekly_wise.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="weekly_wizard" model="ir.ui.view">
<field name="name">Sales Hourly Wise report</field>
<field name="model">sale.report.weekly</field>
<field name="arch" type="xml">
<form>
<group col="1">
<field name="date"/>
<field name="invoice_status" widget="dropdown"/>
</group>
<group>
<field name="amount_type" widget="radio"/>
</group>
<footer>
<button name="get_weekly_report" string="PDF Report"
type="object" class="btn-primary"/>
<button name="get_excel_weekly_report" string="XLSX Report"
type="object" class="btn-primary"/>
</footer>
</form>
</field>
</record>
<record id="sale_weekly_report" model="ir.actions.act_window">
<field name="name">Hourly Sales Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.report.weekly</field>
<field name="view_mode">form</field>
<field name="view_id" ref="weekly_wizard"/>
<field name="target">new</field>
</record>
</odoo>

41
serial_no_from_mo/README.rst

@ -0,0 +1,41 @@
Generate Lot/Serial Number From Manufacturing Order
===================================================
* Generate Lot/Serial Number From Manufacturing Order for Odoo 15
Installation
============
- www.odoo.com/documentation/15.0/setup/install.html
- Install our custom addon
License
-------
General Public License, Version 3 (LGPL v3).
(https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html)
Company
-------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer:
Athul @ Cybrosys
Contacts
--------
* Mail Contact : odoo@cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
This module is maintained by Cybrosys Technologies.
For support and more information, please visit https://www.cybrosys.com
Further information
===================
HTML Description: `<static/description/index.html>`__

23
serial_no_from_mo/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models

44
serial_no_from_mo/__manifest__.py

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'Generate Lot/Serial Number From Manufacturing Order',
'version': '15.0.1.0.0',
'summary': """Auto generate Serial/lot from manufacturing order""",
'description': """Automatically generates lot/serial number for product while confirming
the manufacturing order.User can set lot/seral number sequence in
product wise and global wise""",
'category': 'Manufacturing',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'depends': ['base', 'mrp'],
'website': 'https://www.cybrosys.com',
'data': [
'views/res_settings.xml',
'views/product_template.xml',
],
'images': ['static/description/banner.png'],
'license': 'LGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

6
serial_no_from_mo/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module Generate Lot/Serial Number from Manufacturing order
#### 29.4.2022
#### Version 15.0.1.0.0
##### ADD
- Initial Commit for serial_no_from_mo

23
serial_no_from_mo/models/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import res_settings
from . import product_template

81
serial_no_from_mo/models/product_template.py

@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api
class ProductTemplate(models.Model):
_inherit = 'product.template'
digit = fields.Integer(string="Number of Digits")
prefix = fields.Char(string="Prefix")
class MrpProduction(models.Model):
_inherit = "mrp.production"
def action_confirm(self):
parms = self.env['ir.config_parameter'].sudo()
type = parms.get_param('serial_selection')
if self.product_id.tracking == 'serial' or self.product_id.tracking == 'lot':
if type == 'global':
digit = parms.get_param('digit')
prefix = parms.get_param('prefix')
seq = self.env['ir.sequence'].sudo().search([('code', '=', 'mrp.production.sequence')])
if seq:
seq.write({
'prefix': prefix,
'padding': digit
})
if not seq:
self.env['ir.sequence'].create({
'name': 'Mrp Production',
'implementation': 'standard',
'code': 'mrp.production.sequence',
'prefix': prefix,
'padding': digit})
serial_id = self.env['stock.production.lot'].create({
'name': self.env['ir.sequence'].sudo().next_by_code('mrp.production.sequence'),
'product_id': self.product_id.id,
'company_id': self.company_id.id,
})
else:
seq = self.env['ir.sequence'].sudo().search([('code', '=', self.product_id.name)])
if seq:
seq.write({
'prefix': self.product_id.product_tmpl_id.prefix,
'padding': self.product_id.product_tmpl_id.digit,
})
if not seq:
self.env['ir.sequence'].create({
'name': 'Mrp Production',
'implementation': 'standard',
'code': self.product_id.name,
'prefix': self.product_id.product_tmpl_id.prefix,
'padding': self.product_id.product_tmpl_id.digit})
serial_id = self.env['stock.production.lot'].create({
'name': self.env['ir.sequence'].sudo().next_by_code(self.product_id.name),
'product_id': self.product_id.id,
'company_id': self.company_id.id,
})
self.lot_producing_id = serial_id
return super(MrpProduction, self).action_confirm()

50
serial_no_from_mo/models/res_settings.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
serial_selection = fields.Selection([('global', 'Global'), ('product_wise', 'Product Wise')],
default='global', string="Serial number Selection Method")
digit = fields.Integer(string="Number of Digits")
prefix = fields.Char(string="Prefix")
@api.model
def get_values(self):
res = super(ResConfigSettings, self).get_values()
params = self.env['ir.config_parameter'].sudo()
serial_selection = params.get_param('serial_selection')
digit = params.get_param('digit')
prefix = params.get_param('prefix')
res.update(serial_selection=serial_selection, digit=digit, prefix=prefix)
return res
def set_values(self):
super(ResConfigSettings, self).set_values()
parms = self.env['ir.config_parameter'].sudo()
parms.set_param("serial_selection", self.serial_selection)
parms.set_param("digit", self.digit)
parms.set_param("prefix", self.prefix)

BIN
serial_no_from_mo/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
serial_no_from_mo/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
serial_no_from_mo/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
serial_no_from_mo/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
serial_no_from_mo/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
serial_no_from_mo/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
serial_no_from_mo/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
serial_no_from_mo/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
serial_no_from_mo/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
serial_no_from_mo/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
serial_no_from_mo/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
serial_no_from_mo/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
serial_no_from_mo/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
serial_no_from_mo/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save