浏览代码

Dashboard de doctores para Dental Mocona

sebastian 5 年之前
当前提交
790a852c58
共有 36 个文件被更改,包括 1035 次插入0 次删除
  1. 2 0
      __init__.py
  2. 二进制
      __init__.pyc
  3. 24 0
      __openerp__.py
  4. 1 0
      controllers/__init__.py
  5. 二进制
      controllers/__init__.pyc
  6. 10 0
      controllers/helpers/__init__.py
  7. 二进制
      controllers/helpers/__init__.pyc
  8. 54 0
      controllers/helpers/account_invoice.py
  9. 二进制
      controllers/helpers/account_invoice.pyc
  10. 68 0
      controllers/helpers/account_invoice_line.py
  11. 二进制
      controllers/helpers/account_invoice_line.pyc
  12. 49 0
      controllers/helpers/company.py
  13. 二进制
      controllers/helpers/company.pyc
  14. 17 0
      controllers/helpers/ir_module_module.py
  15. 二进制
      controllers/helpers/ir_module_module.pyc
  16. 89 0
      controllers/helpers/pos_order.py
  17. 二进制
      controllers/helpers/pos_order.pyc
  18. 21 0
      controllers/helpers/res_partner.py
  19. 二进制
      controllers/helpers/res_partner.pyc
  20. 18 0
      controllers/helpers/res_store.py
  21. 二进制
      controllers/helpers/res_store.pyc
  22. 22 0
      controllers/helpers/res_user.py
  23. 二进制
      controllers/helpers/res_user.pyc
  24. 27 0
      controllers/helpers/widget_list.py
  25. 二进制
      controllers/helpers/widget_list.pyc
  26. 46 0
      controllers/main.py
  27. 二进制
      controllers/main.pyc
  28. 15 0
      data/charts_data.xml
  29. 二进制
      static/description/icon.png
  30. 390 0
      static/src/js/chart.js
  31. 28 0
      static/src/js/dashboard.js
  32. 18 0
      static/src/js/main.js
  33. 5 0
      static/src/js/widget_base.js
  34. 100 0
      static/src/js/widgets/ranking_doctores.js
  35. 17 0
      static/src/xml/widgets/ranking_doctores.xml
  36. 14 0
      template.xml

+ 2 - 0
__init__.py

@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+import controllers

二进制
__init__.pyc


+ 24 - 0
__openerp__.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+{
+    'name': "Widgets para el dashboard de Mocona",
+    'author': "Eiru",
+    'website': "https://www.eiru.com.py",
+    'category': 'Uncategorized',
+    'version': '2.0',
+    'depends': [
+        'base',
+        'account',
+        'sale',
+        'sale_order_lider_mocona',
+        'eiru_reports_dashboard',
+    ],
+    'data': [
+        'data/charts_data.xml',
+        'template.xml',
+    ],
+    'qweb': [
+        'static/src/xml/*.xml',
+        'static/src/xml/widgets/*.xml',
+
+    ]
+}

+ 1 - 0
controllers/__init__.py

@@ -0,0 +1 @@
+import main

二进制
controllers/__init__.pyc


+ 10 - 0
controllers/helpers/__init__.py

@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+
+from company import get_company_info
+from ir_module_module import get_ir_module_widget
+from widget_list import get_widget_list
+from res_user import get_user_info
+from res_partner import get_res_partner
+from res_store import get_res_store_widget
+from account_invoice import get_account_invoice
+from account_invoice_line import get_account_invoice_line_widget

二进制
controllers/helpers/__init__.pyc


+ 54 - 0
controllers/helpers/account_invoice.py

@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_invoice():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as invoice_rate,
+            invoice.number
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        WHERE invoice.state = 'open'
+        AND journal.store_id = ''' + str(user_store) + '''
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'invoice_id': j[0],
+            'currency_id': j[1],
+            'date': j[2],
+            'type': j[3],
+            'origin': j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/account_invoice.pyc


+ 68 - 0
controllers/helpers/account_invoice_line.py

