[MERGE] forward port of branch 8.0 up to 40fdb84

This commit is contained in:
Christophe Simonis
2016-03-04 14:33:37 +01:00
11 changed files with 98 additions and 30 deletions
+1
View File
@@ -777,6 +777,7 @@ class account_invoice(models.Model):
line2[tmp]['debit'] = (am > 0) and am or 0.0 line2[tmp]['debit'] = (am > 0) and am or 0.0
line2[tmp]['credit'] = (am < 0) and -am or 0.0 line2[tmp]['credit'] = (am < 0) and -am or 0.0
line2[tmp]['tax_amount'] += l['tax_amount'] line2[tmp]['tax_amount'] += l['tax_amount']
line2[tmp]['amount_currency'] += l['amount_currency']
line2[tmp]['analytic_lines'] += l['analytic_lines'] line2[tmp]['analytic_lines'] += l['analytic_lines']
else: else:
line2[tmp] = l line2[tmp] = l
+1 -1
View File
@@ -166,7 +166,7 @@ class res_partner(osv.Model):
if partner.user_ids: if partner.user_ids:
res['login'] = partner.user_ids[0].login res['login'] = partner.user_ids[0].login
else: else:
res['email'] = partner.email or '' res['login'] = res['email'] = partner.email or ''
return res return res
class res_users(osv.Model): class res_users(osv.Model):
+1 -1
View File
@@ -37,7 +37,7 @@ class Blackbox(Thread):
# request. The first device to give an answer that makes sense # request. The first device to give an answer that makes sense
# wins. # wins.
def _find_device_path_by_probing(self): def _find_device_path_by_probing(self):
path = "/dev/serial/by-id/" path = "/dev/serial/by-path/"
probe_message = self._wrap_low_level_message_around("S000") probe_message = self._wrap_low_level_message_around("S000")
try: try:
+46 -16
View File
@@ -29,10 +29,12 @@ class Scale(Thread):
self.lock = Lock() self.lock = Lock()
self.scalelock = Lock() self.scalelock = Lock()
self.status = {'status':'connecting', 'messages':[]} self.status = {'status':'connecting', 'messages':[]}
self.input_dir = '/dev/serial/by-id/' self.input_dir = '/dev/serial/by-path/'
self.weight = 0 self.weight = 0
self.weight_info = 'ok' self.weight_info = 'ok'
self.device = None self.device = None
self.probed_device_paths = []
self.path_to_scale = ''
def lockedstart(self): def lockedstart(self):
with self.lock: with self.lock:
@@ -61,27 +63,55 @@ class Scale(Thread):
elif status == 'disconnected' and message: elif status == 'disconnected' and message:
_logger.info('Disconnected Scale: %s', message) _logger.info('Disconnected Scale: %s', message)
def _get_raw_response(self, connection):
response = ""
while True:
byte = connection.read(1)
if byte:
response += byte
else:
return response
def get_device(self): def get_device(self):
try: try:
if not os.path.exists(self.input_dir): if not os.path.exists(self.input_dir):
self.set_status('disconnected','Scale Not Found') self.set_status('disconnected','Scale Not Found')
return None return None
devices = [ device for device in listdir(self.input_dir)] devices = [ device for device in listdir(self.input_dir)]
scales = [ device for device in devices if ('mettler' in device.lower()) or ('toledo' in device.lower()) ]
if len(scales) > 0: if len(devices) > 0:
print join(self.input_dir,scales[0]) for device in devices:
self.set_status('connected','Connected to '+scales[0]) path = self.input_dir + device
return serial.Serial(join(self.input_dir,scales[0]),
baudrate = 9600, # don't keep probing devices that are not a scale,
bytesize = serial.SEVENBITS, # only keep probing if in the past the device was
stopbits = serial.STOPBITS_ONE, # confirmed to be a scale
parity = serial.PARITY_EVEN, if path not in self.probed_device_paths or path == self.path_to_scale:
#xonxoff = serial.XON, _logger.debug('Probing: ' + path)
timeout = 0.02, connection = serial.Serial(path,
writeTimeout= 0.02) baudrate = 9600,
else: bytesize = serial.SEVENBITS,
self.set_status('disconnected','Scale Not Found') stopbits = serial.STOPBITS_ONE,
return None parity = serial.PARITY_EVEN,
timeout = 1,
writeTimeout = 1)
connection.write("W")
self.probed_device_paths.append(path)
if self._get_raw_response(connection):
_logger.debug(path + ' is scale')
self.path_to_scale = path
self.set_status('connected','Connected to '+device)
connection.timeout = 0.02
connection.writeTimeout = 0.02
return connection
else:
_logger.debug('Already probed: ' + path)
self.set_status('disconnected','Scale Not Found')
return None
except Exception as e: except Exception as e:
self.set_status('error',str(e)) self.set_status('error',str(e))
return None return None
+1 -6
View File
@@ -85,12 +85,7 @@ class ReportController(Controller):
at the bottom of the output image at the bottom of the output image
""" """
try: try:
width, height, humanreadable = int(width), int(height), bool(humanreadable) barcode = request.registry['report'].barcode(type, value, width=width, height=height, humanreadable=humanreadable)
barcode = createBarcodeDrawing(
type, value=value, format='png', width=width, height=height,
humanReadable = humanreadable
)
barcode = barcode.asString('png')
except (ValueError, AttributeError): except (ValueError, AttributeError):
raise exceptions.HTTPException(description='Cannot convert into barcode.') raise exceptions.HTTPException(description='Cannot convert into barcode.')
+1
View File
@@ -1,3 +1,4 @@
import report import report
import report_paperformat import report_paperformat
import abstract_report import abstract_report
import ir_qweb
+21
View File
@@ -0,0 +1,21 @@
from reportlab.graphics.barcode import createBarcodeDrawing
from openerp.osv import osv
from openerp.addons.base.ir.ir_qweb import HTMLSafe
class BarcodeConverter(osv.AbstractModel):
""" ``barcode`` widget rendering, inserts a data:uri-using image tag in the
document. May be overridden by e.g. the website module to generate links
instead.
"""
_name = 'ir.qweb.field.barcode'
_inherit = 'ir.qweb.field'
def value_to_html(self, cr, uid, value, field, options=None, context=None):
barcode_type = options.get('type', 'Code128')
barcode = self.pool['report'].barcode(
barcode_type,
value,
**dict((key, value) for key, value in options.items() if key in ['width', 'height', 'humanreadable']))
return HTMLSafe('<img src="data:%s;base64,%s">' % ('png', barcode.encode('base64')))
+16
View File
@@ -42,6 +42,7 @@ from contextlib import closing
from distutils.version import LooseVersion from distutils.version import LooseVersion
from functools import partial from functools import partial
from pyPdf import PdfFileWriter, PdfFileReader from pyPdf import PdfFileWriter, PdfFileReader
from reportlab.graphics.barcode import createBarcodeDrawing
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@@ -570,3 +571,18 @@ class Report(osv.Model):
stream.close() stream.close()
return merged_file_path return merged_file_path
def barcode(self, barcode_type, value, width=600, height=100, humanreadable=0):
if barcode_type == 'UPCA' and len(value) in (11, 12, 13):
barcode_type = 'EAN13'
if len(value) in (11, 12):
value = '0%s' % value
try:
width, height, humanreadable = int(width), int(height), bool(humanreadable)
barcode = createBarcodeDrawing(
barcode_type, value=value, format='png', width=width, height=height,
humanReadable=humanreadable
)
return barcode.asString('png')
except (ValueError, AttributeError):
raise ValueError("Cannot convert into barcode.")
-6
View File
@@ -51,12 +51,6 @@ msgstr ""
msgid " (reserved)" msgid " (reserved)"
msgstr "" msgstr ""
#. module: stock
#: code:addons/stock/stock.py:2954
#, python-format
msgid "You cannot have two inventory adjustements in state 'in Progess' with the same product(%s), same location(%s), same package, same owner and same lot. Please first validate the first inventory adjustement with this product before creating another one."
msgstr ""
#. module: stock #. module: stock
#: code:addons/stock/stock.py:3090 #: code:addons/stock/stock.py:3090
#, python-format #, python-format
+1
View File
@@ -1,2 +1,3 @@
import controllers import controllers
import report import report
import ir_qweb
+9
View File
@@ -0,0 +1,9 @@
from openerp.osv import orm
class Barcode(orm.AbstractModel):
_name = 'website.qweb.field.barcode'
_inherit = ['website.qweb.field', 'ir.qweb.field.barcode']
def from_html(self, cr, uid, model, field, element, context=None):
return None