From 4cc01a34e4c56939992ab9ceee21e295d54273e1 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 7 Jun 2016 17:30:17 +0200 Subject: [PATCH 01/70] [FIX] website_portal_sale: prevent overlap In the website portal summary ('/my/home'), a long invoice number might overlap the date. opw-677567 --- .../static/src/less/website_portal_sale.less | 7 +++++-- addons/website_portal_sale/views/templates.xml | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/addons/website_portal_sale/static/src/less/website_portal_sale.less b/addons/website_portal_sale/static/src/less/website_portal_sale.less index 5e8b9302f10..dfdc8ec75f2 100644 --- a/addons/website_portal_sale/static/src/less/website_portal_sale.less +++ b/addons/website_portal_sale/static/src/less/website_portal_sale.less @@ -5,7 +5,10 @@ align-items: center; } - .orders_label_text_align { vertical-align: 15%; -} \ No newline at end of file +} + +.cell_overflow { + overflow: hidden; +} diff --git a/addons/website_portal_sale/views/templates.xml b/addons/website_portal_sale/views/templates.xml index 25c88200800..04c82fe7f41 100644 --- a/addons/website_portal_sale/views/templates.xml +++ b/addons/website_portal_sale/views/templates.xml @@ -115,8 +115,8 @@ - - + + From fe99c51703c3a1aaa4cb5cfd88c45525b6330c3f Mon Sep 17 00:00:00 2001 From: Joren Van Onder Date: Tue, 7 Jun 2016 14:22:05 +0200 Subject: [PATCH 02/70] [IMP] hw_scanner: support multiple simultaneously attached devices The hw_scanner module not only supports barcode readers (although that was it's original intention). It also happens to support certain card readers (like the MagTek Dynamag we use for Mercury) because they act the same way as barcode scanners (like a keyboard and end sequence with ENTER). Before we supported Mercury there was no real reason to support multiple devices on the POSBox, because it didn't make much sense to attach >1 barcode reader to the same POSBox. With Mercury however, this is a real use case, as users want both a barcode reader and a card reader. This commit implements support for this, while keeping the functionality as close as possible to how it was before (eg. care was taken to not break plug and play support). --- addons/hw_scanner/controllers/main.py | 111 +++++++++++++++----------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/addons/hw_scanner/controllers/main.py b/addons/hw_scanner/controllers/main.py index 8e5e8f6af18..ad0f47a2cda 100644 --- a/addons/hw_scanner/controllers/main.py +++ b/addons/hw_scanner/controllers/main.py @@ -22,6 +22,13 @@ except ImportError: _logger.error('Odoo module hw_scanner depends on the evdev python module') evdev = None +class ScannerDevice(): + def __init__(self, path): + self.evdev = evdev.InputDevice(path) + self.evdev.grab() + + self.barcode = [] + self.shift = False class Scanner(Thread): def __init__(self): @@ -29,6 +36,7 @@ class Scanner(Thread): self.lock = Lock() self.status = {'status':'connecting', 'messages':[]} self.input_dir = '/dev/input/by-id/' + self.open_devices = [] self.barcodes = Queue() self.keymap = { 2: ("1","!"), @@ -109,25 +117,33 @@ class Scanner(Thread): elif status == 'disconnected' and message: _logger.info('Disconnected Barcode Scanner: %s', message) - def get_device(self): + def get_devices(self): try: if not evdev: return None - devices = [ device for device in listdir(self.input_dir)] - keyboards = [ device for device in devices if ('kbd' in device) and ('keyboard' not in device.lower())] - scanners = [ device for device in devices if ('barcode' in device.lower()) or ('scanner' in device.lower())] - if len(scanners) > 0: - self.set_status('connected','Connected to '+scanners[0]) - return evdev.InputDevice(join(self.input_dir,scanners[0])) - elif len(keyboards) > 0: - self.set_status('connected','Connected to '+keyboards[0]) - return evdev.InputDevice(join(self.input_dir,keyboards[0])) + + new_devices = [device for device in listdir(self.input_dir) + if join(self.input_dir, device) not in [dev.evdev.fn for dev in self.open_devices]] + scanners = [device for device in new_devices + if (('kbd' in device) and ('keyboard' not in device.lower())) + or ('barcode' in device.lower()) or ('scanner' in device.lower())] + + for device in scanners: + _logger.debug('opening device %s', join(self.input_dir,device)) + self.open_devices.append(ScannerDevice(join(self.input_dir,device))) + + if self.open_devices: + self.set_status('connected','Connected to '+ str([dev.evdev.name for dev in self.open_devices])) else: self.set_status('disconnected','Barcode Scanner Not Found') - return None + + return self.open_devices except Exception as e: self.set_status('error',str(e)) - return None + return [] + + def release_device(self, dev): + self.open_devices.remove(dev) def get_barcode(self): """ Returns a scanned barcode. Will wait at most 5 seconds to get a barcode, and will @@ -150,6 +166,11 @@ class Scanner(Thread): self.lockedstart() return self.status + def _get_open_device_by_fd(self, fd): + for dev in self.open_devices: + if dev.evdev.fd == fd: + return dev + def run(self): """ This will start a loop that catches all keyboard events, parse barcode sequences and put them on a timestamped queue that can be consumed by @@ -160,49 +181,45 @@ class Scanner(Thread): barcode = [] shift = False - device = None + devices = None while True: # barcodes loop - if device: # ungrab device between barcodes and timeouts for plug & play - try: - device.ungrab() - except Exception as e: - device = None - self.set_status('error',str(e)) - else: - time.sleep(5) # wait until a suitable device is plugged - device = self.get_device() - if not device: - continue + devices = self.get_devices() try: - device.grab() - shift = False - barcode = [] - while True: # keycode loop - r,w,x = select([device],[],[],5) + r,w,x = select({dev.fd: dev for dev in [d.evdev for d in devices]},[],[],5) if len(r) == 0: # timeout break - events = device.read() - for event in events: - if event.type == evdev.ecodes.EV_KEY: - #_logger.debug('Evdev Keyboard event %s',evdev.categorize(event)) - if event.value == 1: # keydown events - if event.code in self.keymap: - if shift: - barcode.append(self.keymap[event.code][1]) - else: - barcode.append(self.keymap[event.code][0]) - elif event.code == 42 or event.code == 54: # SHIFT - shift = True - elif event.code == 28: # ENTER, end of barcode - self.barcodes.put( (time.time(),''.join(barcode)) ) - barcode = [] - elif event.value == 0: #keyup events - if event.code == 42 or event.code == 54: # LEFT SHIFT - shift = False + for fd in r: + device = self._get_open_device_by_fd(fd) + + if not evdev.util.is_device(device.evdev.fn): + _logger.info('%s disconnected', str(device.evdev)) + self.release_device(device) + break + + events = device.evdev.read() + + for event in events: + if event.type == evdev.ecodes.EV_KEY: + # _logger.debug('Evdev Keyboard event %s',evdev.categorize(event)) + if event.value == 1: # keydown events + if event.code in self.keymap: + if device.shift: + device.barcode.append(self.keymap[event.code][1]) + else: + device.barcode.append(self.keymap[event.code][0]) + elif event.code == 42 or event.code == 54: # SHIFT + device.shift = True + elif event.code == 28: # ENTER, end of barcode + _logger.debug('pushing barcode %s from %s', ''.join(device.barcode), str(device.evdev)) + self.barcodes.put( (time.time(),''.join(device.barcode)) ) + device.barcode = [] + elif event.value == 0: #keyup events + if event.code == 42 or event.code == 54: # LEFT SHIFT + device.shift = False except Exception as e: self.set_status('error',str(e)) From f307e36e66c53f89eee1ac0dfdd691518abacc91 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 8 Jun 2016 10:57:21 +0200 Subject: [PATCH 03/70] [FIX] base_import: disable tracking during validation Force the value tracking_disable to be make sure that the validation (which is supposed to have no impact), will not send any email. Fixes #3173 --- addons/base_import/static/src/js/import.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/base_import/static/src/js/import.js b/addons/base_import/static/src/js/import.js index 0ee88e0a203..916605d699c 100644 --- a/addons/base_import/static/src/js/import.js +++ b/addons/base_import/static/src/js/import.js @@ -363,9 +363,11 @@ openerp.base_import = function (instance) { var fields = this.$('.oe_import_fields input.oe_import_match_field').map(function (index, el) { return $(el).select2('val') || false; }).get(); + var tracking_disable = 'tracking_disable' in kwargs ? kwargs.tracking_disable : !this.$('#oe_import_tracking').prop('checked') + delete kwargs.tracking_disable kwargs.context = _.extend( {}, this.parent_context, - {tracking_disable: !this.$('#oe_import_tracking').prop('checked')} + {tracking_disable: tracking_disable} ); return this.Import.call('do', [this.id, fields, this.import_options()], kwargs) .then(undefined, function (error, event) { @@ -381,7 +383,7 @@ openerp.base_import = function (instance) { }) ; }, onvalidate: function () { - return this.call_import({ dryrun: true }) + return this.call_import({ dryrun: true, tracking_disable: true }) .done(this.proxy('validated')); }, onimport: function () { From d0d3ba921d0d20fb9ea3e7053eb70d94b61f1892 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 8 Jun 2016 10:08:27 +0200 Subject: [PATCH 04/70] [FIX] website_quote: delay in SO line When creating an SO line with a quotation template, the customer lead time must be set. opw:678039 --- addons/website_quote/models/order.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/website_quote/models/order.py b/addons/website_quote/models/order.py index 046ade6ef09..d6d78cc80a5 100644 --- a/addons/website_quote/models/order.py +++ b/addons/website_quote/models/order.py @@ -185,6 +185,7 @@ class sale_order(osv.osv): 'product_uom': line.product_uom_id.id, 'website_description': line.website_description, 'state': 'draft', + 'delay': line.product_id.sale_delay }) lines.append((0, 0, data)) options = [] From 07e6f28df3334489ba710d0709c1a2ba2376a47a Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 8 Jun 2016 13:58:54 +0200 Subject: [PATCH 05/70] [FIX] delivery, stock: carrier_id field in incoming stock picking The field "carrier_id" must be hidden for the incoming stock picking. opw:676411 --- addons/delivery/views/delivery_view.xml | 2 +- addons/stock/stock.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/delivery/views/delivery_view.xml b/addons/delivery/views/delivery_view.xml index 7fe85289c8e..804e0191da4 100644 --- a/addons/delivery/views/delivery_view.xml +++ b/addons/delivery/views/delivery_view.xml @@ -276,7 +276,7 @@ - +