@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_invoice_line_widget():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+        	product.name_template,
+            line.medic_id,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND TO_CHAR(invoice.date_invoice,'YYYY-MM') = TO_CHAR(current_date,'YYYY-MM')
+            AND journal.store_id = ''' + str(user_store) + '''
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+            line.medic_id,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate])))
+
+    return [
+        {
+            'invoice_id': j[0],
+            'invoice_line_id': j[1],
+            'number': j[2],
+            'origin': j[3],
+            'date': j[4],
+            'type': j[5],
+            'product_name':j[6],
+            'price_unit':j[7],
+            'quantity':j[8],
+            'subtotal':j[9],
+            'tax': j[10],
+            'cost': j[11],
+            'history_id': [12],
+            'medic_id': [13],
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/account_invoice_line.pyc


+ 49 - 0
controllers/helpers/company.py

@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_company_info():
+    user_company = r.env.user.company_id.id
+    user_store = r.env.user.store_id.id
+    query = '''
+    SELECT
+        company.id,
+        company.name,
+        currency.id,
+        currency.name,
+        currency.symbol,
+        currency.decimal_places,
+        currency.decimal_separator,
+        currency.thousands_separator,
+        currency.symbol_position,
+        store.name AS store,
+        partner.ruc AS company_ruc
+    FROM res_company AS company
+    LEFT JOIN res_currency AS currency
+    ON company.currency_id = currency.id
+    LEFT JOIN res_store AS store
+    ON store.id = ''' + str(user_store) + '''
+    LEFT JOIN res_partner AS partner
+    ON partner.id = company.partner_id
+    WHERE currency.active = true
+    AND company.id = ''' + str(user_company) + '''
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'currency_id':{
+                'id':  j[2],
+                'name':  j[3],
+                'symbol':  j[4],
+                'decimal_places':  j[5],
+                'decimal_separator':  j[6],
+                'thousands_separator':  j[7],
+                'symbol_position':  j[8],
+            },
+            'store': j[9],
+            'ruc': j[10],
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/company.pyc


+ 17 - 0
controllers/helpers/ir_module_module.py

@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_ir_module_widget():
+    query = '''
+    SELECT name
+    FROM ir_module_module
+    WHERE state = 'installed'
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'name': j[0],
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/ir_module_module.pyc


+ 89 - 0
controllers/helpers/pos_order.py

@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_pos_order_widget():
+    user_store = r.env.user.store_id.id
+
+    validate = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='pos_order')
+    '''
+
+    query = '''
+        SELECT pos.create_date, pos.name, pos.partner_id, pos.user_id, SUM(line.price_subtotal_incl) as amount
+        FROM pos_order as pos
+        LEFT JOIN res_store_journal_rel as journal
+        ON journal.journal_id = pos.sale_journal
+        LEFT JOIN pos_order_line AS line
+        ON line.order_id = pos.id
+        --LEFT JOIN res_partner AS partner
+        --ON partner.id = pos.partner_id
+        WHERE TO_CHAR(pos.date_order,'YYYY-MM') = TO_CHAR(current_date,'YYYY-MM')
+        AND journal.store_id = ''' + str(user_store) + '''
+        GROUP BY pos.create_date, pos.partner_id, pos.user_id, pos.name
+    '''
+
+    r.cr.execute(validate)
+    for j in r.cr.fetchall():
+        band = j[0]
+
+    if band == True:
+        r.cr.execute(query)
+        return [
+            {
+                'date': j[0],
+                'name': j[1],
+                'customer_id': j[2],
+                'user_id': j[3],
+                'amount': j[4],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        return []
+
+def get_pos_order_widget_own():
+    user_store = r.env.user.store_id.id
+    user_id = r.env.user.id
+
+    validate = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='pos_order')
+    '''
+
+    query = '''
+        SELECT pos.create_date, pos.name, pos.partner_id, pos.user_id, SUM(line.price_subtotal_incl) as amount
+        FROM pos_order as pos
+        LEFT JOIN res_store_journal_rel as journal
+        ON journal.journal_id = pos.sale_journal
+        LEFT JOIN pos_order_line AS line
+        ON line.order_id = pos.id
+        --LEFT JOIN res_partner AS partner
+        --ON partner.id = pos.partner_id
+        WHERE TO_CHAR(pos.date_order,'YYYY-MM') = TO_CHAR(current_date,'YYYY-MM')
+        AND journal.store_id = ''' + str(user_store) + ''' AND pos.user_id = ''' + str(user_id) + '''
+        GROUP BY pos.create_date, pos.partner_id, pos.user_id, pos.name
+    '''
+
+    r.cr.execute(validate)
+    for j in r.cr.fetchall():
+        band = j[0]
+
+    if band == True:
+        r.cr.execute(query)
+        return [
+            {
+                'date': j[0],
+                'name': j[1],
+                'customer_id': j[2],
+                'user_id': j[3],
+                'amount': j[4],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        return []

二进制
controllers/helpers/pos_order.pyc


+ 21 - 0
controllers/helpers/res_partner.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_res_partner():
+    query = '''
+        SELECT
+            partner.id,
+            partner.name,
+            partner.active
+        FROM res_partner AS partner WHERE partner.customer = true
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'active':j[2]
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/res_partner.pyc


+ 18 - 0
controllers/helpers/res_store.py

@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_res_store_widget():
+    query = '''
+    SELECT  id,
+            name
+    FROM res_store
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/res_store.pyc


+ 22 - 0
controllers/helpers/res_user.py

@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_user_info():
+    query = '''
+    SELECT
+        partner.id,
+        partner.name,
+        partner.active
+    FROM res_partner AS partner
+    WHERE partner.is_medic = true
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'active':j[2]
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/res_user.pyc


+ 27 - 0
controllers/helpers/widget_list.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_widget_list():
+    user_id = r.env.user.id
+    query = '''
+        SELECT
+        	--users.id,
+        	--partner.name,
+        	chart.name
+        FROM res_users AS users
+        --LEFT JOIN res_partner AS partner
+        --ON partner.id = users.partner_id
+        LEFT JOIN chart_list_users_rel AS chart_rel
+        ON chart_rel.user_id = users.id
+        LEFT JOIN chart_list AS chart
+        ON chart.id = chart_rel.chart_id
+        WHERE users.id = ''' + str(user_id) + '''
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'name': j[0],
+        } for j in r.cr.fetchall()
+    ]

二进制
controllers/helpers/widget_list.pyc


+ 46 - 0
controllers/main.py

@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+from openerp import http
+from werkzeug.wrappers import Response
+from werkzeug.datastructures import Headers
+from gzip import GzipFile
+from StringIO import StringIO as IO
+import simplejson as json
+import helpers as hp
+import logging
+
+LOGGER = logging.getLogger(__name__)
+GZIP_COMPRESSION_LEVEL = 9
+
+def make_gzip_response(data=None, status=200):
+    gzip_buffer = IO()
+
+    with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
+        gzip_file.write(json.dumps(data))
+
+    value = gzip_buffer.getvalue()
+    gzip_buffer.close()
+
+    headers = Headers()
+    headers.add('Content-Encoding', 'gzip')
+    headers.add('Vary', 'Accept-Encoding')
+    headers.add('Content-Length', len(value))
+
+    return Response(value, status=status, headers=headers, content_type='application/json')
+
+class DashboardController3(http.Controller):
+
+    @http.route('/dashboard-widgets3', auth='user', methods=['GET', 'POST'])
+    def getWidgetList(self, **kw):
+        return make_gzip_response({
+            'widgets': hp.get_widget_list(),
+        })
+
+    @http.route('/dashboard-RankingDoctores', auth='user', methods=['GET', 'POST'])
+    def getRankingDoctores(self, **kw):
+
+        return make_gzip_response({
+            'company': hp.get_company_info(),
+            'invoices':hp.get_account_invoice(),
+            'users': hp.get_user_info(),
+            'invoiceslines': hp.get_account_invoice_line_widget(),
+        })

二进制
controllers/main.pyc


+ 15 - 0
data/charts_data.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <!--
+        =============================================================
+            RANKING DE DOCTORES
+        =============================================================
+        -->
+        <record model="chart.list" id="widget_ranking_doctores">
+            <field name="name">RankingDoctores</field>
+        </record>
+
+    </data>
+</openerp>

二进制
static/description/icon.png


+ 390 - 0
static/src/js/chart.js

@@ -0,0 +1,390 @@
+function DashboardChart3(widget) {
+    "use strict";
+
+    var model = openerp;
+
+    widget.DashboardChartWidget3 = widget.Base.extend({
+        BuildLineChart: function (name,label,data,CurrencyBase,linecolor,backgroundColor) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+            var chart = new Chart($(name), {
+                type: 'line',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            label: false,
+                            data: data,
+                            backgroundColor: backgroundColor,
+                            borderColor: linecolor,
+                            borderWidth: 2,
+                            fill: false,
+                        }
+                    ]
+                },
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    events: ['click'],
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    }
+                }
+            });
+        },
+
+        BuildBalanceLineChart: function (name,label,bodySale,bodyPurchase,bodyExpense,CurrencyBase) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+            var chartData = {
+    			labels: label,
+    			datasets: [ {
+    				type: 'bar',
+    				label: 'Ventas',
+                    borderColor: '#43a047',
+                    backgroundColor: '#43a047',
+    				borderWidth: 2,
+    				data: bodySale,
+                    fill: false,
+    			}, {
+    				type: 'bar',
+    				label: 'Compras',
+                    borderColor: '#f9a825',
+    				backgroundColor: '#f9a825',
+    				data: bodyPurchase,
+    				borderWidth: 2,
+                    fill: false,
+    			}, {
+    				type: 'bar',
+    				label: 'Gastos',
+                    borderColor: '#ef6c00',
+    				backgroundColor: '#ef6c00',
+    				data: bodyExpense,
+    				borderWidth: 2,
+                    fill: false,
+    			}]
+    		};
+            var chart = new Chart($(name),{
+                type: 'bar',
+                data: chartData,
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: true,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    // events: ['click'],
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    }
+                }
+            });
+        },
+
+        BuildDoughnutChart: function (name,label,data,CurrencyBase) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+            var color = [];
+            color.push('#BCCEF4');
+            color.push('#A9E5E3');
+            color.push('#A0D995');
+            color.push('#C5D084');
+            color.push('#FAE187');
+            color.push('#FFBD82');
+            color.push('#FFA8B8');
+            color.push('#E5BEDD');
+            color.push('#C4ABFE');
+            color.push('#D8D8D8');
+            var myBar = new Chart($(name), {
+                type: 'doughnut',
+                data: {
+                    labels: label,
+                    datasets: [{
+                        backgroundColor: color,
+                        fill: true,
+                        label:false,
+                        data: data,
+                    }],
+                },
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    hover: {
+                       mode: 'nearest',
+                       intersect: true
+                    },
+                    title: {
+                        display: false,
+                    },
+                    legend: {
+                        display: false,
+                        position: 'right',
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.labels[tooltipItem.index] || '';
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(data.datasets[0].data[tooltipItem.index],{
+                                    symbol: CurrencyBase.symbol,
+                                    format: "%s%v",
+                                    precision: CurrencyBase.decimal_places,
+                                    thousand: CurrencyBase.thousands_separator,
+                                    decimal: CurrencyBase.decimal_separator,
+                                });
+                                return label;
+                            }
+                        }
+                    },
+                },
+            });
+        },
+
+
+        BuildHorizontalBarChart: function (name,CurrencyBase,label,body) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+
+            // var color = [];
+            // color.push('#BCCEF4');
+            // color.push('#A9E5E3');
+            // color.push('#A0D995');
+            // color.push('#C5D084');
+            // color.push('#FAE187');
+            // color.push('#FFBD82');
+            // color.push('#FFA8B8');
+            // color.push('#E5BEDD');
+            // color.push('#C4ABFE');
+            // color.push('#D8D8D8');
+
+            var chart = new Chart($(name), {
+                type: 'horizontalBar',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            data: body,
+                            // backgroundColor: '#43a047',
+                            backgroundColor: '#bbdefb',
+                            fill: true,
+                        }
+                    ]
+                },
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.xLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    },
+                    // events: ['click'],
+                }
+            });
+        },
+
+        BuildBarChart: function (name,CurrencyBase,label,body) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+            var chart = new Chart($(name), {
+                type: 'bar',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            data: body,
+                            backgroundColor: '#bbdefb',
+                            fill: true,
+                        }
+                    ]
+                },
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    },
+                    // events: ['click'],
+                }
+            });
+        },
+
+    });
+}

