Sfoglia il codice sorgente

fidelizacion de ventas

deisy 5 anni fa
parent
commit
a57daf25b2

+ 1 - 1
__init__.py

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

BIN
__init__.pyc


+ 1 - 0
__openerp__.py

@@ -9,6 +9,7 @@
         'account',
         'eiru_assets',
         'eiru_reports',
+        'eiru_delivery_baco',
     ],
     'qweb': [
         'static/src/xml/*.xml',

+ 2 - 0
controller/__init__.py

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

+ 9 - 0
controller/helpers/__init__.py

@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+from res_company import get_res_company_baco
+from res_company import get_company_logo_baco
+from res_store import get_res_store_baco
+from account_journal import get_account_journal_baco
+from res_users import get_res_users_baco
+from account_invoice import get_account_invoice_sale_type_baco
+from pos_order import get_pos_order_baco
+from res_partner import get_res_partner_baco

+ 206 - 0
controller/helpers/account_invoice.py

@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_invoice_sale_type_baco(): #historico de venta
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    validate_columns = '''
+        SELECT EXISTS (SELECT 1 FROM information_schema.columns
+        WHERE table_name='account_invoice' AND column_name in ('contado','credito'))'''
+
+    query1 = '''
+        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]),
+            invoice.number,
+            partner.name,
+            customer.name,
+            invoice.amount_tax * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]),
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number,
+            customer.phone,
+            customer.mobile,
+            customer.email,
+            invoice.is_delivery,
+            invoice.delivery_type
+        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
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('out_invoice')
+        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,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number,
+            customer.phone,
+            customer.mobile,
+            customer.email
+    '''
+
+    query2 = '''
+        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]),
+            invoice.number,
+            partner.name,
+            customer.name,
+            invoice.amount_tax * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]),
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number,
+            invoice.contado,
+            invoice.credito,
+            customer.phone,
+            customer.mobile,
+            customer.email,
+            invoice.is_delivery,
+            invoice.delivery_type
+        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
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('out_invoice')
+        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,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number,
+            customer.phone,
+            customer.mobile,
+            customer.email
+    '''
+
+    r.cr.execute(validate_columns)
+
+    for j in r.cr.fetchall():
+        column = j[0]
+
+    if column == True:
+        r.cr.execute(query2,(tuple([company_currency_rate,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],
+            'user_name':j[9],
+            'customer_name':j[10],
+            'amount_tax':j[11],
+            'state':j[12],
+            'store_id':j[13],
+            'journal_id':j[14],
+            'state':j[15],
+            'company_id':j[16],
+            'customer_ruc':j[17],
+            'supplier_invoice_number':j[18],
+            'contado':j[19],
+            'credito':j[20],
+            'phone':j[21],
+            'mobile':j[22],
+            'email':j[23],
+            'is_delivery':j[24],
+            'delivery_type':j[25]
+        } for j in r.cr.fetchall()]
+    else:
+        r.cr.execute(query1,(tuple([company_currency_rate,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],
+            'user_name':j[9],
+            'customer_name':j[10],
+            'amount_tax':j[11],
+            'state':j[12],
+            'store_id':j[13],
+            'journal_id':j[14],
+            'state':j[15],
+            'company_id':j[16],
+            'customer_ruc':j[17],
+            'supplier_invoice_number':j[18],
+            'phone':j[19],
+            'mobile':j[20],
+            'email':j[21],
+            'is_delivery':j[22],
+            'delivery_type':j[23]
+        } for j in r.cr.fetchall()]

+ 15 - 0
controller/helpers/account_journal.py

@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'account.journal'
+
+def get_account_journal_baco():
+    return [
+        {
+            'id': journal.id,
+            'name': journal.name,
+            'code': journal.code,
+            'type': journal.type,
+            'store_id': journal.store_ids.id
+        } for journal in r.env[_MODEL].search([])
+    ]

+ 88 - 0
controller/helpers/pos_order.py

@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_pos_order_baco():
+    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,
+            partner.name,
+            pos.id,
+            salesperson.name,
+            SUM(line.price_subtotal) as untaxed,
+            pos.sale_journal,
+            journal.store_id,
+            pos.company_id,
+            partner.ruc,
+            partner.phone,
+            partner.mobile,
+            partner.email
+        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
+        LEFT JOIN res_users AS users
+        ON users.id = pos.user_id
+        LEFT JOIN res_partner AS salesperson
+        ON salesperson.id = users.partner_id
+        GROUP BY
+            pos.create_date,
+            pos.partner_id,
+            pos.user_id,
+            pos.name,
+            partner.name,
+            pos.id,
+            salesperson.name,
+            pos.sale_journal,
+            journal.store_id,
+            pos.company_id,
+            partner.ruc,
+            partner.phone,
+            partner.mobile,
+            partner.email
+    '''
+
+    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],
+                'customer_name': j[5],
+                'order_id': j[6],
+                'user_name': j[7],
+                'amount_untaxed': j[8],
+                'journal_id': j[9],
+                'store_id': j[10],
+                'company_id': j[11],
+                'customer_ruc': j[12],
+                'phone':j[13],
+                'mobile':j[14],
+                'email':j[15],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        return []

+ 62 - 0
controller/helpers/res_company.py

@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'res.company'
+
+def get_company_logo_baco():
+    domain = [
+        # ('expense','=', True)
+    ]
+    return [
+        {
+            'id': company.id,
+            'logo': company.logo,
+        } for company in r.env[_MODEL].search(domain)
+    ]
+
+def get_res_company_baco():
+    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
+        ORDER BY company.id ASC
+    '''
+
+    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()
+    ]

+ 22 - 0
controller/helpers/res_partner.py

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

+ 13 - 0
controller/helpers/res_store.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'res.store'
+
+def get_res_store_baco():
+    return [
+        {
+            'id': store.id,
+            'name': store.name,
+            'company_id': store.company_id.id,
+        } for store in r.env[_MODEL].search([])
+    ]

+ 27 - 0
controller/helpers/res_users.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_res_users_baco():
+    query = '''
+        SELECT
+            users.id,
+            users.company_id,
+            users.store_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],
+            'company_id': j[1],
+            'store_id': j[2],
+            'name': j[3],
+
+        } for j in r.cr.fetchall()
+    ]

+ 52 - 0
controller/main.py

@@ -0,0 +1,52 @@
+# -*- 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 ReportController(http.Controller):
+
+    # CONSULTA INICIAL
+    @http.route('/report-filter-data-baco', auth='user', methods=['GET', 'POST'])
+    def getFilterData(self, **kw):
+        return make_gzip_response({
+            'companies': hp.get_res_company_baco(),
+            'logo': hp.get_company_logo_baco(),
+            'stores': hp.get_res_store_baco(),
+            'journals': hp.get_account_journal_baco(),
+            'users': hp.get_res_users_baco(),
+            'partner':hp.get_res_partner_baco(),
+
+        })
+
+    # HISTORICO DE VENTAS
+    @http.route('/report-sale-history-baco', auth='user', methods=['GET', 'POST'])
+    def getSaleHistory(self, **kw):
+        return make_gzip_response({
+            'invoices': hp.get_account_invoice_sale_type_baco(),
+            'orders': hp.get_pos_order_baco(),
+            'partners': hp.get_res_partner_baco(),
+        })

+ 0 - 2
controllers.py

@@ -1,2 +0,0 @@
-# -*- coding: utf-8 -*-
-from openerp import http

BIN
controllers.pyc


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

@@ -8,6 +8,7 @@ openerp.eiru_reports_baco = function(instance) {
   try {
     report_product_ranking_baco(reporting);
     report_delivery_baco(reporting);
+    report_ventas_fidelizacion(reporting);
   } catch (e) {
     // ignorar error
   }
@@ -15,6 +16,7 @@ openerp.eiru_reports_baco = function(instance) {
 
   instance.web.client_actions.add('eiru_reports_baco.product_ranking_baco_action', 'instance.eiru_reports_baco.ReportProductRankingBacoWidget');
   instance.web.client_actions.add('eiru_reports_baco.delivery_action', 'instance.eiru_reports_baco.ReportDeliveryWidget');
+  instance.web.client_actions.add('eiru_reports_baco.ventas_fidelizacion_action', 'instance.eiru_reports_baco.ReportVentasWidget');
 
 
 }

+ 809 - 0
static/src/js/reports/report_ventas_fidelizacion.js

@@ -0,0 +1,809 @@
+function report_ventas_fidelizacion(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportVentasWidget = reporting.Base.extend({
+        template: 'ReportVentas',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new model.eiru_reports.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    RES PARTNER
+                =================================
+                */
+                self.ResPartner = IntialSQL.partner;
+                if(self.ResPartner.length > 1){
+                    self.$el.find('#current-customer').append('<option value="9999999">Todas los clientes</option>');
+                    _.each(self.ResPartner,function(item){
+                        self.$el.find('#current-customer').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.customer').css('display','none');
+                }
+
+                /*
+                =================================
+                    RES USERS
+                =================================
+                */
+                self.ResUsers = IntialSQL.users;
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var ResUsers = _.flatten(_.filter(self.ResUsers,function (item) {
+                    return _.contains(store_ids, item.store_id);
+                }));
+                if(ResUsers.length > 0){
+                    self.$el.find('#current-user').append('<option value="9999999">Todos los Vendedores</option>');
+                    _.each(ResUsers,function(item){
+                        self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.users').css('display','none');
+                }
+                return self.fethIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fethCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.ResPartner = DataSQL.partners;
+                self.AccountInvoice = DataSQL.invoices;
+                self.PosOrder = DataSQL.orders;
+
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data-baco');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-history-baco');
+            return data;
+        },
+
+        fethIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fethCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getPosOrder:function(partner_id) {
+            var self = this;
+
+            var content = _.filter(self.PosOrder,function(item){
+              return item.customer_id == partner_id;
+            });
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var type = self.$el.find('#current-type').val();
+            var sale_type = self.$el.find('#current-sale-type').val();
+            var user = self.$el.find('#current-user').val();
+            var customer = self.$el.find('#current-customer').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(state && state != 9999999){
+                if(state == 'open'){
+                    content = [];
+                }
+            }
+            if(type && type != 9999999){
+                if(type == 'sale'){
+                    content = [];
+                }
+            }
+
+            if(sale_type && sale_type != 9999999){
+                if(sale_type == 'local'){
+                  content = [];
+                }
+                if(sale_type == 'envio'){
+                  content = [];
+                }
+            }
+
+            if(user && user != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.user_id == user;
+                }));
+            }
+
+            if(customer && customer != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.customer_id == customer;
+                }));
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            var suma =0;
+             _.each(content,function(item){
+              suma = suma + item.amount
+            });
+            return [content,suma];
+        },
+
+        getAccountInvoice:function(partner_id) {
+            var self = this;
+            var content = _.filter(self.AccountInvoice,function(item){
+              return item.customer_id == partner_id;
+            });
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var type = self.$el.find('#current-type').val();
+            var sale_type = self.$el.find('#current-sale-type').val();
+            var user = self.$el.find('#current-user').val();
+            var customer = self.$el.find('#current-customer').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(state && state != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.state == state;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'tpv'){
+                    content = [];
+                }
+            }
+
+            if(sale_type && sale_type != 9999999){
+                if(sale_type == 'local'){
+                  content = _.flatten(_.filter(content,function (item) {
+                      return item.is_delivery == true && item.delivery_type == 'local';
+                  }));
+                }
+                if(sale_type == 'envio'){
+                  content = _.flatten(_.filter(content,function (item) {
+                      return item.is_delivery == true && item.delivery_type == 'envio';
+                  }));
+                }
+                if(sale_type == 'tienda'){
+                  content = _.flatten(_.filter(content,function (item) {
+                      return item.is_delivery != true;
+                  }));
+                }
+            }
+
+            if(user && user != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.user_id == user;
+                }));
+            }
+
+            if(customer && customer != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.customer_id == customer;
+                }));
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            var suma =0;
+             _.each(content,function(item){
+              suma = suma + item.amount
+            });
+            return [content,suma];
+        },
+
+        getStoreName:function(store_id){
+          var self = this;
+          var ResStore =  _.filter(self.ResStore,function (item) {
+                  return item.id == store_id;
+          });
+          return ResStore[0].name;
+        },
+
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+
+            var ResPartner = self.ResPartner;
+            _.each(ResPartner, function(partner){
+
+            var PosOrder = self.getPosOrder(partner.id);
+            var AccountInvoice = self.getAccountInvoice(partner.id);
+            var suma = PosOrder[1] + AccountInvoice[1];
+
+            _.each(PosOrder[0], function(item){
+
+                var utc = moment.utc(item.date,'YYYY-MM-DD h:mm:ss A');
+                data.push({
+                    id:item.id,
+                    store: self.getStoreName(item.store_id),
+                    origin:'',
+                    number:item.name,
+                    type: 'TPV',
+                    date:moment(utc._d).format('DD/MM/YYYY'),
+                    sale_type: 'Tienda',
+                    user_name:item.user_name,
+                    user_id:item.user_id,
+                    customer_ruc:self.valorNull(item.customer_ruc),
+                    customer_name:self.valorNull(item.customer_name),
+                    phone:self.valorNull(item.phone),
+                    mobile:self.valorNull(item.mobile),
+                    email:self.valorNull(item.email),
+                    pos:PosOrder[0].length,
+                    sale: AccountInvoice[0].length,
+                    total:accounting.formatMoney(item.amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    sale_amount:accounting.formatMoney(suma,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    ===========================
+                        NO FORMAT
+                    ===========================
+                    */
+                    date_no_format:moment(utc._d).format('YYYY-MM-DD'),
+                    total_no_format:item.amount,
+                    sale_amount_no_format: suma,
+                    /*
+                    ===========================
+                        FOOTER
+                    ===========================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+
+
+            _.each(AccountInvoice[0], function(item){
+              if(item.is_delivery == true){
+                if(item.delivery_type == 'envio'){
+                  var sale_type = 'Envío al exterior';
+                }
+                else {
+                  var sale_type = 'Delivery Local';
+                }
+              }
+              else {
+                var sale_type = 'Tienda';
+              }
+
+                data.push({
+                    id:item.id,
+                    store: self.getStoreName(item.store_id),
+                    supplier_invoice_number:self.valorNull(item.supplier_invoice_number),
+                    origin:item.origin,
+                    number:item.number,
+                    type:'Pedido de venta',
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    sale_type: sale_type,
+                    user_name:item.user_name,
+                    user_id:item.user_id,
+                    customer_ruc:self.valorNull(item.customer_ruc),
+                    customer_name:self.valorNull(item.customer_name),
+                    phone:self.valorNull(item.phone),
+                    mobile:self.valorNull(item.mobile),
+                    email:self.valorNull(item.email),
+                    pos: PosOrder[0].length,
+                    sale: AccountInvoice[0].length,
+                    total:accounting.formatMoney(item.amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    sale_amount: accounting.formatMoney(suma,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    total_no_format:item.amount,
+                    sale_amount_no_format: suma,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+
+              });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.ResCompany,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = CompanyLogo[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = TotalFooter(row);
+            var sale_amount = TotalSaleAmount(row);
+            row.push({
+                store:'Totales',
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Fidelización de Ventas.';
+                var pdf_type = 'l';
+                var pdf_name = 'fidelizacion_de_ventas_';
+                var pdf_columnStyles = {
+                    store:{halign:'left'},
+                    user_name:{ halign:'left'},
+                    date:{halign:'center'},
+                    type:{halign:'left'},
+                    number:{halign:'left'},
+                    supplier_invoice_number:{halign:'left'},
+                    origin:{ halign:'left'},
+                    customer_name:{ halign:'left'},
+                    customer_ruc:{ halign:'left'},
+                    phone:{ halign:'right'},
+                    mobile:{ halign:'right'},
+                    email:{ halign:'right'},
+                    total:{columnWidth: 22, halign:'right'},
+                    pos:{ halign:'center'},
+                    sale:{ halign:'center'},
+                    sale_amount:{columnWidth: 22, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new model.eiru_reports.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var user = self.$el.find('#current-user').val();
+            var customer = self.$el.find('#current-customer').val();
+            var state = self.$el.find('#current-state').val();
+            var type = self.$el.find('#current-type').val();
+            var sale_type = self.$el.find('#current-sale-type').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(user && user != 9999999){
+                var ResUser = _.filter(self.ResUsers, function(item){
+                    return item.id == user;
+                });
+                filter.push({
+                    title:'Vendedor',
+                    value: ResUser[0].name,
+                });
+            }
+            if(customer && customer != 9999999){
+                var ResPartner = _.filter(self.ResPartner, function(item){
+                    return item.id == customer;
+                });
+                filter.push({
+                    title:'Cliente',
+                    value: ResPartner[0].name,
+                });
+            }
+            if(state && state != 9999999){
+                filter.push({
+                    title: 'Estado',
+                    value: $('#current-state option:selected').text(),
+                });
+            }
+
+            if(type && type != 9999999){
+                filter.push({
+                    title: 'Tipo de Factura',
+                    value: $('#current-type option:selected').text(),
+                });
+            }
+
+            if(sale_type && sale_type != 9999999){
+                filter.push({
+                    title: 'Tipo de Venta',
+                    value: $('#current-sale-type option:selected').text(),
+                });
+            }
+
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 195 - 0
static/src/reports/report_ventas_fidelizacion.xml

@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportVentas">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Fidelización de Ventas </h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+
+                    <div class="col-lg-3 customer filter-style">
+                        <label>Cliente</label>
+                        <select id="current-customer" class="form-control form-control-sm">
+                        </select>
+                    </div>
+
+                    <div class="col-lg-3 user filter-style">
+                        <label>Vendedor</label>
+                        <select id="current-user" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Factura</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Tipos</option>
+                            <option value="tpv">Terminal</option>
+                            <option value="sale">Pedido de Venta</option>
+                        </select>
+                    </div>
+
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Venta</label>
+                        <select id="current-sale-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Tipos</option>
+                            <option value="local">Delivery Local</option>
+                            <option value="envio">Envío al Exterior</option>
+                            <option value="tienda">Tienda</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:100%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                              <th data-field="store" data-align="left" data-footer-formatter="Totales">Sucursal</th>
+                              <th data-field="user_name" data-align="left">Vendedor</th>
+                              <th data-field="date" data-align="center">Fecha</th>
+                              <th data-field="type" data-align="center">Tipo de factura</th>
+                              <th data-field="number" data-align="left">Factura</th>
+                              <th data-field="supplier_invoice_number" data-align="left" data-visible="false">Factura Física</th>
+                              <th data-field="origin" data-align="center" data-visible="false">Origen</th>
+                              <th data-field="customer_name" data-align="left">Cliente</th>
+                              <th data-field="customer_ruc" data-align="left">RUC</th>
+                              <th data-field="phone" data-align="left">Teléfono</th>
+                              <th data-field="mobile" data-align="left">Celular</th>
+                              <th data-field="email" data-align="left">Email</th>
+                              <th data-field="total" data-align="right" data-footer-formatter="TotalFooter">Total</th>
+                              <th data-field="sale_type" data-align="center">Tipo de venta</th>
+                              <th data-field="pos" data-align="center">TPV</th>
+                              <th data-field="sale" data-align="center">Ventas</th>
+                              <th data-field="sale_amount" data-align="right">Monto acumulado</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                function TotalSaleAmount(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.sale_amount_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 1 - 0
templates.xml

@@ -14,6 +14,7 @@
 
         <script type="text/javascript" src="/eiru_reports_baco/static/src/js/reports/report_product_ranking_baco.js"/>
         <script type="text/javascript" src="/eiru_reports_baco/static/src/js/reports/report_delivery_baco.js"/>
+        <script type="text/javascript" src="/eiru_reports_baco/static/src/js/reports/report_ventas_fidelizacion.js"/>
 
       </xpath>
     </template>

+ 5 - 0
views/actions.xml

@@ -12,5 +12,10 @@
 			<field name="name">Delivery por vendedor</field>
 			<field name="tag">eiru_reports_baco.delivery_action</field>
 		</record>
+
+		<record id="ventas_fidelizacion_action" model="ir.actions.client">
+			<field name="name">Fidelización de Ventas</field>
+			<field name="tag">eiru_reports_baco.ventas_fidelizacion_action</field>
+		</record>
 	</data>
 </openerp>

+ 1 - 0
views/menus.xml

@@ -8,6 +8,7 @@
 
     <menuitem id="product_ranking_baco_menu" parent="baco_parent_menu" name="Ranking de productos por categoría" action="product_ranking_baco_action" sequence="1"/>
     <menuitem id="delivery_menu" parent="baco_parent_menu" name="Delivery por vendedor" action="delivery_action" sequence="2"/>
+    <menuitem id="fidelizacion_menu" parent="baco_parent_menu" name="Fidelización de ventas" action="ventas_fidelizacion_action" sequence="3"/>
 
 
   </data>