diff --git a/dashboard_pos/README.rst b/dashboard_pos/README.rst new file mode 100644 index 000000000..604a7baa1 --- /dev/null +++ b/dashboard_pos/README.rst @@ -0,0 +1,18 @@ +POS Dashboard v13 +================= +POS Dashboard + +Installation +============ + - www.odoo.com/documentation/13.0/setup/install.html + - Install our custom addon + +Configuration +============= + + No additional configurations needed + +Credits +======= + Developer: Irfan v13 @ cybrosys, Contact: odoo@cybrosys.com + diff --git a/dashboard_pos/__init__.py b/dashboard_pos/__init__.py new file mode 100644 index 000000000..28d9debd4 --- /dev/null +++ b/dashboard_pos/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies (). +# Author: Irfan () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import models diff --git a/dashboard_pos/__manifest__.py b/dashboard_pos/__manifest__.py new file mode 100644 index 000000000..a18f31708 --- /dev/null +++ b/dashboard_pos/__manifest__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies (). +# Author: Irfan () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +{ + 'name': "POS Dashboard", + 'version': '13.0.1.0.0', + 'summary': """POS Dashboard""", + 'description': """POS Dashboard""", + 'category': 'Point of Sale', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.openhrms.com", + 'depends': ['hr', 'point_of_sale'], + 'external_dependencies': { + 'python': ['pandas'], + }, + + 'data': [ + 'views/dashboard_views.xml' + ], + 'qweb': ["static/src/xml/pos_dashboard.xml"], + 'images': ['static/description/banner.png'], + 'license': "AGPL-3", + 'installable': True, + 'application': False, +} \ No newline at end of file diff --git a/dashboard_pos/doc/RELEASE_NOTES.md b/dashboard_pos/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..2e7b500e4 --- /dev/null +++ b/dashboard_pos/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 20.03.2020 +#### Version 13.0.1.0.0 + +##### Initial Commit for pos_dashboard + diff --git a/dashboard_pos/models/__init__.py b/dashboard_pos/models/__init__.py new file mode 100644 index 000000000..4e73b4f90 --- /dev/null +++ b/dashboard_pos/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies (). +# Author: Irfan () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import pos_dashboard diff --git a/dashboard_pos/models/pos_dashboard.py b/dashboard_pos/models/pos_dashboard.py new file mode 100644 index 000000000..6739722a0 --- /dev/null +++ b/dashboard_pos/models/pos_dashboard.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies (). +# Author: Irfan () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +import pytz +from odoo import models, fields, api +from datetime import timedelta, datetime, date + + +class PosDashboard(models.Model): + _inherit = 'pos.order' + + @api.model + def get_department(self, option): + company_id = self.env.company.id + if option == 'pos_hourly_sales': + + user_tz = self.env.user.tz if self.env.user.tz else pytz.UTC + query = '''select EXTRACT(hour FROM date_order at time zone 'utc' at time zone '{}') + as date_month,sum(amount_total) from pos_order where + EXTRACT(month FROM date_order::date) = EXTRACT(month FROM CURRENT_DATE) + AND pos_order.company_id = ''' + str( + company_id) + ''' group by date_month ''' + query = query.format(user_tz) + label = 'HOURS' + elif option == 'pos_monthly_sales': + query = '''select date_order::date as date_month,sum(amount_total) from pos_order where + EXTRACT(month FROM date_order::date) = EXTRACT(month FROM CURRENT_DATE) AND pos_order.company_id = ''' + str( + company_id) + ''' group by date_month ''' + label = 'DAYS' + else: + query = '''select TO_CHAR(date_order,'MON')date_month,sum(amount_total) from pos_order where + EXTRACT(year FROM date_order::date) = EXTRACT(year FROM CURRENT_DATE) AND pos_order.company_id = ''' + str( + company_id) + ''' group by date_month''' + label = 'MONTHS' + + self._cr.execute(query) + docs = self._cr.dictfetchall() + order = [] + for record in docs: + order.append(record.get('sum')) + today = [] + for record in docs: + today.append(record.get('date_month')) + final = [order, today, label] + return final + + @api.model + def get_details(self): + company_id = self.env.company.id + cr = self._cr + cr.execute( + """select pos_payment_method.name,sum(amount) from pos_payment inner join pos_payment_method on + pos_payment_method.id=pos_payment.payment_method_id group by pos_payment_method.name ORDER + BY sum(amount) DESC; """) + payment_details = cr.fetchall() + cr.execute( + '''select hr_employee.name,sum(pos_order.amount_paid) as total,count(pos_order.amount_paid) as orders + from pos_order inner join hr_employee on pos_order.user_id = hr_employee.user_id + where pos_order.company_id =''' + str(company_id) + '''GROUP BY hr_employee.name order by total DESC;''') + salesperson = cr.fetchall() + total_sales = [] + for rec in salesperson: + rec = list(rec) + sym_id = rec[1] + company = self.env.company + if company.currency_id.position == 'after': + rec[1] = "%s %s" % (sym_id, company.currency_id.symbol) + else: + rec[1] = "%s %s" % (company.currency_id.symbol, sym_id) + rec = tuple(rec) + total_sales.append(rec) + cr.execute( + '''select DISTINCT(product_template.name) as product_name,sum(qty) as total_quantity from + pos_order_line inner join product_product on product_product.id=pos_order_line.product_id inner join + product_template on product_product.product_tmpl_id = product_template.id where pos_order_line.company_id =''' + str( + company_id) + ''' group by product_template.id ORDER + BY total_quantity DESC Limit 10 ''') + selling_product = cr.fetchall() + sessions = self.env['pos.config'].search([]) + sessions_list = [] + dict = { + 'closing_control': 'Closed', + 'opened': 'Opened', + 'new_session': 'New Session', + 'opening_control': "Opening Control" + } + for session in sessions: + sessions_list.append({ + 'session': session.name, + 'status': dict.get(session.pos_session_state) + }) + payments =[] + for rec in payment_details: + rec = list(rec) + sym_id = rec[1] + company = self.env.company + if company.currency_id.position == 'after': + rec[1] = "%s %s" % (sym_id, company.currency_id.symbol) + else: + rec[1] = "%s %s" % (company.currency_id.symbol, sym_id) + rec = tuple(rec) + payments.append(rec) + return { + 'payment_details': payments, + 'salesperson': total_sales, + 'selling_product': sessions_list, + } + + @api.model + def get_refund_details(self): + default_date = datetime.today().date() + pos_order = self.env['pos.order'].search([]) + total = 0 + today_refund_total = 0 + total_order_count = 0 + total_refund_count = 0 + today_sale = 0 + a = 0 + for rec in pos_order: + if rec.amount_total < 0.0 and rec.date_order.date() == default_date: + today_refund_total = today_refund_total + 1 + total_sales = rec.amount_total + total = total + total_sales + total_order_count = total_order_count + 1 + if rec.date_order.date() == default_date: + today_sale = today_sale + 1 + if rec.amount_total < 0.0: + total_refund_count = total_refund_count + 1 + magnitude = 0 + while abs(total) >= 1000: + magnitude += 1 + total /= 1000.0 + # add more suffixes if you need them + val = '%.2f%s' % (total, ['', 'K', 'M', 'G', 'T', 'P'][magnitude]) + pos_session = self.env['pos.session'].search([]) + total_session = 0 + for record in pos_session: + total_session = total_session + 1 + return { + 'total_sale': val, + 'total_order_count': total_order_count, + 'total_refund_count': total_refund_count, + 'total_session': total_session, + 'today_refund_total': today_refund_total, + 'today_sale': today_sale, + } + + @api.model + def get_the_top_customer(self, ): + company_id = self.env.company.id + query = '''select res_partner.name as customer,pos_order.partner_id,sum(pos_order.amount_paid) as amount_total from pos_order + inner join res_partner on res_partner.id = pos_order.partner_id where pos_order.company_id = ''' + str( + company_id) + ''' GROUP BY pos_order.partner_id, + res_partner.name ORDER BY amount_total DESC LIMIT 10;''' + self._cr.execute(query) + docs = self._cr.dictfetchall() + print(docs) + + order = [] + for record in docs: + order.append(record.get('amount_total')) + day = [] + for record in docs: + day.append(record.get('customer')) + final = [order, day] + return final + + @api.model + def get_the_top_products(self): + company_id = self.env.company.id + + query = '''select DISTINCT(product_template.name) as product_name,sum(qty) as total_quantity from + pos_order_line inner join product_product on product_product.id=pos_order_line.product_id inner join + product_template on product_product.product_tmpl_id = product_template.id where pos_order_line.company_id = ''' + str( + company_id) + ''' group by product_template.id ORDER + BY total_quantity DESC Limit 10 ''' + + self._cr.execute(query) + top_product = self._cr.dictfetchall() + + total_quantity = [] + for record in top_product: + # if record.get('total_quantity') != 0: + # print(total_quantity.append(record.get('total_quantity'))) + total_quantity.append(record.get('total_quantity')) + product_name = [] + for record in top_product: + product_name.append(record.get('product_name')) + final = [total_quantity, product_name] + return final + + @api.model + def get_the_top_categories(self): + company_id = self.env.company.id + query = '''select DISTINCT(product_category.complete_name) as product_category,sum(qty) as total_quantity + from pos_order_line inner join product_product on product_product.id=pos_order_line.product_id inner join + product_template on product_product.product_tmpl_id = product_template.id inner join product_category on + product_category.id =product_template.categ_id where pos_order_line.company_id = ''' + str( + company_id) + ''' group by product_category ORDER BY total_quantity DESC ''' + self._cr.execute(query) + top_product = self._cr.dictfetchall() + total_quantity = [] + for record in top_product: + total_quantity.append(record.get('total_quantity')) + product_categ = [] + for record in top_product: + product_categ.append(record.get('product_category')) + final = [total_quantity, product_categ] + return final diff --git a/dashboard_pos/static/description/banner.png b/dashboard_pos/static/description/banner.png new file mode 100644 index 000000000..40c1cde8a Binary files /dev/null and b/dashboard_pos/static/description/banner.png differ diff --git a/dashboard_pos/static/description/icon.png b/dashboard_pos/static/description/icon.png new file mode 100644 index 000000000..9815fbb22 Binary files /dev/null and b/dashboard_pos/static/description/icon.png differ diff --git a/dashboard_pos/static/description/images/booking_order.png b/dashboard_pos/static/description/images/booking_order.png new file mode 100644 index 000000000..4d3da60bb Binary files /dev/null and b/dashboard_pos/static/description/images/booking_order.png differ diff --git a/dashboard_pos/static/description/images/chart_view.png b/dashboard_pos/static/description/images/chart_view.png new file mode 100644 index 000000000..5a6807eac Binary files /dev/null and b/dashboard_pos/static/description/images/chart_view.png differ diff --git a/dashboard_pos/static/description/images/checked.png b/dashboard_pos/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/dashboard_pos/static/description/images/checked.png differ diff --git a/dashboard_pos/static/description/images/cybrosys.png b/dashboard_pos/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/dashboard_pos/static/description/images/cybrosys.png differ diff --git a/dashboard_pos/static/description/images/dashboard.png b/dashboard_pos/static/description/images/dashboard.png new file mode 100644 index 000000000..a3250c6e0 Binary files /dev/null and b/dashboard_pos/static/description/images/dashboard.png differ diff --git a/dashboard_pos/static/description/images/mrp_orders.png b/dashboard_pos/static/description/images/mrp_orders.png new file mode 100644 index 000000000..228cecc14 Binary files /dev/null and b/dashboard_pos/static/description/images/mrp_orders.png differ diff --git a/dashboard_pos/static/description/images/order_line_image.png b/dashboard_pos/static/description/images/order_line_image.png new file mode 100644 index 000000000..3ba237b48 Binary files /dev/null and b/dashboard_pos/static/description/images/order_line_image.png differ diff --git a/dashboard_pos/static/description/images/pos_coupons.png b/dashboard_pos/static/description/images/pos_coupons.png new file mode 100644 index 000000000..cf274c0bb Binary files /dev/null and b/dashboard_pos/static/description/images/pos_coupons.png differ diff --git a/dashboard_pos/static/description/images/pos_dashboard.gif b/dashboard_pos/static/description/images/pos_dashboard.gif new file mode 100644 index 000000000..69eb3918c Binary files /dev/null and b/dashboard_pos/static/description/images/pos_dashboard.gif differ diff --git a/dashboard_pos/static/description/images/pos_return.png b/dashboard_pos/static/description/images/pos_return.png new file mode 100644 index 000000000..026b47e1e Binary files /dev/null and b/dashboard_pos/static/description/images/pos_return.png differ diff --git a/dashboard_pos/static/description/images/product_creation.png b/dashboard_pos/static/description/images/product_creation.png new file mode 100644 index 000000000..9f62d36ce Binary files /dev/null and b/dashboard_pos/static/description/images/product_creation.png differ diff --git a/dashboard_pos/static/description/images/tile_view.png b/dashboard_pos/static/description/images/tile_view.png new file mode 100644 index 000000000..919a5b8c8 Binary files /dev/null and b/dashboard_pos/static/description/images/tile_view.png differ diff --git a/dashboard_pos/static/description/images/tree_view.png b/dashboard_pos/static/description/images/tree_view.png new file mode 100644 index 000000000..ebfaddf92 Binary files /dev/null and b/dashboard_pos/static/description/images/tree_view.png differ diff --git a/dashboard_pos/static/description/index.html b/dashboard_pos/static/description/index.html new file mode 100644 index 000000000..4c3589baa --- /dev/null +++ b/dashboard_pos/static/description/index.html @@ -0,0 +1,545 @@ +
+ cybrosys-logo
+
+
+
+