+ 28 - 0
static/src/js/dashboard.js

@@ -0,0 +1,28 @@
+function dashboard_reporting_widget3 (instance, widget) {
+  "use strict";
+
+  var widgets = widget;
+
+  instance.eiru_reports_dashboard.DashboardReportingWidget = instance.eiru_reports_dashboard.DashboardReportingWidget.extend({
+
+    RenderWidgets: function () {
+      var self = this;
+      this._super.apply(this, arguments);
+
+      var ChartList = self.Widgets;
+
+      // CHART VENTA POR VENDEDOR CON OBJETIVOS
+
+      var chart =  _.flatten(_.filter(ChartList,function (inv) {
+        return inv.name == 'RankingDoctores';
+      }));
+
+      if(chart.length > 0){
+        var RankingDoctores = new widgets.RankingDoctores();
+        RankingDoctores.renderElement();
+        RankingDoctores.start();
+        this.grid.addWidget(RankingDoctores.$el, 0, 0,RankingDoctores.size.width,RankingDoctores.size.height,true);
+      }
+    },
+  });
+}

+ 18 - 0
static/src/js/main.js

@@ -0,0 +1,18 @@
+openerp.eiru_dashboard_mocona = function (instance) {
+  "use strict";
+  instance.eiru_dashboard_mocona = {};
+  var dashboard = instance.eiru_dashboard_mocona;
+
+  widget_reporting_base3(instance, dashboard);
+  dashboard_reporting_widget3(instance, dashboard);
+
+  try{
+
+    DashboardChart3(dashboard);
+    ranking_doctores(dashboard);
+
+  }
+  catch(e){
+    //ERROR
+  }
+}

