[MERGE] forward port of branch saas-6 up to df95b1f

The changes in `l10n_es` [1] have been ignored. They will be ported to
the new accouting later.

[1] See 730890f369 and e3e5cfe82c
This commit is contained in:
Christophe Simonis
2016-06-14 19:22:21 +02:00
10 changed files with 116 additions and 57 deletions
+4 -2
View File
@@ -396,9 +396,11 @@ var DataImport = Widget.extend(ControlPanelMixin, {
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) {
@@ -414,7 +416,7 @@ var DataImport = Widget.extend(ControlPanelMixin, {
}) ;
},
onvalidate: function () {
return this.call_import({ dryrun: true })
return this.call_import({ dryrun: true, tracking_disable: true })
.done(this.proxy('validated'));
},
onimport: function () {
+6 -4
View File
@@ -609,21 +609,23 @@ class hr_payslip(osv.osv):
if context is None:
context = {}
#delete old worked days lines
worked_days_ids_to_remove=[]
old_worked_days_ids = ids and worked_days_obj.search(cr, uid, [('payslip_id', '=', ids[0])], context=context) or False
if old_worked_days_ids:
worked_days_obj.unlink(cr, uid, old_worked_days_ids, context=context)
worked_days_ids_to_remove = map(lambda x: (2, x,),old_worked_days_ids)
#delete old input lines
input_line_ids_to_remove=[]
old_input_ids = ids and input_obj.search(cr, uid, [('payslip_id', '=', ids[0])], context=context) or False
if old_input_ids:
input_obj.unlink(cr, uid, old_input_ids, context=context)
input_line_ids_to_remove = map(lambda x: (2,x,), old_input_ids)
#defaults
res = {'value':{
'line_ids':[],
'input_line_ids': [],
'worked_days_line_ids': [],
'input_line_ids': input_line_ids_to_remove,
'worked_days_line_ids': worked_days_ids_to_remove,
#'details_by_salary_head':[], TODO put me back
'name':'',
'contract_id': False,
+64 -47
View File
@@ -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))
@@ -37,7 +37,7 @@ class fiche_paye_parser(report_sxw.rml_parse):
category_total = 0
if cate_ids:
line_ids = payslip_line.search(self.cr, self.uid, [('slip_id', '=', obj.id),('category_id.id', '=', cate_ids[0] )])
line_ids = payslip_line.search(self.cr, self.uid, [('slip_id', '=', obj.id), ('category_id', 'child_of', cate_ids)])
for line in payslip_line.browse(self.cr, self.uid, line_ids):
category_total += line.total
+1 -1
View File
@@ -136,7 +136,7 @@ class procurement_order(osv.osv):
unlink_ids.append(s['id'])
else:
raise UserError(_('Cannot delete Procurement Order(s) which are in %s state.') % s['state'])
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
return super(procurement_order, self).unlink(cr, uid, unlink_ids, context=context)
def create(self, cr, uid, vals, context=None):
context = context or {}
+1
View File
@@ -217,6 +217,7 @@ class sale_order(osv.osv):
'website_description': line.website_description,
'state': 'draft',
'customer_lead': self._get_customer_lead(cr, uid, line.product_id.product_tmpl_id),
'delay': line.product_id.sale_delay
})
lines.append((0, 0, data))
options = []
+11
View File
@@ -0,0 +1,11 @@
UAE, 07 May 2016
I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Jordan Vrtanoski jordan.vrtanoski@gmail.com https://github.com/jordanvrtanoski
+12
View File
@@ -0,0 +1,12 @@
Sweden, 2016-06-09
I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Patrik Lermon patrik.lermon@gmail.com https://github.com/kler
+11
View File
@@ -0,0 +1,11 @@
India, 2016/06/08
I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Shelton Freddy sheltonfreddy141@gmail.com https://github.com/sheltonfreddy141
+5 -2
View File
@@ -140,8 +140,11 @@ def local_redirect(path, query=None, keep_hash=False, forward_debug=True, code=3
url = path
if not query:
query = {}
if forward_debug and request and request.debug:
query['debug'] = None
if request and request.debug:
if forward_debug:
query['debug'] = ''
else:
query['debug'] = None
if query:
url += '?' + werkzeug.url_encode(query)
if keep_hash: