Kaynağa Gözat

first commit

deisy 6 yıl önce
işleme
bb9bd63774
41 değiştirilmiş dosya ile 1259 ekleme ve 0 silme
  1. 3 0
      __init__.py
  2. BIN
      __init__.pyc
  3. 24 0
      __openerp__.py
  4. 1 0
      controllers/__init__.py
  5. BIN
      controllers/__init__.pyc
  6. 12 0
      controllers/helpers/__init__.py
  7. BIN
      controllers/helpers/__init__.pyc
  8. 105 0
      controllers/helpers/account_invoice.py
  9. BIN
      controllers/helpers/account_invoice.pyc
  10. 49 0
      controllers/helpers/company.py
  11. BIN
      controllers/helpers/company.pyc
  12. 49 0
      controllers/helpers/dashboard_objective.py
  13. BIN
      controllers/helpers/dashboard_objective.pyc
  14. 17 0
      controllers/helpers/ir_module_module.py
  15. BIN
      controllers/helpers/ir_module_module.pyc
  16. 45 0
      controllers/helpers/pos_order.py
  17. BIN
      controllers/helpers/pos_order.pyc
  18. 18 0
      controllers/helpers/res_store.py
  19. BIN
      controllers/helpers/res_store.pyc
  20. 22 0
      controllers/helpers/res_user.py
  21. BIN
      controllers/helpers/res_user.pyc
  22. 27 0
      controllers/helpers/widget_list.py
  23. BIN
      controllers/helpers/widget_list.pyc
  24. 59 0
      controllers/main.py
  25. BIN
      controllers/main.pyc
  26. 23 0
      data/charts_data.xml
  27. 2 0
      models/__init__.py
  28. BIN
      models/__init__.pyc
  29. 19 0
      models/salesman_objective.py
  30. BIN
      models/salesman_objective.pyc
  31. BIN
      static/description/icon.png
  32. 156 0
      static/src/js/chart.js
  33. 41 0
      static/src/js/dashboard.js
  34. 20 0
      static/src/js/main.js
  35. 5 0
      static/src/js/widget_base.js
  36. 320 0
      static/src/js/widgets/widget_salesman_objective.js
  37. 136 0
      static/src/js/widgets/widget_salesman_ranking_with_objective.js
  38. 46 0
      static/src/xml/widgets/widget_salesman_objective.xml
  39. 17 0
      static/src/xml/widgets/widget_salesman_ranking_with_objective.xml
  40. 15 0
      template.xml
  41. 28 0
      views/salesman_objective.xml

+ 3 - 0
__init__.py

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

BIN
__init__.pyc


