[MERGE] forward port of branch 8.0 up to 40fdb84
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,3 +1,4 @@
|
|||||||
import report
|
import report
|
||||||
import report_paperformat
|
import report_paperformat
|
||||||
import abstract_report
|
import abstract_report
|
||||||
|
import ir_qweb
|
||||||
|
|||||||
@@ -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')))
|
||||||
@@ -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.")
|
||||||
|
|||||||
@@ -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,2 +1,3 @@
|
|||||||
import controllers
|
import controllers
|
||||||
import report
|
import report
|
||||||
|
import ir_qweb
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user