POS Dashboard

+

+ Detailed Dashboard View for POS +

+
+

Key Highlights

+
    +
  • + check + Total Pos Orders +
  • +
  • + checkSession + Details +
  • +
  • + checkCustomer + List +
  • +
  • + checkSale + Report +
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This module helps you to see the Overview of POS, here You can see the total orders, + sessions, top customers, top products etc +

+
+
+ +

POS Dashboard

+
+
    +
  • + checkTotal Pos Orders +
  • +
  • + checkSession Details +
  • +
  • + checkRefund Details +
  • +
  • + checkSale Details +
  • +
  • + checkSale Report Charts +
  • +
  • + checkTop Products +
  • + +
+
+ +
+
+

Screenshots

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

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+
+ Odoo Industry
+
+
+

+ + Trading

+

+ Easily procure and sell your products.

+
+
+
+
+
+ Odoo Industry +
+
+
+

+ + Manufacturing

+

+ Plan, track and schedule your operations.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Restaurant

+

+ Run your bar or restaurant methodical.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + POS

+

+ Easy configuring and convivial selling.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + E-commerce & Website

+

+ Mobile friendly, awe-inspiring product pages.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Hotel Management

+

+ An all-inclusive hotel management application.

+
+
+
+
+
+ + Odoo Industry
+
+
+

