[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] See730890f369ande3e5cfe82c
This commit is contained in:
@@ -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 () {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user