+ 5 - 0
static/src/js/widget_base.js

@@ -0,0 +1,5 @@
+function widget_reporting_base3 (instance, widget) {
+  "use strict";
+
+  widget.Base = instance.eiru_reports_dashboard.Base.extend({});
+}

+ 100 - 0
static/src/js/widgets/ranking_doctores.js

@@ -0,0 +1,100 @@
+function ranking_doctores(widget) {
+    "use strict";
+
+    var model = openerp;
+    var Qweb = openerp.web.qweb;
+
+    widget.RankingDoctores = widget.Base.extend({
+        template: 'RankingDoctores',
+        init: function (parent) {
+            this._super(parent, {
+                width: 6,
+                height: 4
+            });
+        },
+        start: function () {
+            var self = this;
+            self.fetchInitial();
+        },
+        fetchInitial: function(){
+            var self = this;
+            self.fetchDataSQL().then(function (DataSQL) {
+                return DataSQL;
+            }).then(function(DataSQL) {
+                self.ResCompany = DataSQL.company;
+                self.AccountInvoice = DataSQL.invoices;
+                self.AccountInvoiceLine = DataSQL.invoiceslines;
+                self.ResUser = DataSQL.users;
+                return self.SalesmanRanking();
+            });
+        },
+        fetchDataSQL: function() {
+            var data = $.get('/dashboard-RankingDoctores');
+            return data;
+        },
+
+        getAccountInvoiceLine:function(id) {
+            var self = this;
+            return _.flatten(_.filter(self.AccountInvoiceLine,function (inv) {
+                return inv.id === id;
+            }));
+        },
+        getAccountInvoice:function(id) {
+            var self = this;
+            return _.flatten(_.filter(self.AccountInvoice,function (inv) {
+                return inv.id === id && inv.type == 'out_invoice';
+            }));
+        },
+
+        SalesmanRanking: function() {
+            var self = this;
+            var ranking = [];
+            var amount = 0;
+            var ResUser = self.ResUser;
+            //console.log(ResUser);
+            _.each(ResUser, function (item) {
+                var AccountInvoiceLine = self.getAccountInvoiceLine(item.medic_id);
+                //console.log(AccountInvoiceLine);
+                var AccountInvoice = self.getAccountInvoice(AccountInvoiceLine.invoice_id);
+                _.each(AccountInvoice, function (item1) {
+                    if(item1.type == 'out_invoice'){
+
+                        var account_invoice_amount = _.reduce(_.map(AccountInvoiceLine,function(item) {
+                            return item.subtotal;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        amount = (account_invoice_amount);
+
+                    }
+                });
+
+                if(amount > 0 ){
+                   ranking.push({
+                       name: item.name,
+                       amount: amount,
+                   });
+                }
+            });
+            ranking.sort(function(a, b) {
+                return b.amount - a.amount
+            });
+            self.BuildChart(ranking);
+        },
+        BuildChart: function (ranking){
+            var self = this;
+            var label = [];
+            var body = [];
+            var item;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            for (var i = 0; i < ranking.length; i++) {
+                item = ranking[i];
+                label.push(item.name)
+                body.push(item.amount);
+            }
+            var name = '.ranking-doctores-chart';
+            var chart = new widget.DashboardChartWidget3(self);
+            chart.BuildHorizontalBarChart(name,CurrencyBase,label,body);
+        }
+    });
+}

+ 17 - 0
static/src/xml/widgets/ranking_doctores.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="RankingDoctores">
+        <div>
+            <div class="grid-stack-item-content reporting-dashboard ucrm">
+                <div class="widget-content">
+                    <div class="row">
+                        <h2 style="margin-top:0px;margin-left:10px;" class="text-center"><small> Ranking de Doctores </small></h2>
+                    </div>
+                    <div class="chart-container center-block" style="padding:10px;height:6.5cm;">
+                        <canvas class="ranking-doctores-chart"></canvas>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </t>
+</template>

+ 14 - 0
template.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+  <data>
+    <template id="eiru_dashboard_mocona_assets" inherit_id="eiru_assets.assets">
+      <xpath expr="." position="inside">
+        <script type="text/javascript" src="/eiru_dashboard_mocona/static/src/js/chart.js"/>
+        <script type="text/javascript" src="/eiru_dashboard_mocona/static/src/js/widget_base.js" />
+        <script type="text/javascript" src="/eiru_dashboard_mocona/static/src/js/widgets/ranking_doctores.js"/>
+        <script type="text/javascript" src="/eiru_dashboard_mocona/static/src/js/dashboard.js"/>
+        <script type="text/javascript" src="/eiru_dashboard_mocona/static/src/js/main.js"/>
+      </xpath>
+    </template>
+  </data>
+</openerp>