+ + Education

+

+ A Collaborative platform for educational management.

+
+
+
+
+
+ Odoo Industry
+
+
+

+ + Service Management

+

+ Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please + let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/dashboard_pos/static/src/css/pos_dashboard.css b/dashboard_pos/static/src/css/pos_dashboard.css new file mode 100644 index 000000000..ec1b234cc --- /dev/null +++ b/dashboard_pos/static/src/css/pos_dashboard.css @@ -0,0 +1,1009 @@ +.oh_dashboards{ + padding-top :15px; + background-color: #f8faff !important; +} + +.oh-card h4 { + font-size: 1.1rem; +} +.breadcrumbs { + margin-top: 0; +} + +.buttons button { + margin: 2px 0; } + +/* Button Reset */ +.btn, .button { + display: inline-block; + font-weight: 400; + text-align: center; + white-space: nowrap; + vertical-align: middle; + transition: all .15s ease-in-out; + border-radius: 0; + cursor: pointer; } + + +/* Widget One +---------------------------*/ +.stat-content { + display: inline-block; + width: 66%; +} +.stat-icon{ + display: inline-block; +} + +.stat-widget-one .stat-icon { + vertical-align: top; + margin: auto; + width: 100%; + color: #01c490; +} + +.stat-widget-one .stat-icon i { + font-size: 30px; + font-weight: 900; + display: inline-block; + color: #01c490;} + +.stat-widget-one .stat-text { + font-size: 14px; + color: #868e96; + font-weight: bold; +} + +.stat-widget-one .stat-digit { + font-size: 24px; + color: #02448b; } + +.stat-count { + font-size: 20px; + text-align: center; + color: #00438b;} + +.stat-title { + font-size: 17px; + text-align: center; + color: #00438b; } + +.mb-0{ + font-size: 20px; + position: relative; + text-align: center; +} +.mb-0 .dash-title { + font-size: 20px; + text-align: center; + color: rgba(255, 255, 255, 0.81); +} +.hr_birthday { + font-size: 28px; + text-align: center; + padding: 20px 0; + color: #00438b; + font-weight: 600; +} +body .text-color { + color: #00438b; +} +.slice { + stroke: #fff; + stroke-width: 0px; +} + +/* Leave graph */ + +path { stroke: #fff; } +path:hover { opacity:0.9; } +rect:hover { fill:#934da5; } +.axis { font: 10px sans-serif; } +.legend tr{ border-bottom:1px solid grey; } +.legend tr:first-child{ border-top:1px solid grey; } + +.axis path, +.axis line { + fill: none; + stroke: #000; + shape-rendering: crispEdges; +} + +.x.axis path { display: none; } +.legend{ + border-collapse: collapse; + border-spacing: 0px; + display: inline-block; +} +.legend td, .legend .legend_col{ + padding:4px 5px; + vertical-align:bottom; +} +.legendFreq, .legendPerc{ + align:right; + width:50px; +} + +/* Leave broadfactor graph */ + +.broad_factor_graph .axis path, +.broad_factor_graph .axis line { + fill: none; + stroke: black; + shape-rendering: crispEdges; +} +.broad_factor_graph .axis text { + font-family: sans-serif; + font-size: 11px; +} + +.broad_factor_graph rect { + -moz-transition: all 0.3s; + -webkit-transition: all 0.3s; + -o-transition: all 0.3s; + transition: all 0.3s; +} +.broad_factor_graph rect:hover{ + fill: #ff618a; +} + +#broad_factor_pdf { + background-color: #ffffff; + border: 0; + color : #000000; + float: right; +} +#broad_factor_pdf i { + color: red; +} + +.leave_broad_factor{ + overflow-x: auto !important; + overflow-y: hidden !important; + height: auto; +} + +/*=====================New Dashboard===========================*/ + +.oh_dashboards { + background-color: #f8faff !important; + padding: 0px !important; + +} +.container-fluid.o_pos_dashboard { + padding: 0px !important; +} +.employee-prof { + + padding: 0px; + height: 100%; + background-color: #3e6282; + /*background-image: linear-gradient(180deg, #3e6282, #41666f);*/ + position: fixed; + z-index: 999; +} +.employee-prof .oh-card:hover { + + transform:none !important; + box-shadow: none !important; + +} + +/*.dummy{ + height:130vh; +}*/ +.oh-card { + + padding-top: 0px; + padding: 0px; + margin-bottom: 1.5rem; + border-radius: 0px; + box-shadow: none; + background: none; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + +} +.oh-card:hover { + + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; + +} +.employee-prof .employee-icon { + + float: left; + padding-right: 0px; + width: 100%; + height: 185px; + overflow: hidden; + background: #fff; + +} +.employee-prof .employee-icon img{ + width: 100%; + background: #fff; +} + +.employee-prof .employee-name h2 { + + text-align: center; + font-weight: 300; + text-transform: uppercase; + font-size: 17px; + margin-top: 12px; + margin-bottom: 2px; + color: #fff; + +} +.media-body.employee-name { + + background: #466b8d; + float: left; + margin: 0; + width: 100% + +} +.employee-prof .employee-name p { + + margin: 0 0 9px; + text-align: center; + font-size: 12px; + color: #f3f3f3; + +} +.employee-prof p { + margin: 0 0 9px; + color: #fff; +} +.employee-gender { + width: 40%; + margin-left: 10%; + padding: 8% 10% 4%; + text-align: center; + border-right: 1px solid #4d769b; + margin-top: 14%; + float: left; + border-bottom: 1px solid #4d769b; +} +.employee-gender p { + margin: 0px 0 4px !important; + color: #fff; +} +.employee-age { + width: 40%; + margin-right: 10%; + padding: 4% 10% 7%; + text-align: center; + margin-top: 18%; + float: left; + border-bottom: 1px solid #4d769b; +} +.employee-age p { + margin: 0 0 1px; + color: #fff; +} +.employee-experience { + + width: 100%; + text-align: center; + padding-top: 8%; + float: left; + padding-bottom: 3%; + +} +.employee-country { + width: 40%; + margin-left: 10%; + padding: 9% 0% 4%; + text-align: center; + border-right: 1px solid #4d769b; + margin-top: 2%; + float: left; + border-top: 1px solid #4d769b; + +} +.employee-country p { + margin: 0px 0 1px !important; + color: #fff; +} +.employee-mobile { + width: 40%; + margin-right: 10%; + padding: 9% 0% 7%; + text-align: center; + margin-top: 2%; + float: left; + border-top: 1px solid #4d769b; +} +.employee-mobile p { + margin: 0 0 1px; + color: #fff; +} +.oh-payslip { + + margin-top: 4.5%; + +} +.oh-payslip .stat-icon { + + width: 30%; + height: 85px; + text-align: center; + background: #ff8762; + color: #fff; + width: 32%; + padding-top: 2%; + font-size: xxx-large; + +} +.oh-payslip .oh-card { + + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + +} +.stat-widget-one .stat-text { + + font-size: 14px; + color: #ff8762; + margin-top: 2.3rem; + margin-left: 1rem; + +} +.stat-widget-one .stat-digit { + font-size: 26px; + color:#993232; + margin-left: 1rem; + margin-top: -1px; + font-family: initial +} + +.stat-widget-one .stat-icon i { + + font-size: 25px; + font-weight: 900; + display: inline-block; + color: #fff; + +} +.stat-widget-one { + + background-color: white; + text-align: left; + +} +.stat-widget-one { + width: 100%; +} +.oh-payslip .stat-icon { + + width: 30%; + height: 85px; + text-align: center; + padding-top: 2%; + +} +.oh-timesheets .stat-icon{ + background: #5ebade !important; +} +.oh-contracts .stat-icon{ + background: #b298e1 !important; +} +.oh-broad-factor .stat-icon{ + background: #70cac1 !important; +} +.oh-timesheets .stat-widget-one .stat-text { + color: #5ebade; +} +.oh-contracts .stat-widget-one .stat-text { + color: #b298e1; +} +.oh-broad-factor .stat-widget-one .stat-text { + color: #70cac1; +} +.leave-manager { + + background-color: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding: 0px; + margin: 15px; + +} +.hr_leave_request_approve { + padding: 0; + padding-bottom: 0em; + padding-top: 0em; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; +} +.leaves_request_month { + padding: 0; + padding-top: 0px; + padding-bottom: 0px; + padding-bottom: 0em; + padding-top: 0em; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + border-bottom: 1px solid #f1f1f133; +} +.leaves_request_today{ + padding: 0; + padding-bottom: 0em; + padding-top: 0em; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + +} +.hr_leave_request_approve:hover, .leaves_request_month:hover, .leaves_request_today:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} +.hr_leave_request_approve p { + font-size: 14px; + color: #ff8762; + margin-left: 1rem; + margin-bottom: 0px; + text-align: left; + width: 64%; + font-weight: bold; + float: left; +} +.leaves_request_today p { + font-size: 14px; + color: #5ebade; + margin-left: 1rem; + margin-bottom: 0px; + text-align: left; + width:64%; + float:left; + font-weight: bold; +} +.leaves_request_month p{ + font-size: 14px; + color: #b298e1; + margin-left: 1rem; + margin-bottom:0px; + text-align: left; + width:64%; + float:left; + font-weight: bold; +} +h4 .stat-count { + font-size: 17px; + text-align: center; + color: #000 !important; + margin-top: 0px; + width: 100%; + float: left; + margin: 0; +} +.leave-manager h4 { + float: left; + width: 23%; + +} +.hr_leave_request_approve h4 { + + padding: 5.2rem 0; + margin: 0; + background: #ff8762; + color: #fff; + +} +.leaves_request_today h4 { + + padding: 2.2rem 0; + margin: 0 !important; + background: #5ebade; + color: #fff; + +} +.leaves_request_month h4 { + + padding: 2.1rem 0; + margin: 0 !important; + background: #b298e1; + color: #fff; + +} +.leaves_request_today h4 .stat-count ,.leaves_request_month h4 .stat-count , .hr_leave_request_approve h4 .stat-count +{ + color:#fff !important; +} +.graph_view .legend { + margin-bottom: 27px; + display: inline-block; + border-collapse: collapse; + border-spacing: 0px; + margin-left: 29px; +} +.hr-chart-1{ + margin: 15px 0px; + background: #fff; + padding: 0px !important; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); +} +.hr-chart-1:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} +.stat-head { + text-align: left !important; + font-weight: 300; + font-size: 15px; + margin-bottom: 25px; + margin-left: 24px; + width: 100%; +} +.emp_graph { + padding-left: 90px; + height: auto; + padding-bottom: 65px; + text-align: center !important; +} +.hr_leave_allocations_approve p { + font-size: 14px; + color: #ff8762; + margin-left: 1rem; + margin-bottom: 0px; + text-align: left; + width: 70%; + float: left; + font-weight: bold; +} +.hr_leave_allocations_approve h4 { + + padding: 2.5rem 0; + margin: 0; + background: #ff8762; + color: #fff; + width: 26%; + float: left; +} +.hr_leave_allocations_approve .stat-count { + + font-size: 17px; + text-align: center; + color: #fff !important; + margin-top: 0px; + width: 100%; + float: left; + margin: 0; + +} +.hr_leave_allocations_approve { + + padding: 0; + padding-top: 0px; + padding-bottom: 0px; + padding-bottom: 0em; + padding-top: 0em; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + background: #fff; + height: 80px; + +} +.hr_leave_allocations_approve:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} +.leave-manager { + + background-color: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding: 0px; + margin: 15px; + margin-right: 15px; + margin-right: 0px; + width: 95% !important; + padding: 0; + +} +.hr_job_application_approve { + padding: 0; + padding-top: 0px; + padding-bottom: 0px; + padding-top: 0px; + padding-bottom: 0px; + padding-top: 0px; + padding-bottom: 0px; + padding-bottom: 0em; + padding-top: 0em; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + background: #fff; + margin-top: 15px; + height: 80px; + +} +.hr_job_application_approve p { + font-size: 14px; + color: #70cac1; + margin-left: 1rem; + margin-bottom: 0px; + text-align: left; + width: 70%; + float: left; + font-weight: bold; +} +.hr_job_application_approve h4 { + + padding: 2.5rem 0; + margin: 0; + background: #70cac1; + color: #fff; + width: 26%; + float: left; + +} +.hr_job_application_approve .stat-count { + + font-size: 17px !important; + color: #fff !important; + margin-top: 0px !important; + width: 100%; + float: left; + margin: 0; + margin: 0px !important; + text-align: center !important; + width: 100% !important; + +} +.hr_job_application_approve:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} +.hr_attendance_login .oh-card { + margin: 0; + margin-bottom: 0px; + margin-bottom: 0px; + background: #134c8a; + padding-bottom: 7px; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); +} +.hr_attendance_login .stat-widget-one { + background: none; +} +.hr_attendance_login .stat-widget-one .stat-icon { + text-align: center; + padding-top: 9px; +} +.hr_attendance_login .stat-content { + width: 100%; + color: #fff !important; +} +.hr_attendance_login .stat-widget-one .stat-text { + margin: 0; + text-align: center; + width: 100% !important; + padding: 0; + color: #fff; +} +.hr_attendance_login .stat-widget-one .stat-icon .fa { + font-size: 50px; +} +.hr_attendance_login .stat-widget-one .stat-icon .fa { + font-size: 50px; + margin: 0px; + box-shadow: none; +} +.hr_attendance_login { + margin-top: 1.5%; +} +.monthly_leave_graph_view .oh-card { + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding: 15px; +} +.broad_factor_graph .oh-card { + padding: 15px !important; + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding: 15px; +} +.leave_broad_factor { + overflow-x: auto !important; + overflow-y: hidden !important; + height: 336px; + padding: 0px; + padding-left: 0px; +} +#broad_factor_pdf { + + background-color: #ffffff; + float: right; + border-radius: 30px; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + border: 1px solid #4ec3b7; + color: #757575; + padding-top: 9px; + color: #4ec3b7; + +} +#broad_factor_pdf:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} +.hr_birthday { + font-size: 17px; + text-align: center; + padding: 20px 0; + color: #00438b; + font-weight: 300; +} +.hr_notification img { + width: 40px; + height: 40px; + border-radius: 100%; +} +.hr_notification { + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + height: 316px; + overflow-y: auto; + margin-bottom: 15px; +} +.hr_notification .media { + border-bottom: 1px solid #e6e6e6; + padding-bottom: 6px; + margin-bottom: 10px; +} +.hr_notification .text-color.display-6 { + margin: 0px 0 3px; + color: #2d2d2d; +} +.hr_notification p { + margin: 0 0 1px; + color: #666; + font-size: 10px; +} +.hr_notification_head { + font-size: 17px; + text-align: center; + padding: 12px 0; + color: #fff; + font-weight: 300; + background: #de6a5e; + margin-bottom: 9px; +} +.monthly_leave_trend .oh-card{ + background: #fff; + transition: none !important; + will-change: none !important; + box-shadow: none !important; + margin-bottom: 5px; +} + +.monthly_leave_trend path { + stroke: #70cac1; + stroke-width: 2; + fill: none; +} + +.monthly_leave_trend .axis path, +.monthly_leave_trend .axis line { + fill: none; + stroke: grey; + stroke-width: 1; + shape-rendering: crispEdges; +} +.monthly_leave_trend circle{ + fill: #ffffff; + stroke: #44b7ac; + stroke-width: 1.5; +} +.hr-chart-1 { + margin: 15px 0px; + background: #fff; + padding: 0px !important; + padding-top: 0px; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding-top: 3px !important; +} +.monthly_leave_trend { + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); +} +.monthly_leave_trend:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} + + +/*----------------------*/ +.monthly_join_resign_trend{ + padding-right: 0px !important; +} + +.monthly_join_resign_trend .oh-card { + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding: 15px; +} + +.monthly_join_resign_trend .axis path, +.monthly_join_resign_trend .axis line { + fill: none; + shape-rendering: crispEdges; + } + +.monthly_join_resign_trend .line { + fill: none; + stroke-width: 3px; + + } + +.monthly_join_resign_trend .area { + fill: steelblue; + opacity: 0.5; + } + +.monthly_join_resign_trend .dot { + fill: steelblue; + stroke: steelblue; + stroke-width: 1.5px; + } + +/*----------------------------------------*/ + + +.monthly_attrition_rate path { + stroke: #70cac1; + stroke-width: 2; + fill: none; +} + +.monthly_attrition_rate .axis path, +.monthly_attrition_rate .axis line { + fill: none; + stroke: grey; + stroke-width: 1; + shape-rendering: crispEdges; +} +.monthly_attrition_rate circle{ + fill: #ffffff; + stroke: #44b7ac; + stroke-width: 1.5; +} + +.monthly_attrition_rate .oh-card { + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06); + padding: 15px; +} + +.monthly_attrition_rate .oh-card:hover{ + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} + + +.row.main-section { + margin-right: 0px; !important; +} +/* width */ +.hr_notification::-webkit-scrollbar { + width: 4px; +} + +/* Track */ +.hr_notification::-webkit-scrollbar-track { + background: #f1f1f1; +} + +/* Handle */ +.hr_notification::-webkit-scrollbar-thumb { + background: #5ebade; +} + +/* Handle on hover */ +.hr_notification::-webkit-scrollbar-thumb:hover { + background: #598da1; +} + +.oh-card-body { + display: flex; + justify-content: space-between; + align-items: center; +} + +.oh-ribbon { + position: absolute; + left: -5px; top: -5px; + z-index: 1; + overflow: hidden; + width: 150px; height: 150px; + text-align: right; +} +.oh-ribbon span { + font-size: 10px; + font-weight: bold; + color: #FFF; + text-transform: uppercase; + text-align: center; + line-height: 20px; + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); + width: 200px; + display: block; + background: #79A70A; + background: linear-gradient(#2989d8 0%, #1e5799 100%); + box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1); + position: absolute; + top: 56px; + left: -35px; +} +.oh-ribbon span::before { + content: ""; + position: absolute; left: 0px; top: 100%; + z-index: -1; + border-left: 3px solid #1e5799; + border-right: 3px solid transparent; + border-bottom: 3px solid transparent; + border-top: 3px solid #1e5799; +} +.oh-ribbon span::after { + content: ""; + position: absolute; right: 0px; top: 100%; + z-index: -1; + border-left: 3px solid transparent; + border-right: 3px solid #1e5799; + border-bottom: 3px solid transparent; + border-top: 3px solid #1e5799; +} + +.o_action_manager{ + overflow-y: scroll !important; + max-width:100%; + } + + .hr_notification { + + margin-top: 20px; +} + +.stat_count{ + margin-top: -111px; + margin-left: 35px; + font-size: 48px; +} + + +.stat-head { + text-align: left !important; + font-weight: 300; + font-size: 18px; + margin-bottom: 25px; + margin-left: 24px; + width: 100%; + margin-top: 57px; +} \ No newline at end of file diff --git a/dashboard_pos/static/src/js/pos_dashboard.js b/dashboard_pos/static/src/js/pos_dashboard.js new file mode 100644 index 000000000..9adcd0632 --- /dev/null +++ b/dashboard_pos/static/src/js/pos_dashboard.js @@ -0,0 +1,544 @@ +odoo.define('dashboard_pos.Dashboard', function (require) { +"use strict"; + +var AbstractAction = require('web.AbstractAction'); +var ajax = require('web.ajax'); +var core = require('web.core'); +var rpc = require('web.rpc'); +var session = require('web.session'); +var web_client = require('web.web_client'); +var _t = core._t; +var QWeb = core.qweb; + +var PosDashboard = AbstractAction.extend({ + template: 'PosDashboard', + events: { + 'click .pos_order_today':'pos_order_today', + 'click .pos_order':'pos_order', + 'click .pos_total_sales':'pos_order', + 'click .pos_session':'pos_session', + 'click .pos_refund_orders':'pos_refund_orders', + 'click .pos_refund_today_orders':'pos_refund_today_orders', + 'change #pos_sales': 'onclick_pos_sales', + }, + + init: function(parent, context) { + this._super(parent, context); + this.dashboards_templates = ['PosOrders','PosChart','PosCustomer']; + this.payment_details = []; + this.top_salesperson = []; + this.selling_product = []; + this.total_sale = []; + this.total_order_count = []; + this.total_refund_count = []; + this.total_session = []; + this.today_refund_total = []; + this.today_sale = []; + }, + + willStart: function() { + var self = this; + return $.when(ajax.loadLibs(this), this._super()).then(function() { + return self.fetch_data(); + }); + }, + + start: function() { + var self = this; + this.set("title", 'Dashboard'); + return this._super().then(function() { + self.render_dashboards(); + self.render_graphs(); + self.$el.parent().addClass('oe_background_grey'); + }); + }, + + fetch_data: function() { + var self = this; + var def1 = this._rpc({ + model: 'pos.order', + method: 'get_refund_details' + }).then(function(result) { + self.total_sale = result['total_sale'], + self.total_order_count = result['total_order_count'] + self.total_refund_count = result['total_refund_count'] + self.total_session = result['total_session'] + self.today_refund_total = result['today_refund_total'] + self.today_sale = result['today_sale'] + }); + var def2 = self._rpc({ + model: "pos.order", + method: "get_details", + }) + .then(function (res) { + self.payment_details = res['payment_details']; + self.top_salesperson = res['salesperson']; + self.selling_product = res['selling_product']; + }); + return $.when(def1,def2); + }, + + render_dashboards: function() { + var self = this; + _.each(this.dashboards_templates, function(template) { + self.$('.o_pos_dashboard').append(QWeb.render(template, {widget: self})); + }); + }, + render_graphs: function(){ + var self = this; + self.render_top_customer_graph(); + self.render_top_product_graph(); + self.render_product_category_graph(); + }, +// get_emp_image_url: function(employee){ +// return window.location.origin + '/web/image?model=pos.order&field=image&id='+employee; +// }, + + + + + pos_order_today: function(e){ + var self = this; + var date = new Date(); + var yesterday = new Date(date.getTime()); + yesterday.setDate(date.getDate() - 1); + console.log(yesterday) + e.stopPropagation(); + e.preventDefault(); + + session.user_has_group('hr.group_hr_user').then(function(has_group){ + if(has_group){ + var options = { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }; + self.do_action({ + name: _t("Today Order"), + type: 'ir.actions.act_window', + res_model: 'pos.order', + view_mode: 'tree,form,calendar', + view_type: 'form', + views: [[false, 'list'],[false, 'form']], + domain: [['date_order','<=', date],['date_order', '>=', yesterday]], + target: 'current' + }, options) + } + }); + + }, + + + pos_refund_orders: function(e){ + var self = this; + var date = new Date(); +// alert(date,"date") + var yesterday = new Date(date.getTime()); + yesterday.setDate(date.getDate() - 1); + console.log(yesterday) + e.stopPropagation(); + e.preventDefault(); + + session.user_has_group('hr.group_hr_user').then(function(has_group){ + if(has_group){ + var options = { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }; + self.do_action({ + name: _t("Refund Orders"), + type: 'ir.actions.act_window', + res_model: 'pos.order', + view_mode: 'tree,form,calendar', + view_type: 'form', + views: [[false, 'list'],[false, 'form']], + domain: [['amount_total', '<', 0.0]], + +// domain: [['date_order', '=', date]], + target: 'current' + }, options) + } + }); + + }, + pos_refund_today_orders: function(e){ + var self = this; + var date = new Date(); +// alert(date,"date") + var yesterday = new Date(date.getTime()); + yesterday.setDate(date.getDate() - 1); + console.log(yesterday) + e.stopPropagation(); + e.preventDefault(); + + session.user_has_group('hr.group_hr_user').then(function(has_group){ + if(has_group){ + var options = { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }; + self.do_action({ + name: _t("Refund Orders"), + type: 'ir.actions.act_window', + res_model: 'pos.order', + view_mode: 'tree,form,calendar', + view_type: 'form', + views: [[false, 'list'],[false, 'form']], + domain: [['amount_total', '<', 0.0],['date_order','<=', date],['date_order', '>=', yesterday]], +// domain: [['date_order', '=', date]], + target: 'current' + }, options) + } + }); + + }, + + pos_order: function(e){ + var self = this; + var date = new Date(); + var yesterday = new Date(date.getTime()); + yesterday.setDate(date.getDate() - 1); + console.log(yesterday) + e.stopPropagation(); + e.preventDefault(); + session.user_has_group('hr.group_hr_user').then(function(has_group){ + if(has_group){ + var options = { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }; + self.do_action({ + name: _t("Total Order"), + type: 'ir.actions.act_window', + res_model: 'pos.order', + view_mode: 'tree,form,calendar', + view_type: 'form', + views: [[false, 'list'],[false, 'form']], +// domain: [['amount_total', '<', 0.0]], + target: 'current' + }, options) + } + }); + + }, + pos_session: function(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + session.user_has_group('hr.group_hr_user').then(function(has_group){ + if(has_group){ + var options = { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }; + self.do_action({ + name: _t("sessions"), + type: 'ir.actions.act_window', + res_model: 'pos.session', + view_mode: 'tree,form,calendar', + view_type: 'form', + views: [[false, 'list'],[false, 'form']], +// domain: [['state','=', In Progress]], + target: 'current' + }, options) + } + }); + + }, + + onclick_pos_sales:function(events){ + var option = $(events.target).val(); + console.log('came monthly') + var self = this + var ctx = self.$("#canvas_1"); + rpc.query({ + model: "pos.order", + method: "get_department", + args: [option], + }).then(function (arrays) { + console.log(arrays) + var data = { + labels: arrays[1], + datasets: [ + { + label: arrays[2], + data: arrays[0], + backgroundColor: [ + "rgba(255, 99, 132,1)", + "rgba(54, 162, 235,1)", + "rgba(75, 192, 192,1)", + "rgba(153, 102, 255,1)", + "rgba(10,20,30,1)" + ], + borderColor: [ + "rgba(255, 99, 132, 0.2)", + "rgba(54, 162, 235, 0.2)", + "rgba(75, 192, 192, 0.2)", + "rgba(153, 102, 255, 0.2)", + "rgba(10,20,30,0.3)" + ], + borderWidth: 1 + }, + + ] + }; + + //options + var options = { + responsive: true, + title: { + display: true, + position: "top", + text: "SALE DETAILS", + fontSize: 18, + fontColor: "#111" + }, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + ticks: { + min: 0 + } + }] + } + }; + + //create Chart class object + if (window.myCharts != undefined) + window.myCharts.destroy(); + window.myCharts = new Chart(ctx, { +// var chart = new Chart(ctx, { + type: "bar", + data: data, + options: options + }); + + }); + }, + + + render_top_customer_graph:function(){ + var self = this + var ctx = self.$(".top_customer"); + rpc.query({ + model: "pos.order", + method: "get_the_top_customer", + }).then(function (arrays) { + + + var data = { + labels: arrays[1], + datasets: [ + { + label: "", + data: arrays[0], + backgroundColor: [ + "rgb(148, 22, 227)", + "rgba(54, 162, 235)", + "rgba(75, 192, 192)", + "rgba(153, 102, 255)", + "rgba(10,20,30)" + ], + borderColor: [ + "rgba(255, 99, 132,)", + "rgba(54, 162, 235,)", + "rgba(75, 192, 192,)", + "rgba(153, 102, 255,)", + "rgba(10,20,30,)" + ], + borderWidth: 1 + }, + + ] + }; + + //options + var options = { + responsive: true, + title: { + display: true, + position: "top", + text: " Top Customer", + fontSize: 18, + fontColor: "#111" + }, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + ticks: { + min: 0 + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "pie", + data: data, + options: options + }); + + }); + }, + + render_top_product_graph:function(){ + var self = this + var ctx = self.$(".top_selling_product"); + rpc.query({ + model: "pos.order", + method: "get_the_top_products", + }).then(function (arrays) { + + + var data = { + labels: arrays[1], + datasets: [ + { + label: "Quantity", + data: arrays[0], + backgroundColor: [ + "rgba(255, 99, 132,1)", + "rgba(54, 162, 235,1)", + "rgba(75, 192, 192,1)", + "rgba(153, 102, 255,1)", + "rgba(10,20,30,1)" + ], + borderColor: [ + "rgba(255, 99, 132, 0.2)", + "rgba(54, 162, 235, 0.2)", + "rgba(75, 192, 192, 0.2)", + "rgba(153, 102, 255, 0.2)", + "rgba(10,20,30,0.3)" + ], + borderWidth: 1 + }, + + ] + }; + + //options + var options = { + responsive: true, + title: { + display: true, + position: "top", + text: " Top products", + fontSize: 18, + fontColor: "#111" + }, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + ticks: { + min: 0 + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "horizontalBar", + data: data, + options: options + }); + + }); + }, + + render_product_category_graph:function(){ + var self = this + var ctx = self.$(".top_product_categories"); + rpc.query({ + model: "pos.order", + method: "get_the_top_categories", + }).then(function (arrays) { + + + var data = { + labels: arrays[1], + datasets: [ + { + label: "Quantity", + data: arrays[0], + backgroundColor: [ + "rgba(255, 99, 132,1)", + "rgba(54, 162, 235,1)", + "rgba(75, 192, 192,1)", + "rgba(153, 102, 255,1)", + "rgba(10,20,30,1)" + ], + borderColor: [ + "rgba(255, 99, 132, 0.2)", + "rgba(54, 162, 235, 0.2)", + "rgba(75, 192, 192, 0.2)", + "rgba(153, 102, 255, 0.2)", + "rgba(10,20,30,0.3)" + ], + borderWidth: 1 + }, + + + ] + }; + + //options + var options = { + responsive: true, + title: { + display: true, + position: "top", + text: " Top product categories", + fontSize: 18, + fontColor: "#111" + }, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + ticks: { + min: 0 + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "horizontalBar", + data: data, + options: options + }); + + }); + }, +}); + + +core.action_registry.add('pos_dashboard', PosDashboard); + +return PosDashboard; + +}); diff --git a/dashboard_pos/static/src/xml/pos_dashboard.xml b/dashboard_pos/static/src/xml/pos_dashboard.xml new file mode 100644 index 000000000..aa3b230fa --- /dev/null +++ b/dashboard_pos/static/src/xml/pos_dashboard.xml @@ -0,0 +1,305 @@ + + + +
+
+
+
+
+ +
+
+
+
+
+ + +
+
+
Today Orders
+
+
+
+
+
+
+
+
+
+
+ +
+
+
Total Orders
+
+
+
+
+
+
+
+
+
+
+
+ +
+
Total Sales
+
+
+
+
+
+
+
+
+
+
+
+
+
Sessions
+
+
+
+
+
+
+ +
+
+
+
+
+
+
Total Refund Orders
+
+
+
+
+
+
+
+
+
+
+
+
+
Today Refund Order
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +

SALE REPORT

+
+
+
+ +
+
+
+
+
+

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

+

+
+ +
+
+
+
+
+

+

+
+ +
+
+
+
+
+

+

+
+ +
+
+
+
+ +
+ + +
+
+
+
+
+ Sale by Salesperson +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + +
Name   ordersAmount
+

+ +

+
+

+ +

+
+

+ +

+
+
+
+
+
+
+
+
+ Payment Method +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
Payment Method   Amount
+

+ +

+
+

+ +

+
+
+
+
+
+ + +
+
+
+ Session Status +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
Session   Status
+

+ +

+
+

+ +

+
+
+
+
+
+ +
+
+ + +
+
diff --git a/dashboard_pos/views/dashboard_views.xml b/dashboard_pos/views/dashboard_views.xml new file mode 100644 index 000000000..f30a4868b --- /dev/null +++ b/dashboard_pos/views/dashboard_views.xml @@ -0,0 +1,21 @@ + + + + Dashboard + pos_dashboard + + + + + + +