+ 24 - 0
__openerp__.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+{
+    'name': "Widgets for salesman objectives ",
+    'author': "Eiru",
+    'website': "https://www.eiru.com.py",
+    'category': 'Uncategorized',
+    'version': '2.0',
+    'depends': [
+        'base',
+        'account',
+        'sale',
+        'eiru_reports_dashboard',
+    ],
+    'data': [
+        'views/salesman_objective.xml',
+        '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

BIN
controllers/__init__.pyc


+ 12 - 0
controllers/helpers/__init__.py

@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+
+from company import get_company_info
+from account_invoice import get_account_invoice_widget
+from account_invoice import get_account_invoice_salesman_ranking
+from ir_module_module import get_ir_module_widget
+from dashboard_objective import get_dashboard_objective_widget
+from dashboard_objective import get_own_objective
+from pos_order import get_pos_order_widget
+from res_user import get_user_info
+from res_store import get_res_store_widget
+from widget_list import get_widget_list

BIN
controllers/helpers/__init__.pyc


+ 105 - 0
controllers/helpers/account_invoice.py

@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_invoice_widget():
+    user_store = r.env.user.store_id.id
+    user_id = r.env.user.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
+        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 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) + ''' AND invoice.user_id = ''' + str(user_id) + '''
+        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],
+
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_invoice_salesman_ranking():
+    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
+        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 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,
+        	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],
+
+        } for j in r.cr.fetchall()
+    ]

BIN
controllers/helpers/account_invoice.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()
+    ]

BIN
controllers/helpers/company.pyc


+ 49 - 0
controllers/helpers/dashboard_objective.py

@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_dashboard_objective_widget():
+    user_store = r.env.user.store_id.id
+    query = '''
+    SELECT  user_id,
+            store_id,
+            date,
+            sale_objective
+    FROM salesman_objective
+    WHERE TO_CHAR(date,'YYYY-MM') = TO_CHAR(current_date,'YYYY-MM')
+    AND store_id = ''' + str(user_store) + '''
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'user_id': j[0],
+            'store_id': j[1],
+            'date': j[2],
+            'sale_objective': j[3],
+        } for j in r.cr.fetchall()
+    ]
+
+def get_own_objective():
+    user_id = r.env.user.id
+    user_store = r.env.user.store_id.id
+    query = '''
+    SELECT  user_id,
+            store_id,
+            date,
+            sale_objective
+    FROM salesman_objective
+    WHERE TO_CHAR(date,'YYYY-MM') = TO_CHAR(current_date,'YYYY-MM')
+    AND store_id = ''' + str(user_store) + ''' AND user_id = ''' + str(user_id) + '''
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'user_id': j[0],
+            'store_id': j[1],
+            'date': j[2],
+            'sale_objective': j[3],
+        } for j in r.cr.fetchall()
+    ]

BIN
controllers/helpers/dashboard_objective.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()
+    ]

BIN
controllers/helpers/ir_module_module.pyc


+ 45 - 0
controllers/helpers/pos_order.py

@@ -0,0 +1,45 @@
+# -*- 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 []

BIN
controllers/helpers/pos_order.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()
+    ]

BIN
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
+        users.id,
+        partner.name
+    FROM res_users AS users
+    LEFT JOIN res_partner AS partner
+    ON partner.id = users.partner_id
+    WHERE users.active = true
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+        } for j in r.cr.fetchall()
+    ]

BIN
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()
+    ]

BIN
controllers/helpers/widget_list.pyc


+ 59 - 0
controllers/main.py

@@ -0,0 +1,59 @@
+# -*- 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 DashboardController2(http.Controller):
+
+    @http.route('/dashboard-widgets2', auth='user', methods=['GET', 'POST'])
+    def getWidgetList(self, **kw):
+        return make_gzip_response({
+            'widgets': hp.get_widget_list(),
+        })
+
+    @http.route('/dashboard-SalesmanObjective', auth='user', methods=['GET', 'POST'])
+    def getSalesmanObjective(self, **kw):
+
+        return make_gzip_response({
+            'company': hp.get_company_info(),
+            'modules': hp.get_ir_module_widget(),
+            'objectives':hp.get_own_objective(),
+            'orders':hp.get_pos_order_widget(),
+            'invoices':hp.get_account_invoice_widget(),
+
+        })
+
+    @http.route('/dashboard-RankingSalesmanObjective', auth='user', methods=['GET', 'POST'])
+    def getRankingSalesman(self, **kw):
+
+        return make_gzip_response({
+            'company': hp.get_company_info(),
+            'users': hp.get_user_info(),
+            'orders':hp.get_pos_order_widget(),
+            'invoices':hp.get_account_invoice_salesman_ranking(),
+            'objective':hp.get_dashboard_objective_widget(),
+        })

BIN
controllers/main.pyc


+ 23 - 0
data/charts_data.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        <!--
+        =============================================================
+            OBJETIVOS POR VENDEDORES
+        =============================================================
+        -->
+        <record model="chart.list" id="widget_salesman_objective">
+            <field name="name">WidgetSalesmanObjective</field>
+        </record>
+
+        <!--
+        =============================================================
+            RANKING DE VENDEDORES CON OBJETIVO
+        =============================================================
+        -->
+        <record model="chart.list" id="widget_salesman_ranking_objective">
+            <field name="name">WidgetSalesmanRankingObjective</field>
+        </record>
+
+    </data>
+</openerp>

+ 2 - 0
models/__init__.py

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

BIN
models/__init__.pyc


+ 19 - 0
models/salesman_objective.py

@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from openerp import models, fields, api
+
+class DashboardObjective(models.Model):
+    _name = 'salesman.objective'
+
+
+    user_id = fields.Many2one('res.users', string='Vendedor')
+    store_id = fields.Many2one('res.store', string='Sucursal')
+    date = fields.Date("Fecha")
+    sale_objective = fields.Float(string="Objetivo de Ventas")
+
+    @api.onchange('user_id')
+    def onchange_user_id(self):
+        res = {}
+        user = self.env['res.users'].search([('id','=', self.user_id.id)])
+        self.store_id = user.store_id.id
+        res = {'value' :{'store_id': self.store_id}}
+        return res

BIN
models/salesman_objective.pyc


BIN
static/description/icon.png


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

@@ -0,0 +1,156 @@
+function DashboardChart2(widget) {
+  "use strict";
+
+  var model = openerp;
+
+  widget.DashboardChartWidget2 = 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;
+              }
+            }
+          }
+        }
+      });
+    },
+
+    BuildBarChart2: function (name,label,bodyObjective,bodySale,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: 'horizontalBar',
+          label: 'Meta',
+          borderColor: '#43a047',
+          backgroundColor: '#43a047',
+          borderWidth: 2,
+          data: bodyObjective,
+          fill: true,
+        }, {
+          type: 'horizontalBar',
+          label: 'Logrado',
+          borderColor: '#f9a825',
+          backgroundColor: '#f9a825',
+          data: bodySale,
+          borderWidth: 2,
+          fill: true,
+        }]
+      };
+
+      var chart = new Chart($(name),{
+        type: 'horizontalBar',
+        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,
+            }
+          },
+          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;
+              }
+            }
+          }
+        }
+      });
+    },
+  });
+}

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

@@ -0,0 +1,41 @@
+function dashboard_reporting_widget2 (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 MIS OBJETIVOS DE VENTA
+
+      var chart =  _.flatten(_.filter(ChartList,function (inv) {
+        return inv.name == 'WidgetSalesmanObjective';
+      }));
+
+      if(chart.length > 0){
+        var WidgetSalesmanObjective = new widgets.WidgetSalesmanObjective();
+        WidgetSalesmanObjective.renderElement();
+        WidgetSalesmanObjective.start();
+        this.grid.addWidget(WidgetSalesmanObjective.$el, 0, 0,WidgetSalesmanObjective.size.width,WidgetSalesmanObjective.size.height,true);
+      }
+
+      // CHART VENTA POR VENDEDOR CON OBJETIVOS
+
+      var chart =  _.flatten(_.filter(ChartList,function (inv) {
+        return inv.name == 'WidgetSalesmanRankingObjective';
+      }));
+
+      if(chart.length > 0){
+        var WidgetSalesmanRankingObjective = new widgets.SalesmanRankingObjective();
+        WidgetSalesmanRankingObjective.renderElement();
+        WidgetSalesmanRankingObjective.start();
+        this.grid.addWidget(WidgetSalesmanRankingObjective.$el, 0, 0,WidgetSalesmanRankingObjective.size.width,WidgetSalesmanRankingObjective.size.height,true);
+      }
+    },
+  });
+}

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

@@ -0,0 +1,20 @@
+openerp.eiru_dashboard_salesman_objective = function (instance) {
+  "use strict";
+  instance.eiru_dashboard_salesman_objective = {};
+  var dashboard = instance.eiru_dashboard_salesman_objective;
+
+  widget_reporting_base2(instance, dashboard);
+  dashboard_reporting_widget2(instance, dashboard);
+
+  try{
+
+    DashboardChart2(dashboard);
+
+    widget_salesman_objective(dashboard);
+    widget_salesman_ranking_with_objective(dashboard);
+
+  }
+  catch(e){
+    //ERROR
+  }
+}

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

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

+ 320 - 0
static/src/js/widgets/widget_salesman_objective.js

@@ -0,0 +1,320 @@
+function widget_salesman_objective(widget) {
+  "use strict";
+
+  var model = openerp;
+  var Qweb = openerp.web.qweb;
+
+  widget.WidgetSalesmanObjective = widget.Base.extend({
+    template: 'WidgetSalesmanObjective',
+    modules: ['point_of_sale'],
+
+    SaleObjectiveAmount: 0,
+    SaleMonth: 0,
+    content: [],
+
+    init: function (parent) {
+      this._super(parent, {
+        width: 12,
+        height: 6
+      });
+    },
+
+    fetchUTC: function(){
+      var self = this;
+      var date = moment().format('YYYY-MM-01 00:00:00');
+      var utc = moment.utc(date,'YYYY-MM-DD h:mm:ss A');
+      var first = moment('00:00:00','HH:mm:ss');
+      var second = moment(moment(utc._d,'HH:mm:ss'));
+      var data = moment.duration(first - second);
+      return data._data.hours;
+    },
+
+    start: function () {
+      var self = this;
+      self.fetchInitial();
+    },
+
+    checkModel : function(model){
+      var self = this;
+      return _.filter(self.IrModuleModule,function(item){
+        return item.name === model;
+      });
+    },
+
+    fetchInitial: function(){
+      var self = this;
+      self.fetchDataSQL().then(function (DataSQL) {
+        return DataSQL;
+      }).then(function(DataSQL) {
+        self.IrModuleModule = DataSQL.modules;
+        self.ResCompany = DataSQL.company;
+        self.DashboardObjective = DataSQL.objectives;
+        self.PosOrder = DataSQL.orders;
+        self.AccountInvoice = DataSQL.invoices;
+        return self.fetchMonth();
+      });
+    },
+
+    fetchDataSQL: function() {
+      var self = this;
+      var data = $.get('/dashboard-SalesmanObjective');
+      return data;
+    },
+
+    getPercentage: function(amount, objective){
+      var self = this;
+      var percentage = 0;
+      if(objective > 0){
+        percentage = (amount * 100)/objective;
+      }
+      return percentage;
+    },
+
+    fetchToday: function (type) {
+      var self = this;
+      var amount = 0;
+
+      if(type == "sale"){
+        var today = moment().format('YYYY-MM-DD');
+        var PosOrder = _.reduce(_.map(self.PosOrder,function(item) {
+          var utc = moment.utc(item.date,'YYYY-MM-DD h:mm:ss A');
+          utc = moment(utc._d).format('YYYY-MM-DD');
+          if(utc == today){
+            return item.amount;
+          }else{
+            return 0;
+          }
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var AccountInvoice = _.reduce(_.map(self.AccountInvoice,function(item) {
+          if(item.date ==  moment().format('YYYY-MM-DD') && item.type == "out_invoice"){
+            return item.amount;
+          }else{
+            return 0;
+          }
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var AccountInvoiceRefund = _.reduce(_.map(self.AccountInvoice,function(item) {
+          if(item.date ==  moment().format('YYYY-MM-DD') && item.type == "out_refund"){
+            return item.amount;
+          }else{
+            return 0;
+          }
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+        amount = PosOrder + AccountInvoice - AccountInvoiceRefund;
+      }
+      self.today = amount;
+    },
+
+    fetchWeek: function (type) {
+      var self = this;
+      var amount = 0;
+      var content = [];
+
+      if(type == "sale"){
+        var utc = self.fetchUTC();
+        var week_from = moment().weekday(0).format('YYYY-MM-DD 00:00:00');
+        week_from = moment(week_from).add(utc,'hours').format('YYYY-MM-DD HH:mm:ss');
+        var week_to = moment(week_from).weekday(7).format('YYYY-MM-DD HH:mm:ss');
+
+        var PosOrder = _.reduce(_.map(self.PosOrder,function(item) {
+          if(item.date >= week_from && item.date < week_to){
+            var utc = moment.utc(item.date,'YYYY-MM-DD h:mm:ss A');
+            content.push({
+              date: moment(utc._d).format('YYYY-MM-DD'),
+              amount: item.amount,
+            });
+            return item.amount;
+          }else{
+            return 0;
+          }
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var AccountInvoice = _.reduce(_.map(self.AccountInvoice,function(item) {
+          if(item.date >= moment().weekday(0).format('YYYY-MM-DD') && item.date < moment().weekday(7).format('YYYY-MM-DD') && item.type == "out_invoice"){
+            content.push({
+              date: item.date,
+              amount: item.amount,
+            });
+            return item.amount;
+          }else{
+            return 0;
+          }
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var AccountInvoiceRefund = _.reduce(_.map(self.AccountInvoiceRefund,function(item) {
+          if(item.date >= moment().weekday(0).format('YYYY-MM-DD') && item.date < moment().weekday(7).format('YYYY-MM-DD') && item.type == "out_refund"){
+            content.push({
+              date: item.date,
+              amount: item.amount * -1,
+            });
+            return item.amount;
+          }else{
+            return 0;
+          }
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+        amount = PosOrder + AccountInvoice - AccountInvoiceRefund;
+      }
+
+      self.week = amount;
+
+    },
+
+    fetchMonth: function () {
+      var self = this;
+      var content = [];
+      var CurrencyBase = self.ResCompany[0].currency_id;
+
+      var PosOrder = _.reduce(_.map(self.PosOrder,function(item) {
+        var utc = moment.utc(item.date,'YYYY-MM-DD h:mm:ss A');
+        content.push({
+          date: moment(utc._d).format('YYYY-MM-DD'),
+          amount: item.amount,
+        });
+        utc = moment(utc._d).format('YYYY-MM-DD');
+        var value = 0;
+        if(moment(utc).format('YYYY-MM') == moment().format('YYYY-MM')){
+          value = item.amount;
+        }
+        return value;
+      }),function(memo, num) {
+        return memo + num;
+      },0);
+
+      var AccountInvoice = _.reduce(_.map(self.AccountInvoice,function(item) {
+        if(item.type == 'out_invoice'){
+          content.push({
+            date: item.date,
+            amount: item.amount,
+          });
+          return item.amount;
+        }else{
+          return 0;
+        }
+      }),function(memo, num) {
+        return memo + num;
+      },0);
+
+      var AccountInvoiceRefund = _.reduce(_.map(self.AccountInvoice,function(item) {
+        if(item.type == 'out_refund'){
+          content.push({
+            date: item.date,
+            amount: item.amount * -1,
+          });
+          return item.amount;
+        }else{
+          return 0;
+        }
+      }),function(memo, num) {
+        return memo + num;
+      },0);
+
+      var sale = PosOrder + AccountInvoice - AccountInvoiceRefund;
+      self.SaleMonth = sale;
+      self.content = content;
+      self.BuildWidget(sale);
+    },
+
+    BuildChartMonth: function(){
+      var self = this;
+      var data = [];
+      var CurrencyBase = self.ResCompany[0].currency_id;
+      var label = [];
+      var bodySale = [];
+      var name = '.salesman-objective-chart';
+      var date_start = moment().format('YYYY-MM-01');
+      var date_stop = moment().add(1,'months').format('YYYY-MM-01');
+      var date = date_start;
+      var total, i;
+
+      for (i = 0; i < 32; i++) {
+        total = 0;
+        if(i > 0){
+          date = moment(date).add(1,'days').format('YYYY-MM-DD');
+        }
+        if(date == date_stop){
+          break;
+        }
+        data = self.getContentByDate(date, self.content);
+
+        if(data.length > 0){
+          total = _.reduce(_.map(data,function(item) {
+            return item.amount;
+          }),function(memo, num) {
+            return memo + num;
+          },0);
+        }
+        label.push(moment(date).format('DD'));
+        bodySale.push(total);
+      }
+      var ChartColor = '#43a047';
+      var chart = new widget.DashboardChartWidget2(self);
+      chart.BuildLineChart(name,label,bodySale,CurrencyBase,ChartColor,ChartColor);
+    },
+
+    getContentByDate:function(date, content) {
+      var self = this;
+      return _.flatten(_.filter(content,function (inv) {
+        return moment(inv.date).format('YYYY-MM-DD') === date;
+      }));
+    },
+
+
+    BuildWidget: function(sale){
+      var self = this;
+      var ObjectivePending;
+      var Objective;
+      var Today;
+      var Week;
+      var Month;
+      var ObjectivePercentage = 0;
+      var ChartColor;
+      var CurrencyBase = self.ResCompany[0].currency_id;
+      if(self.DashboardObjective.length > 0){
+        self.SaleObjectiveAmount = self.DashboardObjective[0].sale_objective;
+        ObjectivePercentage = self.getPercentage(sale, self.SaleObjectiveAmount);
+      }
+
+      self.fetchToday('sale');
+      self.fetchWeek('sale');
+      self.BuildChartMonth();
+      ChartColor = '#43a047';
+
+      $("#saleObjective").circliful({
+        animationStep: 10,
+        foregroundBorderWidth: 12,
+        backgroundBorderWidth: 1,
+        percent: ObjectivePercentage,
+        fontColor: ChartColor,
+        foregroundColor: ChartColor,
+        percentageTextSize: 35,
+      });
+
+      ObjectivePending = accounting.formatMoney(self.SaleObjectiveAmount - self.SaleMonth, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+      Objective = accounting.formatMoney(self.SaleObjectiveAmount, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+      Today = accounting.formatMoney(self.today, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+      Week = accounting.formatMoney(self.week, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+      Month = accounting.formatMoney(self.SaleMonth, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+
+      self.$el.find('#pending').text(ObjectivePending);
+      self.$el.find('#objective').text(Objective);
+      self.$el.find('#today').text(Today);
+      self.$el.find('#week').text(Week);
+      self.$el.find('#month').text(Month);
+
+
+    },
+  });
+}

+ 136 - 0
static/src/js/widgets/widget_salesman_ranking_with_objective.js

@@ -0,0 +1,136 @@
+function widget_salesman_ranking_with_objective(widget) {
+  "use strict";
+
+  var Qweb = openerp.web.qweb;
+
+  widget.SalesmanRankingObjective = widget.Base.extend({
+    template: 'SalesmanRankingObjective',
+    init: function (parent) {
+      this._super(parent, {
+        width: 12,
+        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.PosOrder = DataSQL.orders;
+        self.ResUser = DataSQL.users;
+        self.Objective = DataSQL.objective;
+        return self.SalesmanRanking();
+      });
+    },
+
+    fetchDataSQL: function() {
+      var data = $.get('/dashboard-RankingSalesmanObjective');
+      return data;
+    },
+
+    getPosOrder:function(id) {
+      var self = this;
+      return _.flatten(_.filter(self.PosOrder,function (inv) {
+        return inv.user_id === id;
+      }));
+    },
+
+    getAccountInvoice:function(id) {
+      var self = this;
+      return _.flatten(_.filter(self.AccountInvoice,function (inv) {
+        return inv.user_id === id && inv.type == 'out_invoice';
+      }));
+    },
+
+    getAccountInvoiceRefund:function(id) {
+      var self = this;
+      return _.flatten(_.filter(self.AccountInvoice,function (inv) {
+        return inv.user_id === id && inv.type == 'out_refund';
+      }));
+    },
+
+    getUserObjective:function(id) {
+      var self = this;
+      return _.map(_.filter(self.Objective,function (inv) {
+        return inv.user_id === id;
+      }), function(map){
+        return map.sale_objective;
+      });
+    },
+
+    SalesmanRanking: function() {
+      var self = this;
+      var ranking = [];
+      var ResUser = self.ResUser;
+
+      _.each(ResUser, function (item) {
+        var PosOrder = self.getPosOrder(item.id);
+        var AccountInvoice = self.getAccountInvoice(item.id);
+        var AccountInvoiceRefund = self.getAccountInvoiceRefund(item.id);
+        var UserObjective = self.getUserObjective(item.id);
+
+        var pos_order_amount = _.reduce(_.map(PosOrder,function(item) {
+          return item.amount;
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var account_invoice_amount = _.reduce(_.map(AccountInvoice,function(item) {
+          return item.amount;
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var account_invoice_refund_amount = _.reduce(_.map(AccountInvoiceRefund,function(item) {
+          return item.amount;
+        }),function(memo, num) {
+          return memo + num;
+        },0);
+
+        var amount = (pos_order_amount + account_invoice_amount) - account_invoice_refund_amount;
+
+        if(amount > 0 ){
+          ranking.push({
+            name: item.name,
+            amount: amount,
+            objective: UserObjective[0],
+          });
+        }
+      });
+
+      ranking.sort(function(a, b) {
+        return b.amount - a.amount
+      });
+
+      self.BuildChart(ranking);
+    },
+
+    BuildChart: function (ranking){
+      var self = this;
+      var label = [];
+      var bodySale = [];
+      var bodyObjective = [];
+      var item;
+      var CurrencyBase = self.ResCompany[0].currency_id;
+
+      for (var i = 0; i < ranking.length; i++) {
+        item = ranking[i];
+        label.push(item.name);
+        bodySale.push(item.amount);
+        bodyObjective.push(item.objective);
+      }
+
+      var name = '.ranking-salesman-objective-chart';
+      var chart = new widget.DashboardChartWidget2(self);
+      chart.BuildBarChart2(name,label,bodyObjective,bodySale,CurrencyBase);
+    }
+  });
+}

+ 46 - 0
static/src/xml/widgets/widget_salesman_objective.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+  <t t-name="WidgetSalesmanObjective">
+    <div class="grid-stack-item-content reporting-dashboard ucrm">
+      <div class="widget-content" >
+        <div style="font-size: 20px; color: #777; font-weight: normal; margin:10px;">
+          Mi objetivo de venta
+        </div>
+
+        <div class="modal-body dashboard-modal">
+          <div class="row" style="border-bottom:1px solid #e0e0e0;">
+            <div class="col-md-2 col-lg-2 text-center">
+              <div
+                id="saleObjective"
+                data-preset="circle"
+                class="ldBar label-center"
+                style="width:200px; font-family:Arial; font-size: 4.0em; margin-left: -15px;"
+                data-stroke-width="10">
+              </div>
+            </div>
+            <div class="col-md-10 col-lg-10" style="height:250px;">
+              <canvas class="salesman-objective-chart"></canvas>
+            </div>
+          </div>
+          <div class="row">
+            <div class="center-block" style="padding:20px;font-size:10pt;">
+              <div class="col-xs-6" style="color:#777;">
+                <span><i class="fa fa-circle-o fa-lg" style="padding:10px"></i>Meta del mes: <i id="objective"/></span>
+                <br/>
+                <span><i class="fa fa-circle-o fa-lg" style="padding:10px"></i>Faltante para logar la meta del mes: <i id="pending"/></span>
+              </div>
+              <div class="col-xs-6" style="color:#777;">
+                <span><i class="fa fa-money fa-lg" style="padding:10px"></i>Facturación del dia: <i id="today"/></span>
+                <br/>
+                <span><i class="fa fa-money fa-lg" style="padding:10px"></i>Facturación de la semana: <i id="week"/></span>
+                <br/>
+                <span><i class="fa fa-money fa-lg" style="padding:10px"></i>Facturación del mes: <i id="month"/></span>
+                <br/>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </t>
+</template>

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

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+  <t t-name="SalesmanRankingObjective">
+    <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 Vendedores </small></h2>
+          </div>
+          <div class="chart-container center-block" style="padding:10px;height:6.5cm;">
+            <canvas class="ranking-salesman-objective-chart"></canvas>
+          </div>
+        </div>
+      </div>
+    </div>
+  </t>
+</template>

+ 15 - 0
template.xml

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

+ 28 - 0
views/salesman_objective.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+  <data>
+
+    <record id="salesman_objective_tree_view" model="ir.ui.view">
+      <field name="name">salesman.objective.tree</field>
+      <field name="model">salesman.objective</field>
+      <field name="arch" type="xml">
+        <tree string="dashboard.objective" editable="botom">
+          <field name="user_id" required="1"/>
+          <field name="store_id" required="1"/>
+          <field name="date" required="1"/>
+          <field name="sale_objective" required="1"/>
+        </tree>
+      </field>
+    </record>
+
+    <record model="ir.actions.act_window" id="action_salesman_objective">
+      <field name="name">Objetivos por Vendedor</field>
+      <field name="res_model">salesman.objective</field>
+      <field name="view_type">form</field>
+      <field name="view_mode">tree</field>
+    </record>
+
+    <menuitem name="Establecer Objetivos por Vendedor" parent="eiru_reports_dashboard.dashboard_objetive_parent_menu" id="dashboard_objective_submenu2" action="action_salesman_objective"/>
+
+  </data>
+</openerp>