From a9226e3d5bb4123842dd7baa352dedd24f94416f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 6 Feb 2014 15:05:24 +0100 Subject: [PATCH 01/28] [FIX] hw_scanner, hw_escpos: prevent driver threads from deadlocking when woken by two simultaneous requests bzr revid: fva@openerp.com-20140206140524-ur51ghcpdzwxv1yr --- addons/hw_escpos/controllers/main.py | 12 +++++++++--- addons/hw_scanner/controllers/main.py | 19 ++++++++++++------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index 52307318870..318f117456c 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -11,7 +11,7 @@ import math import md5 import openerp.addons.hw_proxy.controllers.main as hw_proxy import subprocess -from threading import Thread +from threading import Thread, Lock from Queue import Queue, Empty try: @@ -39,6 +39,7 @@ class EscposDriver(Thread): def __init__(self): Thread.__init__(self) self.queue = Queue() + self.lock = Lock() self.status = {'status':'connecting', 'messages':[]} def connected_usb_devices(self): @@ -47,6 +48,12 @@ class EscposDriver(Thread): if usb.core.find(idVendor=device['vendor'], idProduct=device['product']) != None: connected.append(device) return connected + + def lockedstart(self): + self.lock.acquire() + if not self.isAlive(): + self.start() + self.lock.release() def get_escpos_printer(self): try: @@ -113,8 +120,7 @@ class EscposDriver(Thread): _logger.error(e); def push_task(self,task, data = None): - if not self.isAlive(): - self.start() + self.lockedstart() self.queue.put((time.time(),task,data)) def print_receipt_body(self,eprint,receipt): diff --git a/addons/hw_scanner/controllers/main.py b/addons/hw_scanner/controllers/main.py index 105856a3e28..8fbdae62db6 100644 --- a/addons/hw_scanner/controllers/main.py +++ b/addons/hw_scanner/controllers/main.py @@ -4,7 +4,7 @@ import os import time from os import listdir from os.path import join -from threading import Thread +from threading import Thread, Lock from select import select from Queue import Queue, Empty @@ -26,6 +26,7 @@ except ImportError: class Scanner(Thread): def __init__(self): Thread.__init__(self) + self.lock = Lock() self.status = {'status':'connecting', 'messages':[]} self.input_dir = '/dev/input/by-id/' self.barcodes = Queue() @@ -86,6 +87,12 @@ class Scanner(Thread): 57:(" "," "), } + def lockedstart(self): + self.lock.acquire() + if not self.isAlive(): + self.start() + self.lock.release() + def set_status(self, status, message = None): if status == self.status['status']: if message != None and message != self.status['messages'][-1]: @@ -102,8 +109,6 @@ class Scanner(Thread): elif status == 'disconnected' and message: _logger.warning('Disconnected Barcode Scanner: '+message) - - def get_device(self): try: if not evdev: @@ -135,6 +140,8 @@ class Scanner(Thread): busy reading another barcode """ + self.lockedstart() + while True: try: timestamp, barcode = self.barcodes.get(True, 5) @@ -144,8 +151,7 @@ class Scanner(Thread): return '' def get_status(self): - if not s.isAlive(): - s.start() + self.lockedstart() return self.status def run(self): @@ -209,7 +215,6 @@ hw_proxy.drivers['scanner'] = s class ScannerDriver(hw_proxy.Proxy): @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') def scanner(self): - if not s.isAlive(): - s.start() return s.get_barcode() + From ec4dd7389bb5e4b6d6613dcd9cce47a41382d56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 6 Feb 2014 15:06:45 +0100 Subject: [PATCH 02/28] [IMP] point_of_sale: try harder to connect to proxy when the ip is already known bzr revid: fva@openerp.com-20140206140645-uo82x3tf60wlhytj --- addons/point_of_sale/static/src/js/devices.js | 144 +++++++++++------- 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 8eb32d63873..683cfaeb08b 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -162,25 +162,37 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal }, // find a proxy and connects to it. for options see find_proxy + // - force_ip : only try to connect to the specified ip. + // - port: what port to listen to (default 8069) + // - progress(fac) : callback for search progress ( fac in [0,1] ) autoconnect: function(options){ var self = this; this.set_connection_status('connecting',{}); + var found_url = new $.Deferred(); var success = new $.Deferred(); - this.find_proxy(options) - .then(function(proxies){ - if(proxies.length > 0){ - self.connect(proxies[0]) - .then(function(){ - success.resolve(); - },function(){ - self.set_connection_status('disconnected'); - success.reject(); - }); - }else{ - self.set_connection_status('disconnected'); - success.reject(); - } + + if ( options.force_ip ){ + // if the ip is forced by server config, bailout on fail + found_url = this.try_hard_to_connect(options.force_ip, options) + }else if( localStorage['hw_proxy_url'] ){ + // try harder when we remember a good proxy url + found_url = this.try_hard_to_connect(localStorage['hw_proxy_url'], options) + .then(null,function(){ + return self.find_proxy(options); + }); + }else{ + // just find something quick + found_url = this.find_proxy(options); + } + + success = found_url.then(function(url){ + return self.connect(url); }); + + success.fail(function(){ + self.set_connection_status('disconnected'); + }); + return success; }, @@ -217,10 +229,50 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } }, - // returns as a deferred a list of valid hosts urls that can be used as proxy. + // try several time to connect to a known proxy url + try_hard_to_connect: function(url,options){ + options = options || {}; + var port = ':' + (options.port || '8069'); + + this.set_connection_status('connecting'); + + if(url.indexOf('//') < 0){ + url = 'http://'+url; + } + + if(url.indexOf(':',5) < 0){ + url = url+port; + } + + // try real hard to connect to url, with a 1sec timeout and up to 'retries' retries + function try_real_hard_to_connect(url, retries, done){ + + done = done || new $.Deferred(); + + var c = $.ajax({ + url: url + '/hw_proxy/hello', + method: 'GET', + timeout: 1000, + }) + .done(function(){ + done.resolve(url); + }) + .fail(function(){ + if(retries > 0){ + try_real_hard_to_connect(url,retries-1,done); + }else{ + done.reject(); + } + }); + return done; + } + + return try_real_hard_to_connect(url,3); + }, + + // returns as a deferred a valid host url that can be used as proxy. // options: // - port: what port to listen to (default 8069) - // - force_ip : limit the search to the specified ip // - progress(fac) : callback for search progress ( fac in [0,1] ) find_proxy: function(options){ options = options || {}; @@ -228,36 +280,17 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal var port = ':' + (options.port || '8069'); var urls = []; var found = false; - var proxies = []; - var done = new $.Deferred(); var parallel = 8; + var done = new $.Deferred(); // will be resolved with the proxies valid urls var threads = []; var progress = 0; - this.set_connection_status('connecting'); - if(options.force_ip){ - var url = options.force_ip; - if(url.indexOf('//') < 0){ - url = 'http://'+url; - } - if(url.indexOf(':',5) < 0){ - url = url+port; - } - urls.push(url); - }else{ - if(localStorage['hw_proxy_url']){ - urls.push(localStorage['hw_proxy_url']); - } - - urls.push('http://localhost'+port); - - for(var i = 0; i < 256; i++){ - urls.push('http://192.168.0.'+i+port); - urls.push('http://192.168.1.'+i+port); - urls.push('http://192.168.2.'+i+port); - urls.push('http://10.0.0.'+i+port); - } + urls.push('http://localhost'+port); + for(var i = 0; i < 256; i++){ + urls.push('http://192.168.0.'+i+port); + urls.push('http://192.168.1.'+i+port); + urls.push('http://10.0.0.'+i+port); } var prog_inc = 1/urls.length; @@ -269,40 +302,39 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } } - function thread(url,done){ - if(!url){ + function thread(done){ + var url = urls.shift(); + + done = done || new $.Deferred(); + + if( !url || found || !self.searching_for_proxy ){ done.resolve(); + return done; } + var c = $.ajax({ url: url + '/hw_proxy/hello', method: 'GET', - timeout: 300, + timeout: 400, }).done(function(){ found = true; update_progress(); - proxies.push(url); done.resolve(url); }) .fail(function(){ update_progress(); - var next_url = urls.shift(); - if(found ||! self.searching_for_proxy || !next_url){ - done.resolve(); - }else{ - thread(next_url,done); - } + thread(done); }); + return done; } this.searching_for_proxy = true; - for(var i = 0; i < Math.min(parallel,urls.length); i++){ - threads.push(thread(urls.shift(),new $.Deferred())); + for(var i = 0, len = Math.min(parallel,urls.length); i < len; i++){ + threads.push(thread()); } - var done = new $.Deferred(); - $.when.apply($,threads).then(function(){ var urls = []; for(var i = 0; i < arguments.length; i++){ @@ -310,7 +342,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal urls.push(arguments[i]); } } - done.resolve(urls); + done.resolve(urls[0]); }); return done; From 008e3c1ab01ced4302a648c2ff55ac8a209898be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 6 Feb 2014 15:36:48 +0100 Subject: [PATCH 03/28] [FIX] point_of_sale: receipt header & footer could overflow outside of ticket bzr revid: fva@openerp.com-20140206143648-z1bsknelzznf0jqj --- addons/point_of_sale/static/src/xml/pos.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 748fcbfee1b..d0cd945d4f4 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -635,9 +635,9 @@ Shop:

-
+                
-
+
@@ -711,9 +711,9 @@

-
+                
-
+
From a78af30755bab161e07330a552e3495b0a751e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 6 Feb 2014 16:14:32 +0100 Subject: [PATCH 04/28] [FIX] hw_escpos: company logo was not centered on the first receipt bzr revid: fva@openerp.com-20140206151432-avaz87emjzqyvu9t --- addons/hw_escpos/controllers/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index 318f117456c..b7b254d4bd5 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -163,6 +163,7 @@ class EscposDriver(Thread): # Receipt Header if receipt['company']['logo']: + eprint.set(align='center') eprint.print_base64_image(receipt['company']['logo']) eprint.text('\n') else: From 04301f3b1eb5b21e2b1d95901ae7db263e7b830a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 7 Feb 2014 14:50:38 +0100 Subject: [PATCH 05/28] [FIX] correct various actions in kanban view in sales team: now the user can go to the various reporting view in graph view (addons crm/sale_crm) bzr revid: ged@openerp.com-20140207135038-6tx5ywxxdxywn8cb --- addons/crm/crm_case_section_view.xml | 12 ++++++------ addons/crm/report/crm_lead_report_view.xml | 2 +- addons/sale_crm/sale_crm_view.xml | 9 +++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index bc066db0a7a..c98be7c7cbc 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -65,9 +65,9 @@ Leads Analysis crm.lead.report - form - {"search_default_month":1} - tree,graph + + {"search_default_month":1, "col_group_by":["user_id"]} + graph [('type','=', 'lead'),('section_id', '=', active_id)] Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis. @@ -75,9 +75,9 @@ Opportunities Analysis crm.lead.report - form - {"search_default_month":1} - tree,graph + + {"search_default_month":1, "col_group_by":["user_id"]} + graph [('type','=', 'opportunity'), ('section_id', '=', active_id)] Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline. diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml index f25cfa1f4b1..e4fc55425f2 100644 --- a/addons/crm/report/crm_lead_report_view.xml +++ b/addons/crm/report/crm_lead_report_view.xml @@ -84,7 +84,7 @@ + domain="[]" context="{'group_by':'create_date:month'}" name="month"/> diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml index 8c3c98c3f97..06057e256c4 100644 --- a/addons/sale_crm/sale_crm_view.xml +++ b/addons/sale_crm/sale_crm_view.xml @@ -214,8 +214,7 @@ Quotations Analysis sale.report - form - tree,graph + graph [('state','=','draft'),('section_id', '=', active_id)] {'search_default_order_month':1} This report performs analysis on your quotations. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application. @@ -224,8 +223,7 @@ Sales Analysis sale.report - form - tree,graph + graph [('state','not in',('draft','sent','cancel')),('section_id', '=', active_id)] {'search_default_order_month':1} This report performs analysis on your sales orders. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application. @@ -234,8 +232,7 @@ Invoices Analysis account.invoice.report - form - tree,graph + graph [('section_id', '=', active_id),('state', 'not in', ['draft', 'cancel'])] {'search_default_month':1} From this report, you can have an overview of the amount invoiced to your customer. The tool search can also be used to personalise your Invoices reports and so, match this analysis to your needs. From ab9300e995b7378068ff0129c12871df87e5c7a6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 7 Feb 2014 14:51:34 +0100 Subject: [PATCH 06/28] [REF] removes some useless lines that should have been removed earlier when reworking the reporting views in addon crm bzr revid: ged@openerp.com-20140207135134-wqklenfb1qarwv63 --- addons/crm/report/crm_lead_report.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/crm/report/crm_lead_report.py b/addons/crm/report/crm_lead_report.py index 871bef2099d..3a0786da5c7 100644 --- a/addons/crm/report/crm_lead_report.py +++ b/addons/crm/report/crm_lead_report.py @@ -89,10 +89,6 @@ class crm_lead_report(osv.osv): id, c.date_deadline, - to_char(c.create_date, 'YYYY') as creation_year, - to_char(c.create_date, 'MM') as creation_month, - to_char(c.create_date, 'YYYY-MM-DD') as creation_day, - to_char(c.date_open, 'YYYY-MM-DD') as opening_date, to_char(c.date_closed, 'YYYY-mm-dd') as date_closed, From 88b7511f6883ed42e113f818449fb2fa61c9c40b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 7 Feb 2014 14:53:39 +0100 Subject: [PATCH 07/28] [FIX] correctly use the col group by instead of groupby when reading the context and initializing a graph view (addon web_graph) bzr revid: ged@openerp.com-20140207135339-ohrjh6uvu22tjavh --- addons/web_graph/static/src/js/graph_view.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index e1a50d4ff6d..b39ac105ee4 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -50,7 +50,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ var field_name = field.attrs.name; if (_.has(field.attrs, 'interval')) { field_name = field.attrs.name + ':' + field.attrs.interval; - } + } if (_.has(field.attrs, 'type')) { switch (field.attrs.type) { case 'row': @@ -78,14 +78,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_group_by = context.col_group_by || this.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); + col_group_by = this.extract_groupby('col_group_by', context) || []; if (!this.graph_widget) { if (group_by.length) { this.widget_config.row_groupby = group_by; } if (col_group_by.length) { - this.widget_config.col_groupby = group_by; + this.widget_config.col_groupby = col_group_by; } this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); @@ -101,16 +101,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget.set(domain, group_by, col_group_by); }, + extract_groupby: function (cat_field, context) { + context = (_.isString(context)) ? py.eval(context) : context; + return context[cat_field]; + }, + get_groupbys_from_searchview: function (cat_name, cat_field) { - var facet = this.search_view.query.findWhere({category:cat_name}), + var self=this, + facet = this.search_view.query.findWhere({category:cat_name}), groupby_list = facet ? facet.values.models : []; return _.map(groupby_list, function (g) { var context = g.attributes.value.attrs.context; - if (_.isString(context)) { - return py.eval(context).group_by; - } else { - return context[cat_field]; - } + return self.extract_groupby(cat_field, context); }); }, From 817b9bdb7f6356c2db3a97ab9bc9c63e59ebd261 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 7 Feb 2014 15:22:23 +0100 Subject: [PATCH 08/28] [IMP] removes the 'expand all' buttons, it was confusing and not really useful (addon web_graph) bzr revid: ged@openerp.com-20140207142223-pc31xwv7kckt99a0 --- addons/web_graph/static/src/js/graph_widget.js | 3 --- addons/web_graph/static/src/xml/web_graph.xml | 3 --- 2 files changed, 6 deletions(-) diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index ef547e22632..881be188595 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -258,9 +258,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ case 'swap_axis': this.swap_axis(); break; - case 'expand_all': - this.pivot.expand_all().then(this.proxy('display_data')); - break; case 'update_values': this.pivot.update_data().then(this.proxy('display_data')); break; diff --git a/addons/web_graph/static/src/xml/web_graph.xml b/addons/web_graph/static/src/xml/web_graph.xml index deb34e3d8a8..eb0fb651d9b 100644 --- a/addons/web_graph/static/src/xml/web_graph.xml +++ b/addons/web_graph/static/src/xml/web_graph.xml @@ -35,9 +35,6 @@ - From 356010c3575316fc1dff0dfeb4d1038f9c399f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 7 Feb 2014 17:16:47 +0100 Subject: [PATCH 09/28] [FIX] point_of_sale: totals were not rendrered on firefox due to use of nonstandard innerText dom property bzr revid: fva@openerp.com-20140207161647-rgeymwt4ksei2cod --- addons/point_of_sale/static/src/js/widgets.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index f2a254593d1..a2f0759d1a1 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -258,8 +258,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa var total = order ? order.getTotalTaxIncluded() : 0; var taxes = order ? total - order.getTotalTaxExcluded() : 0; - this.el.querySelector('.summary .total > .value').innerText = this.format_currency(total); - this.el.querySelector('.summary .total .subentry .value').innerText = this.format_currency(taxes); + this.el.querySelector('.summary .total > .value').textContent = this.format_currency(total); + this.el.querySelector('.summary .total .subentry .value').textContent = this.format_currency(taxes); }, }); From f4bbf7b5d4cda7825fc21b6175b6c11cf030ec19 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 10:17:16 +0100 Subject: [PATCH 10/28] [FIX] fixes an issue in graph view (addon web_graph) when the user clicked several times on a field name to expand it, the dropdown menu was displayed several times, overlapping, instead of being reset to the last click location bzr revid: ged@openerp.com-20140210091716-of9w9xhjnpmaa5td --- .../web_graph/static/src/js/graph_widget.js | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 881be188595..26f479790df 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -284,25 +284,30 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ if (header.expanded) { this.fold(header); - } else { - if (header.path.length < header.root.groupby.length) { - this.expand(id); - } else { - if (!this.important_fields.length) { - return; - } - - var fields = _.map(this.important_fields, function (field) { - return {id: field.field, value: field.string, type:self.fields[field.field.split(':')[0]].type}; - }); - this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); - $(event.target).after(this.dropdown); - this.dropdown.css({position:'absolute', - left:event.pageX, - top:event.pageY}); - this.$('.field-selection').next('.dropdown-menu').toggle(); - } + return; + } + if (header.path.length < header.root.groupby.length) { + this.expand(id); + return; + } + if (!this.important_fields.length) { + return; } + + var fields = _.map(this.important_fields, function (field) { + return {id: field.field, value: field.string, type:self.fields[field.field.split(':')[0]].type}; + }); + if (this.dropdown) { + this.dropdown.remove(); + } + this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); + $(event.target).after(this.dropdown); + this.dropdown.css({position:'absolute', + left:event.pageX, + top:event.pageY}); + this.$('.field-selection').next('.dropdown-menu').toggle(); + + }, field_selection: function (event) { From ff89abba855a2348aec2bd00714bf5adda2565fe Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 11:04:39 +0100 Subject: [PATCH 11/28] [FIX] correctly displays tooltips in sales/sales team (they previously were cut in half by incorrect padding) (addon web) bzr revid: ged@openerp.com-20140210100439-icqps10dvtdhlvv0 --- addons/web/static/src/css/base.css | 12 +++++++----- addons/web/static/src/css/base.sass | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 6b568f8846e..bf9362a1e09 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -2142,7 +2142,7 @@ } .openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span { font-size: 80%; - color: darkGreen; + color: darkgreen; vertical-align: top; position: relative; top: -4px; @@ -3138,10 +3138,6 @@ border: none; padding: 10px 0 3px 0; } -.openerp .jqstooltip { - height: auto !important; - width: auto !important; -} .openerp h5 { font-weight: bold; font-size: smaller; @@ -3153,6 +3149,12 @@ margin: 3px 3px 0 !important; } +.jqstooltip { + height: auto !important; + width: auto !important; + padding: 0; +} + @-moz-document url-prefix() { .openerp .oe_searchview .oe_searchview_search { top: -1px; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 5bb2bb9b448..c79deecddb5 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -2517,10 +2517,7 @@ $sheet-padding: 16px border: none padding: 10px 0 3px 0 - // Customize for kanban tooltip - .jqstooltip - height: auto !important - width: auto !important + // Customize for chatter h5 @@ -2531,7 +2528,12 @@ $sheet-padding: 16px .oe_msg_subtype_check margin: 3px 3px 0 !important // }}} - +// Customize for kanban tooltip +.jqstooltip + height: auto !important + width: auto !important + padding: 0 + @-moz-document url-prefix() .openerp .oe_searchview .oe_searchview_search From 9eda870d2b8bad1d2c480a9a54eb7264ce4df183 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 12:23:13 +0100 Subject: [PATCH 12/28] [FIX] fixes a bug caused by two consecutive calls to do_search, with incomplete informations in the first call. These calls then triggered useless queries and caused an incorrect (but brief) display of partial information in graph view (addon web_graph) bzr revid: ged@openerp.com-20140210112313-z9elwhmjil41jcd2 --- addons/web_graph/static/src/js/graph_view.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index b39ac105ee4..33b99b88bcf 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -77,6 +77,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { + if (this.ignore_do_search) { + this.ignore_do_search = false; + return; + } + var self = this, col_group_by = this.extract_groupby('col_group_by', context) || []; @@ -131,6 +136,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (!_.has(this.search_view, '_s_groupby')) { return; } + if (row_groupby.length && col_groupby.length) { + // when two changes to the search view will be done, the method do_search + // will be called twice, once with the correct groupby and incorrect col_groupby, + // and once with correct informations. This flag is necessary to prevent the + // incorrect informations to propagate and trigger useless queries + this.ignore_do_search = true; + } + // add row groupbys var row_facet = this.make_row_groupby_facets(row_groupby), row_search_facet = query.findWhere({category:'GroupBy'}); From 450b9b647d151f7db66b6b6a838cf486a17c74d1 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 13:20:46 +0100 Subject: [PATCH 13/28] [FIX] forces the kanban view in sales/sales team to take the correct reporting view when clicking on those small sparklines (on leads and on opportunities) (addon crm) bzr revid: ged@openerp.com-20140210122046-o5albh9m7jhoylf2 --- addons/crm/crm_case_section_view.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index c98be7c7cbc..2d9a8cef6cc 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -68,6 +68,7 @@ {"search_default_month":1, "col_group_by":["user_id"]} graph + [('type','=', 'lead'),('section_id', '=', active_id)] Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis. @@ -78,6 +79,7 @@ {"search_default_month":1, "col_group_by":["user_id"]} graph + [('type','=', 'opportunity'), ('section_id', '=', active_id)] Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline. From d930115bd398c269a1071679ebb04b68eaff9476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 10 Feb 2014 14:31:09 +0100 Subject: [PATCH 14/28] [IMP] hw_escpos: print a status receipt on printer connection with ip address for easier configuration & debugging. Also setting the driver thread in daemon mode to avoid hanging the tests on the runbot bzr revid: fva@openerp.com-20140210133109-xll1ijjdhbgpj1kr --- addons/hw_escpos/controllers/main.py | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index b7b254d4bd5..c2e777fcd3a 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import commands import logging import simplejson import os @@ -52,6 +53,7 @@ class EscposDriver(Thread): def lockedstart(self): self.lock.acquire() if not self.isAlive(): + self.daemon = True self.start() self.lock.release() @@ -112,6 +114,8 @@ class EscposDriver(Thread): elif task == 'cashbox': if timestamp >= time.time() - 12: self.open_cashbox(printer) + elif task == 'printstatus': + self.print_status(printer) elif task == 'status': pass @@ -123,6 +127,28 @@ class EscposDriver(Thread): self.lockedstart() self.queue.put((time.time(),task,data)) + def print_status(self,eprint): + localips = ['0.0.0.0','127.0.0.1','127.0.1.1'] + ips = [ c.split(':')[1].split(' ')[0] for c in commands.getoutput("/sbin/ifconfig").split('\n') if 'inet addr' in c ] + ips = [ ip for ip in ips if ip not in localips ] + eprint.text('\n\n') + eprint.set(align='center',type='b',height=2,width=2) + eprint.text('PosBox Status\n') + eprint.text('\n') + eprint.set(align='center') + + if len(ips) == 0: + eprint.text('ERROR: Could not connect to LAN\n\nPlease check that the PosBox is correc-\ntly connected with a network cable,\n that the LAN is setup with DHCP, and\nthat network addresses are available') + elif len(ips) == 1: + eprint.text('IP Address\n'+ips[0]+'\n') + else: + eprint.text('IP Addresses\n') + for ip in ips: + eprint.text(ip+'\n') + + eprint.text('\n\n') + eprint.cut() + def print_receipt_body(self,eprint,receipt): def check(string): @@ -140,7 +166,6 @@ class EscposDriver(Thread): else: return str(amount) - def printline(left, right='', width=40, ratio=0.5, indent=0): lwidth = int(width * ratio) rwidth = width - lwidth @@ -252,6 +277,8 @@ class EscposDriver(Thread): driver = EscposDriver() hw_proxy.drivers['escpos'] = driver + +driver.push_task('printstatus') class EscposProxy(hw_proxy.Proxy): From 321a4a74027364f709a9830faeba4d5a70a814fe Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 16:32:21 +0100 Subject: [PATCH 15/28] [FIX] make sure the graph view takes the col_group_by from the search view and not from the context. It was taken from the context, and had the unfortunate side effect that the user could not ungroup by removing the facet from the search view. (addon web_graph) bzr revid: ged@openerp.com-20140210153221-olkv8xee02r9voer --- addons/web_graph/static/src/js/graph_view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 33b99b88bcf..ace2f14ae20 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -83,7 +83,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } var self = this, - col_group_by = this.extract_groupby('col_group_by', context) || []; + col_group_by = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); if (!this.graph_widget) { if (group_by.length) { From 7be15dabaa6d1863adcadb9be85fe6cd3eadf6fc Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 16:34:53 +0100 Subject: [PATCH 16/28] [FIX] corrects an interesting bug, caused by datetime in UTC and GMT, then string formatting, causing incorrect information to display in the sales team screen (addon crm.py) bzr revid: ged@openerp.com-20140210153453-y0mtvs0mnpm1e4e1 --- addons/crm/crm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 28b8469580e..910086735a1 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -120,14 +120,14 @@ class crm_case_section(osv.osv): month_begin = date.today().replace(day=1) section_result = [{ 'value': 0, - 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B'), + 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B %Y'), } for i in range(self._period_number - 1, -1, -1)] group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context) pattern = tools.DEFAULT_SERVER_DATE_FORMAT if obj.fields_get(cr, uid, groupby_field)[groupby_field]['type'] == 'date' else tools.DEFAULT_SERVER_DATETIME_FORMAT for group in group_obj: group_begin_date = datetime.strptime(group['__domain'][0][2], pattern) month_delta = relativedelta.relativedelta(month_begin, group_begin_date) - section_result[self._period_number - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group_begin_date.strftime('%B')} + section_result[self._period_number - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group.get(groupby_field, 0)} return section_result def _get_opportunities_data(self, cr, uid, ids, field_name, arg, context=None): From 08e8a2547ae617c47c9e94c9fdf48130506233d8 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 16:38:08 +0100 Subject: [PATCH 17/28] [IMP] improves some reporting views in CRM (accessed from the sales team screen) (addon crm) bzr revid: ged@openerp.com-20140210153808-3iwrihu7a28vca1y --- addons/crm/crm_case_section_view.xml | 9 +++------ addons/crm/report/crm_lead_report_view.xml | 13 ++++++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index 2d9a8cef6cc..eb84b5e72ce 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -65,10 +65,9 @@ Leads Analysis crm.lead.report - - {"search_default_month":1, "col_group_by":["user_id"]} + {"search_default_month":1} graph - + [('type','=', 'lead'),('section_id', '=', active_id)] Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis. @@ -76,10 +75,8 @@ Opportunities Analysis crm.lead.report - - {"search_default_month":1, "col_group_by":["user_id"]} graph - + [('type','=', 'opportunity'), ('section_id', '=', active_id)] Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline. diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml index e4fc55425f2..c4cffdc012a 100644 --- a/addons/crm/report/crm_lead_report_view.xml +++ b/addons/crm/report/crm_lead_report_view.xml @@ -15,6 +15,17 @@ + + crm.lead.report.graph.two + crm.lead.report + + + + + + + + crm.opportunity.report.graph crm.lead.report @@ -23,7 +34,7 @@ - + From 7d1ba3329c1e4d06b46007d109ffe31a5ca1be39 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 11 Feb 2014 10:59:33 +0100 Subject: [PATCH 18/28] [FIX] website: contactus: address of the company above the phone, typo edit button bzr revid: chm@openerp.com-20140211095933-s712ssydrv1d54nq --- addons/website/views/website_templates.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 9073ccb7a4a..d43d8c45443 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -673,10 +673,9 @@ Sitemap: sitemap.xml