From c9d35c7012162e69b6edf4fbe72ba44636b6cd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 28 Oct 2009 18:04:43 -0200 Subject: [PATCH 01/60] [MERGE] lxml+etree instead of deprecated XML libs which prevent install on Ubuntu. Merged from old_trunk branch because on ne trunk, commits were not atomics anymore (after pig merge + bzr unability to track partial merge origins). merge directive used was: bzr merge -r 1825..1826 lp:~openerp/openobject-server/old_trunk tested main flows on manufacturing database + French -> no bug found; still will commit a few more commits related to trunk + etree lp bug: https://launchpad.net/bugs/429519 fixed bzr revid: rvalyi@gmail.com-20091028200443-2ciyhqaz7rczdusy --- bin/osv/orm.py | 183 +++++++++++------------ bin/tools/convert.py | 330 ++++++++++++++++++++--------------------- bin/tools/translate.py | 34 ++--- bin/wizard/__init__.py | 17 +-- 4 files changed, 268 insertions(+), 296 deletions(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 4859bd7d85a..ec74d01dd79 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -50,16 +50,15 @@ import pickle import fields import tools +from tools.translate import _ import sys try: - from xml import dom, xpath + from lxml import etree except ImportError: - sys.stderr.write("ERROR: Import xpath module\n") - sys.stderr.write("ERROR: Try to install the old python-xml package\n") - sys.stderr.write('On Ubuntu Jaunty, try this: sudo cp /usr/lib/python2.6/dist-packages/oldxml/_xmlplus/utils/boolean.so /usr/lib/python2.5/site-packages/oldxml/_xmlplus/utils\n') - raise + sys.stderr.write("ERROR: Import lxml module\n") + sys.stderr.write("ERROR: Try to install the python-lxml package\n") from tools.config import config @@ -997,14 +996,14 @@ class orm_template(object): fields = {} childs = True - if node.nodeType == node.ELEMENT_NODE and node.localName == 'field': - if node.hasAttribute('name'): + if node.tag == 'field': + if node.get('name'): attrs = {} try: - if node.getAttribute('name') in self._columns: - column = self._columns[node.getAttribute('name')] + if node.get('name') in self._columns: + column = self._columns[node.get('name')] else: - column = self._inherit_fields[node.getAttribute('name')][2] + column = self._inherit_fields[node.get('name')][2] except: column = False @@ -1012,65 +1011,63 @@ class orm_template(object): relation = column._obj childs = False views = {} - for f in node.childNodes: - if f.nodeType == f.ELEMENT_NODE and f.localName in ('form', 'tree', 'graph'): - node.removeChild(f) + for f in node: + if f.tag in ('form', 'tree', 'graph'): + node.remove(f) ctx = context.copy() ctx['base_model_name'] = self._name xarch, xfields = self.pool.get(relation).__view_look_dom_arch(cr, user, f, view_id, ctx) - views[str(f.localName)] = { + views[str(f.tag)] = { 'arch': xarch, 'fields': xfields } attrs = {'views': views} - if node.hasAttribute('widget') and node.getAttribute('widget')=='selection': + if node.get('widget') and node.get('widget') == 'selection': # We can not use the 'string' domain has it is defined according to the record ! - dom = [] + dom = None if column._domain and not isinstance(column._domain, (str, unicode)): dom = column._domain - attrs['selection'] = self.pool.get(relation).name_search(cr, user, '', dom, context=context) - if (node.hasAttribute('required') and not int(node.getAttribute('required'))) or not column.required: + if (node.get('required') and not int(node.get('required'))) or not column.required: attrs['selection'].append((False,'')) - fields[node.getAttribute('name')] = attrs + fields[node.get('name')] = attrs - elif node.nodeType==node.ELEMENT_NODE and node.localName in ('form', 'tree'): - result = self.view_header_get(cr, user, False, node.localName, context) + elif node.tag in ('form', 'tree'): + result = self.view_header_get(cr, user, False, node.tag, context) if result: - node.setAttribute('string', result) + node.set('string', result) - elif node.nodeType==node.ELEMENT_NODE and node.localName == 'calendar': + elif node.tag == 'calendar': for additional_field in ('date_start', 'date_delay', 'date_stop', 'color'): - if node.hasAttribute(additional_field) and node.getAttribute(additional_field): - fields[node.getAttribute(additional_field)] = {} + if node.get(additional_field): + fields[node.get(additional_field)] = {} - if node.nodeType == node.ELEMENT_NODE and node.hasAttribute('groups'): - if node.getAttribute('groups'): - groups = node.getAttribute('groups').split(',') + if 'groups' in node.attrib: + if node.get('groups'): + groups = node.get('groups').split(',') readonly = False access_pool = self.pool.get('ir.model.access') for group in groups: readonly = readonly or access_pool.check_groups(cr, user, group) if not readonly: - node.setAttribute('invisible', '1') - node.removeAttribute('groups') + node.set('invisible', '1') + del(node.attrib['groups']) - if node.nodeType == node.ELEMENT_NODE: - # translate view - if ('lang' in context) and not result: - if node.hasAttribute('string') and node.getAttribute('string'): - trans = self.pool.get('ir.translation')._get_source(cr, user, self._name, 'view', context['lang'], node.getAttribute('string').encode('utf8')) - if not trans and ('base_model_name' in context): - trans = self.pool.get('ir.translation')._get_source(cr, user, context['base_model_name'], 'view', context['lang'], node.getAttribute('string').encode('utf8')) - if trans: - node.setAttribute('string', trans) - if node.hasAttribute('sum') and node.getAttribute('sum'): - trans = self.pool.get('ir.translation')._get_source(cr, user, self._name, 'view', context['lang'], node.getAttribute('sum').encode('utf8')) - if trans: - node.setAttribute('sum', trans) + # translate view + if ('lang' in context) and not result: + if node.get('string'): + trans = self.pool.get('ir.translation')._get_source(cr, user, self._name, 'view', context['lang'], node.get('string').encode('utf8')) + if not trans and ('base_model_name' in context): + trans = self.pool.get('ir.translation')._get_source(cr, user, context['base_model_name'], 'view', context['lang'], node.get('string').encode('utf8')) + if trans: + node.set('string', trans) + if node.get('sum'): + trans = self.pool.get('ir.translation')._get_source(cr, user, self._name, 'view', context['lang'], node.get('sum').encode('utf8')) + if trans: + node.set('sum', trans) if childs: - for f in node.childNodes: + for f in node: fields.update(self.__view_look_dom(cr, user, f, view_id, context)) return fields @@ -1081,7 +1078,7 @@ class orm_template(object): rolesobj = self.pool.get('res.roles') usersobj = self.pool.get('res.users') - buttons = (n for n in node.getElementsByTagName('button') if n.getAttribute('type') != 'object') + buttons = (n for n in node.getiterator('button') if n.get('type') != 'object') for button in buttons: can_click = True if user != 1: # admin user has all roles @@ -1104,8 +1101,6 @@ class orm_template(object): # # running -> done = signal_next (role Z) # running -> cancel = signal_cancel (role Z) - - # As we don't know the object state, in this scenario, # the button "signal_cancel" will be always shown as there is no restriction to cancel in draft # the button "signal_next" will be show if the user has any of the roles (X Y or Z) @@ -1113,9 +1108,9 @@ class orm_template(object): if roles: can_click = any((not role) or rolesobj.check(cr, user, user_roles, role) for (role,) in roles) - button.setAttribute('readonly', str(int(not can_click))) + button.set('readonly', str(int(not can_click))) - arch = node.toxml(encoding="utf-8").replace('\t', '') + arch = etree.tostring(node, encoding="utf-8").replace('\t', '') fields = self.fields_get(cr, user, fields_def.keys(), context) for field in fields_def: if field == 'id': @@ -1180,70 +1175,64 @@ class orm_template(object): def _inherit_apply(src, inherit): def _find(node, node2): - if node2.nodeType == node2.ELEMENT_NODE and node2.localName == 'xpath': - res = xpath.Evaluate(node2.getAttribute('expr'), node) + if node2.tag == 'xpath': + res = node.xpath(node2.get('expr')) return res and res[0] else: - if node.nodeType == node.ELEMENT_NODE and node.localName == node2.localName: + for n in node.getiterator(node2.tag): res = True - for attr in node2.attributes.keys(): + for attr in node2.attrib: if attr == 'position': continue - if node.hasAttribute(attr): - if node.getAttribute(attr)==node2.getAttribute(attr): + if n.get(attr): + if n.get(attr) == node2.get(attr): continue res = False if res: - return node - for child in node.childNodes: - res = _find(child, node2) - if res: - return res + return n return None + # End: _find(node, node2) - - doc_src = dom.minidom.parseString(encode(src)) - doc_dest = dom.minidom.parseString(encode(inherit)) - toparse = doc_dest.childNodes + doc_dest = etree.fromstring(encode(inherit)) + toparse = [ doc_dest ] while len(toparse): node2 = toparse.pop(0) - if not node2.nodeType == node2.ELEMENT_NODE: + if node2.tag == 'data': + toparse += [ c for c in doc_dest ] continue - if node2.localName == 'data': - toparse += node2.childNodes - continue - node = _find(doc_src, node2) - if node: + node = _find(src, node2) + if node is not None: pos = 'inside' - if node2.hasAttribute('position'): - pos = node2.getAttribute('position') + if node2.get('position'): + pos = node2.get('position') if pos == 'replace': - parent = node.parentNode - for child in node2.childNodes: - if child.nodeType == child.ELEMENT_NODE: - parent.insertBefore(child, node) - parent.removeChild(node) + for child in node2: + node.addprevious(child) + node.getparent().remove(node) else: - sib = node.nextSibling - for child in node2.childNodes: - if child.nodeType == child.ELEMENT_NODE: - if pos == 'inside': - node.appendChild(child) - elif pos == 'after': - node.parentNode.insertBefore(child, sib) - elif pos=='before': - node.parentNode.insertBefore(child, node) + sib = node.getnext() + for child in node2: + if pos == 'inside': + node.append(child) + elif pos == 'after': + if sib is None: + node.addnext(child) else: - raise AttributeError(_('Unknown position in inherited view %s !') % pos) + sib.addprevious(child) + elif pos == 'before': + node.addprevious(child) + else: + raise AttributeError(_('Unknown position in inherited view %s !') % pos) else: attrs = ''.join([ - ' %s="%s"' % (attr, node2.getAttribute(attr)) - for attr in node2.attributes.keys() + ' %s="%s"' % (attr, node2.get(attr)) + for attr in node2.attrib if attr != 'position' ]) - tag = "<%s%s>" % (node2.localName, attrs) + tag = "<%s%s>" % (node2.tag, attrs) raise AttributeError(_("Couldn't find tag '%s' in parent view !") % tag) - return doc_src.toxml(encoding="utf-8").replace('\t', '') + return src + # End: _inherit_apply(src, inherit) result = {'type': view_type, 'model': self._name} @@ -1295,7 +1284,8 @@ class orm_template(object): result = _inherit_apply_rec(result, id) return result - result['arch'] = _inherit_apply_rec(result['arch'], sql_res[3]) + inherit_result = etree.fromstring(encode(result['arch'])) + result['arch'] = _inherit_apply_rec(inherit_result, sql_res[3]) result['name'] = sql_res[1] result['field_parent'] = sql_res[2] or False @@ -1322,13 +1312,12 @@ class orm_template(object): xml = self.__get_default_calendar_view() else: xml = '' - result['arch'] = xml + result['arch'] = etree.fromstring(xml) result['name'] = 'default' result['field_parent'] = False result['view_id'] = 0 - doc = dom.minidom.parseString(encode(result['arch'])) - xarch, xfields = self.__view_look_dom_arch(cr, user, doc, view_id, context=context) + xarch, xfields = self.__view_look_dom_arch(cr, user, result['arch'], view_id, context=context) result['arch'] = xarch result['fields'] = xfields if toolbar: @@ -3044,7 +3033,3 @@ class orm(orm_template): if i in ids: return False return True - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 71e44655154..485583b5d9e 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -21,7 +21,7 @@ ############################################################################## import re import cStringIO -import xml.dom.minidom +from lxml import etree import osv import ir import pooler @@ -62,16 +62,13 @@ def _obj(pool, cr, uid, model_str, context=None): def _eval_xml(self,node, pool, cr, uid, idref, context=None): if context is None: context = {} - if node.nodeType == node.TEXT_NODE: - return node.data.encode("utf8") - elif node.nodeType == node.ELEMENT_NODE: - if node.nodeName in ('field','value'): - t = node.getAttribute('type') or 'char' - f_model = node.getAttribute("model").encode('ascii') - if len(node.getAttribute('search')): - f_search = node.getAttribute("search").encode('utf-8') - f_use = node.getAttribute("use").encode('ascii') - f_name = node.getAttribute("name").encode('utf-8') + if node.tag in ('field','value'): + t = node.get('type','') or 'char' + f_model = node.get("model", '').encode('ascii') + if len(node.get('search','')): + f_search = node.get("search",'').encode('utf-8') + f_use = node.get("use",'').encode('ascii') + f_name = node.get("name",'').encode('utf-8') if len(f_use)==0: f_use = "id" q = eval(f_search, idref) @@ -87,7 +84,7 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None): if isinstance(f_val, tuple): f_val = f_val[0] return f_val - a_eval = node.getAttribute('eval') + a_eval = node.get('eval','') if len(a_eval): import time from mx import DateTime @@ -116,14 +113,11 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None): if not id in idref: idref[id]=self.id_get(cr, False, id) return s % idref - txt = '\n'+_process("".join([i.toxml().encode("utf8") for i in node.childNodes]), idref) -# txt = '\n'+"".join([i.toxml().encode("utf8") for i in node.childNodes]) % idref - + txt = '\n'+_process("".join([etree.tostring(i).encode("utf8") for i in node.getchildren()]), idref) return txt if t in ('char', 'int', 'float'): d = "" - for n in [i for i in node.childNodes]: - d+=str(_eval_xml(self,n,pool,cr,uid,idref)) + d = node.text if t == 'int': d = d.strip() if d=='None': @@ -135,37 +129,37 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None): return d elif t in ('list','tuple'): res=[] - for n in [i for i in node.childNodes if (i.nodeType == i.ELEMENT_NODE and i.nodeName=='value')]: + for n in [i for i in node.getchildren() if (i.tag=='value')]: res.append(_eval_xml(self,n,pool,cr,uid,idref)) if t=='tuple': return tuple(res) return res - elif node.nodeName=="getitem": - for n in [i for i in node.childNodes if (i.nodeType == i.ELEMENT_NODE)]: - res=_eval_xml(self,n,pool,cr,uid,idref) - if not res: - raise LookupError - elif node.getAttribute('type') in ("int", "list"): - return res[int(node.getAttribute('index'))] - else: - return res[node.getAttribute('index').encode("utf8")] - elif node.nodeName=="function": - args = [] - a_eval = node.getAttribute('eval') - if len(a_eval): - idref['ref'] = lambda x: self.id_get(cr, False, x) - args = eval(a_eval, idref) - for n in [i for i in node.childNodes if (i.nodeType == i.ELEMENT_NODE)]: - args.append(_eval_xml(self,n, pool, cr, uid, idref, context)) - model = pool.get(node.getAttribute('model')) - method = node.getAttribute('name') - res = getattr(model, method)(cr, uid, *args) - return res - elif node.nodeName=="test": - d = "" - for n in [i for i in node.childNodes]: - d+=str(_eval_xml(self,n,pool,cr,uid,idref, context=context)) - return d + elif node.tag == "getitem": + for n in [i for i in node.getchildren()]: + res=_eval_xml(self,n,pool,cr,uid,idref) + if not res: + raise LookupError + elif node.get('type','') in ("int", "list"): + return res[int(node.get('index',''))] + else: + return res[node.get('index','').encode("utf8")] + elif node.tag == "function": + args = [] + a_eval = node.get('eval','') + if len(a_eval): + idref['ref'] = lambda x: self.id_get(cr, False, x) + args = eval(a_eval, idref) + for n in [i for i in node.getchildren()]: + return_val = _eval_xml(self,n, pool, cr, uid, idref, context) + if return_val != None: + args.append(return_val) + model = pool.get(node.get('model','')) + method = node.get('name','') + res = getattr(model, method)(cr, uid, *args) + return res + elif node.tag == "test": + d = node.text + return d escape_re = re.compile(r'(?= config['assert_exit_level']: @@ -672,12 +662,11 @@ form: module.record_id""" % (xml_id,) self.assert_report.record_assertion(True, severity) def _tag_record(self, cr, rec, data_node=None): - rec_model = rec.getAttribute("model").encode('ascii') + rec_model = rec.get("model").encode('ascii') model = self.pool.get(rec_model) assert model, "The model %s does not exist !" % (rec_model,) - rec_id = rec.getAttribute("id").encode('ascii') + rec_id = rec.get("id",'').encode('ascii') self._test_xml_id(rec_id) - if self.isnoupdate(data_node) and self.mode != 'init': # check if the xml record has an id string if rec_id: @@ -703,17 +692,16 @@ form: module.record_id""" % (xml_id,) else: # otherwise it is skipped return None - res = {} - for field in [i for i in rec.childNodes if (i.nodeType == i.ELEMENT_NODE and i.nodeName=="field")]: + for field in [i for i in rec.getchildren() if (i.tag == "field")]: #TODO: most of this code is duplicated above (in _eval_xml)... - f_name = field.getAttribute("name").encode('utf-8') - f_ref = field.getAttribute("ref").encode('ascii') - f_search = field.getAttribute("search").encode('utf-8') - f_model = field.getAttribute("model").encode('ascii') + f_name = field.get("name",'').encode('utf-8') + f_ref = field.get("ref",'').encode('ascii') + f_search = field.get("search",'').encode('utf-8') + f_model = field.get("model",'').encode('ascii') if not f_model and model._columns.get(f_name,False): f_model = model._columns[f_name]._obj - f_use = field.getAttribute("use").encode('ascii') or 'id' + f_use = field.get("use",'').encode('ascii') or 'id' f_val = False if len(f_search): @@ -761,24 +749,22 @@ form: module.record_id""" % (xml_id,) return int(self.pool.get('ir.model.data').read(cr, self.uid, [result], ['res_id'])[0]['res_id']) def parse(self, xmlstr): - d = xml.dom.minidom.parseString(xmlstr) - de = d.documentElement + de = etree.XML(xmlstr) - if not de.nodeName in ['terp', 'openerp']: + if not de.tag in ['terp', 'openerp']: self.logger.notifyChannel("init", netsvc.LOG_ERROR, "Mismatch xml format" ) raise Exception( "Mismatch xml format: only terp or openerp as root tag" ) - if de.nodeName == 'terp': + if de.tag == 'terp': self.logger.notifyChannel("init", netsvc.LOG_WARNING, "The tag is deprecated, use ") - for n in [i for i in de.childNodes if (i.nodeType == i.ELEMENT_NODE and i.nodeName=="data")]: - for rec in n.childNodes: - if rec.nodeType == rec.ELEMENT_NODE: - if rec.nodeName in self._tags: + for n in [i for i in de.getchildren() if (i.tag=="data")]: + for rec in n.getchildren(): + if rec.tag in self._tags: try: - self._tags[rec.nodeName](self.cr, rec, n) + self._tags[rec.tag](self.cr, rec, n) except: - self.logger.notifyChannel("init", netsvc.LOG_ERROR, '\n'+rec.toxml()) + self.logger.notifyChannel("init", netsvc.LOG_ERROR, '\n'+etree.tostring(rec)) self.cr.rollback() raise return True @@ -891,11 +877,13 @@ def convert_xml_export(res): pool=pooler.get_pool(cr.dbname) cr=pooler.db.cursor() idref = {} - d = xml.dom.minidom.getDOMImplementation().createDocument(None, "terp", None) - de = d.documentElement - data=d.createElement("data") - de.appendChild(data) - de.appendChild(d.createTextNode('Some textual content.')) + + page = etree.Element ( 'terp' ) + doc = etree.ElementTree ( page ) + data = etree.SubElement ( page, 'data' ) + text_node = etree.SubElement ( page, 'text' ) + text_node.text = 'Some textual content.' + cr.commit() cr.close() diff --git a/bin/tools/translate.py b/bin/tools/translate.py index 62f48aaa3c6..b4fa6cc0138 100644 --- a/bin/tools/translate.py +++ b/bin/tools/translate.py @@ -23,9 +23,9 @@ import os from os.path import join import fnmatch -import csv, xml.dom, re +import csv, re +from lxml import etree import tools, pooler -from osv.orm import BrowseRecordError import ir import netsvc from tools.misc import UpdateableStr @@ -335,9 +335,9 @@ def trans_export(lang, modules, buffer, format, dbname=None): def trans_parse_xsl(de): res = [] - for n in [i for i in de.childNodes if (i.nodeType == i.ELEMENT_NODE)]: - if n.hasAttribute("t"): - for m in [j for j in n.childNodes if (j.nodeType == j.TEXT_NODE)]: + for n in [i for i in de.getchildren()]: + if n.get("t"): + for m in [j for j in n.getchildren()]: l = m.data.strip().replace('\n',' ') if len(l): res.append(l.encode("utf8")) @@ -346,8 +346,8 @@ def trans_parse_xsl(de): def trans_parse_rml(de): res = [] - for n in [i for i in de.childNodes if (i.nodeType == i.ELEMENT_NODE)]: - for m in [j for j in n.childNodes if (j.nodeType == j.TEXT_NODE)]: + for n in [i for i in de.getchildren()]: + for m in [j for j in n.getchildren()]: string_list = [s.replace('\n', ' ').strip() for s in re.split('\[\[.+?\]\]', m.data)] for s in string_list: if s: @@ -357,15 +357,15 @@ def trans_parse_rml(de): def trans_parse_view(de): res = [] - if de.hasAttribute("string"): - s = de.getAttribute('string') + if de.get("string"): + s = de.get('string') if s: res.append(s.encode("utf8")) - if de.hasAttribute("sum"): - s = de.getAttribute('sum') + if de.get("sum"): + s = de.get('sum') if s: res.append(s.encode("utf8")) - for n in [i for i in de.childNodes if (i.nodeType == i.ELEMENT_NODE)]: + for n in [i for i in de.getchildren()]: res.extend(trans_parse_view(n)) return res @@ -434,8 +434,8 @@ def trans_generate(lang, modules, dbname=None): obj = pool.get(model).browse(cr, uid, res_id) if model=='ir.ui.view': - d = xml.dom.minidom.parseString(encode(obj.arch)) - for t in trans_parse_view(d.documentElement): + d = etree.XML(encode(obj.arch)) + for t in trans_parse_view(d): push_translation(module, 'view', encode(obj.model), 0, t) elif model=='ir.actions.wizard': service_name = 'wizard.'+encode(obj.wiz_name) @@ -522,10 +522,10 @@ def trans_generate(lang, modules, dbname=None): report_type = "xsl" try: xmlstr = tools.file_open(fname).read() - d = xml.dom.minidom.parseString(xmlstr) - for t in parse_func(d.documentElement): + d = etree.XML()(xmlstr) + for t in parse_func(d.getroot()): push_translation(module, report_type, name, 0, t) - except IOError, xml.dom.expatbuilder.expat.ExpatError: + except IOError, etree.expatbuilder.expat.ExpatError: if fname: logger.notifyChannel("i18n", netsvc.LOG_ERROR, "couldn't export translation for report %s %s %s" % (name, report_type, fname)) diff --git a/bin/wizard/__init__.py b/bin/wizard/__init__.py index 1621559c628..378f9ac4563 100644 --- a/bin/wizard/__init__.py +++ b/bin/wizard/__init__.py @@ -24,7 +24,7 @@ import netsvc from tools import copy from tools.misc import UpdateableStr, UpdateableDict from tools.translate import translate -from xml import dom +from lxml import etree import ir import pooler @@ -50,13 +50,12 @@ class interface(netsvc.Service): self.wiz_name = name def translate_view(self, cr, node, state, lang): - if node.nodeType == node.ELEMENT_NODE: - if node.hasAttribute('string') and node.getAttribute('string'): - trans = translate(cr, self.wiz_name+','+state, 'wizard_view', lang, node.getAttribute('string').encode('utf8')) + if node.get('string'): + trans = translate(cr, self.wiz_name+','+state, 'wizard_view', lang, node.get('string').encode('utf8')) if trans: - node.setAttribute('string', trans) - for n in node.childNodes: - self.translate_view(cr, n, state, lang) + node.set('string', trans) + for n in node.getchildren(): + self.translate_view(cr, n, state, lang) def execute_cr(self, cr, uid, data, state='init', context=None): if not context: @@ -132,9 +131,9 @@ class interface(netsvc.Service): # translate arch if not isinstance(arch, UpdateableStr): - doc = dom.minidom.parseString(arch.encode('utf8')) + doc = etree.XML(arch) self.translate_view(cr, doc, state, lang) - arch = doc.toxml() + arch = etree.tostring(doc) # translate buttons button_list = list(button_list) From ece8b2918a786b93e7fdb38ae64dcca1a5333428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 28 Oct 2009 18:07:03 -0200 Subject: [PATCH 02/60] [MERGE] bzr merge -r 1847..1848 lp:openobject-server ([FIX] Prevent etree deprication warnings) lp bug: https://launchpad.net/bugs/429519 fixed bzr revid: rvalyi@gmail.com-20091028200703-u7298esyxktryqyk --- bin/tools/convert.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 485583b5d9e..23930fa8b75 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -205,12 +205,12 @@ class xml_import(object): if not val: return default return val.lower() not in ('0', 'false', 'off') - + def isnoupdate(self, data_node=None): - return self.noupdate or (data_node and self.nodeattr2bool(data_node, 'noupdate', False)) + return self.noupdate or (len(data_node) and self.nodeattr2bool(data_node, 'noupdate', False)) def get_context(self, data_node, node, eval_dict): - data_node_context = (data_node and data_node.get('context','').encode('utf8')) + data_node_context = (len(data_node) and data_node.get('context','').encode('utf8')) if data_node_context: context = eval(data_node_context, eval_dict) else: @@ -223,7 +223,7 @@ class xml_import(object): return context def get_uid(self, cr, uid, data_node, node): - node_uid = node.get('uid','') or (data_node and data_node.get('uid','')) + node_uid = node.get('uid','') or (len(data_node) and data_node.get('uid','')) if len(node_uid): return self.id_get(cr, None, node_uid) return uid @@ -294,8 +294,8 @@ form: module.record_id""" % (xml_id,) id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) - - + + if not rec.get('menu') or eval(rec.get('menu','')): keyword = str(rec.get('keyword','') or 'client_print_multi') keys = [('action',keyword),('res_model',res['model'])] @@ -688,7 +688,7 @@ form: module.record_id""" % (xml_id,) # we don't want to create it, so we skip it return None # else, we let the record to be created - + else: # otherwise it is skipped return None From 2686991976e4862ad42cdc3c504fd56f9177448f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 28 Oct 2009 18:12:54 -0200 Subject: [PATCH 03/60] [MERGE] bzr merge -r 1856..1857 lp:openobject-server . rev #1857 we merge here consists in a fix by Tiny because they didn't applied the etree conversion properly weeks back (the 2 previous merges here); part was already better merged on our side (2 commits back) because we resolved the conflicts more carefully. lp bug: https://launchpad.net/bugs/429519 fixed bzr revid: rvalyi@gmail.com-20091028201254-oxcmetgpxbp2oelp --- bin/osv/orm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index ec74d01dd79..da7cfc7558f 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1090,7 +1090,7 @@ class orm_template(object): INNER JOIN wkf_transition t ON (t.act_to = a.id) WHERE wkf.osv = %s AND t.signal = %s - """, (self._name, button.getAttribute('name'),)) + """, (self._name, button.get('name'),)) roles = cr.fetchall() # draft -> valid = signal_next (role X) From a5e1d56dd28051f224e8c24b694333c4a2478451 Mon Sep 17 00:00:00 2001 From: "nel@tinyerp.com" <> Date: Wed, 4 Nov 2009 11:51:34 +0100 Subject: [PATCH 04/60] [FIX] Avoid crash when no args bzr revid: nel@tinyerp.com-20091104105134-jl0c4gj5cecm388z --- bin/addons/base/ir/ir_cron.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/addons/base/ir/ir_cron.py b/bin/addons/base/ir/ir_cron.py index 0ef23a6c423..86d4bd57c0e 100644 --- a/bin/addons/base/ir/ir_cron.py +++ b/bin/addons/base/ir/ir_cron.py @@ -28,7 +28,7 @@ import pooler from osv import fields,osv def str2tuple(s): - return eval('tuple(%s)' % s) + return eval('tuple(%s)' % (s or '')) _intervalTypes = { 'work_days': lambda interval: DateTime.RelativeDateTime(days=interval), From 52066fa67905ea6c98a326b1d68992bc41b2bf97 Mon Sep 17 00:00:00 2001 From: Marcelo Hamra <> Date: Thu, 5 Nov 2009 12:11:39 +0530 Subject: [PATCH 05/60] Improved trigger selection query bzr revid: hda@tinyerp.com-20091105064139-ydbaycbiogouwqgc --- bin/addons/base/ir/ir_actions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py index 1403923c040..3047ceb7c8c 100644 --- a/bin/addons/base/ir/ir_actions.py +++ b/bin/addons/base/ir/ir_actions.py @@ -363,8 +363,8 @@ class actions_server(osv.osv): def _select_signals(self, cr, uid, context={}): cr.execute("select distinct t.signal as key, t.signal || ' - [ ' || w.osv || ' ] ' as val from wkf w, wkf_activity a, wkf_transition t "\ " where w.id = a.wkf_id " \ - " and t.act_from = a.wkf_id " \ - " or t.act_to = a.wkf_id and t.signal not in (null, NULL)") + " and t.act_from = a.id " \ + " or t.act_to = a.id and t.signal not in (null, NULL)") result = cr.fetchall() or [] res = [] for rs in result: From 4f3dc20b2fce19a20818964dd37118f36765631f Mon Sep 17 00:00:00 2001 From: "PSO(OpenERP)" <> Date: Fri, 6 Nov 2009 16:51:45 +0530 Subject: [PATCH 06/60] [IMP] Stock : Improved names of Stock move tree view lp bug: https://launchpad.net/bugs/476343 fixed bzr revid: jvo@tinyerp.com-20091106112145-aqwh8xoddhy61unm --- addons/stock/stock_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 6281d2dd1cc..ca2aeeb4f3e 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -229,7 +229,7 @@ # Lot composition (history) # - stock.move.tree2 + Stock Moves stock.move tree move_history_ids @@ -251,7 +251,7 @@ - stock.move.tree2 + Stock Moves stock.move tree move_history_ids2 From 5494568aa69a60fdf03a8c7a91069ae579980fff Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Fri, 6 Nov 2009 16:56:29 +0530 Subject: [PATCH 07/60] [IMP] Account : Entry Line action Name Improved bzr revid: jvo@tinyerp.com-20091106112629-uu7ojl5sy432uwii --- addons/account/account_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 91ebe4ba662..56019d04cc4 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -1354,7 +1354,7 @@ - account.move.line + Account Entry Lines account.move.line form tree,form From 328aceb4eda6b6815299e18b6c7beba7082178b6 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Fri, 6 Nov 2009 17:15:34 +0530 Subject: [PATCH 08/60] [FIX] Account: Wizards were missing translation import statement bzr revid: jvo@tinyerp.com-20091106114534-46rddtl0mk9qh6g4 --- addons/account/wizard/wizard_central_journal.py | 1 + addons/account/wizard/wizard_general_journal.py | 1 + addons/account/wizard/wizard_print_journal.py | 1 + 3 files changed, 3 insertions(+) diff --git a/addons/account/wizard/wizard_central_journal.py b/addons/account/wizard/wizard_central_journal.py index 1b8c4ba525a..09e6bd52e0d 100644 --- a/addons/account/wizard/wizard_central_journal.py +++ b/addons/account/wizard/wizard_central_journal.py @@ -22,6 +22,7 @@ import wizard import pooler +from tools.translate import _ form = '''
diff --git a/addons/account/wizard/wizard_general_journal.py b/addons/account/wizard/wizard_general_journal.py index fe9c1d1141f..c13352db213 100644 --- a/addons/account/wizard/wizard_general_journal.py +++ b/addons/account/wizard/wizard_general_journal.py @@ -22,6 +22,7 @@ import wizard import pooler +from tools.translate import _ form = ''' diff --git a/addons/account/wizard/wizard_print_journal.py b/addons/account/wizard/wizard_print_journal.py index 6b2ea42d66c..a1fad884392 100644 --- a/addons/account/wizard/wizard_print_journal.py +++ b/addons/account/wizard/wizard_print_journal.py @@ -22,6 +22,7 @@ import wizard import pooler +from tools.translate import _ form = ''' From c8909f06abdb7fedc8c6c4db9dc622a219c1d94d Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Fri, 6 Nov 2009 18:28:53 +0530 Subject: [PATCH 09/60] [FIX] Stock : Partial Picking wizard was missing translation import statement lp bug: https://launchpad.net/bugs/476428 fixed bzr revid: jvo@tinyerp.com-20091106125853-zn8vpglxm3lugp86 --- addons/stock/wizard/wizard_partial_picking.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/stock/wizard/wizard_partial_picking.py b/addons/stock/wizard/wizard_partial_picking.py index a93a8981a18..6efde5782cf 100644 --- a/addons/stock/wizard/wizard_partial_picking.py +++ b/addons/stock/wizard/wizard_partial_picking.py @@ -28,6 +28,7 @@ import pooler import wizard from osv import osv import tools +from tools.translate import _ _moves_arch = UpdateableStr() _moves_fields = UpdateableDict() From 89dc28dfe7d8752ab00ee51e1a398a2bfaee9362 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Mon, 9 Nov 2009 12:55:32 +0530 Subject: [PATCH 10/60] [FIX] Export : M2M field name was missing last character lp bug: https://launchpad.net/bugs/478724 fixed bzr revid: jvo@tinyerp.com-20091109072532-rmub2t6519nz1hyu --- bin/osv/orm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 119405e57bf..c7999671b3a 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -523,7 +523,7 @@ class orm_template(object): rr = rr.name rr_name = self.pool.get(rr._table_name).name_get(cr, uid, [rr.id]) rr_name = rr_name and rr_name[0] and rr_name[0][1] or '' - dt += rr_name or '' + ',' + dt += tools.ustr(rr_name or '') + ',' data[fpos] = dt[:-1] break lines += lines2[1:] From c36ff651f2ee97e7975e94e0361525cff9bc8e10 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Wed, 11 Nov 2009 11:20:28 +0530 Subject: [PATCH 11/60] [FIX] M2M : values filtering on set() lp bug: https://launchpad.net/bugs/480301 fixed bzr revid: jvo@tinyerp.com-20091111055028-lza87cnyffvwxy4i --- bin/osv/fields.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/osv/fields.py b/bin/osv/fields.py index cde2a0e8ff4..dc5e2a9fd4a 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -528,6 +528,8 @@ class many2many(_column): return obj = obj.pool.get(self._obj) for act in values: + if not (isinstance(act, list) or isinstance(act, tuple)) or not act: + continue if act[0] == 0: idnew = obj.create(cr, user, act[2]) cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s,%s)', (id, idnew)) From fbcd9132f2bc6fd19de6ead481dbdd3d9fc5bb89 Mon Sep 17 00:00:00 2001 From: "GPA(OpenERP)" <> Date: Wed, 11 Nov 2009 12:27:46 +0530 Subject: [PATCH 12/60] [FIX] CRM : action name improved lp bug: https://launchpad.net/bugs/480035 fixed bzr revid: jvo@tinyerp.com-20091111065746-8zh3u6r6q2sch50u --- addons/crm/crm_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm/crm_view.xml b/addons/crm/crm_view.xml index 3b425ba0f3c..d39ad143358 100644 --- a/addons/crm/crm_view.xml +++ b/addons/crm/crm_view.xml @@ -404,7 +404,7 @@ - crm.case.section.open + Cases crm.case [('section_id','child_of',[active_id])] form From 4dc6cc8698b8f238a5d8c039433b29028e3d54ff Mon Sep 17 00:00:00 2001 From: "mra (Open ERP)" Date: Wed, 11 Nov 2009 12:24:00 +0530 Subject: [PATCH 13/60] [FIX] membership: solve problem of deleting membership invoice created with old membership product bzr revid: mra@tinyerp.com-20091111065400-3dodf4zrsyw45wc3 --- addons/membership/membership.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/membership/membership.py b/addons/membership/membership.py index a0d45169278..4b10f03ccab 100644 --- a/addons/membership/membership.py +++ b/addons/membership/membership.py @@ -267,7 +267,7 @@ class Partner(osv.osv): s = 3 if s==4: for mline in partner_data.member_lines: - if mline.date_from < today and mline.date_to < today and mline.date_from<=mline.date_to and mline.account_invoice_line.invoice_id.state == 'paid': + if mline.date_from < today and mline.date_to < today and mline.date_from<=mline.date_to and (mline.account_invoice_line and mline.account_invoice_line.invoice_id.state) == 'paid': s = 5 else: s = 6 From 275e96de8859770b8804a7905ca0f4917ee9f0e4 Mon Sep 17 00:00:00 2001 From: Xavier Morel <> Date: Wed, 11 Nov 2009 12:32:57 +0530 Subject: [PATCH 14/60] [FIX] Added lxml as required module on setup lp bug: https://launchpad.net/bugs/479915 fixed bzr revid: jvo@tinyerp.com-20091111070257-b628xbpfl0v3fshd --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 47ea152b5d0..f34a69bfb8b 100755 --- a/setup.py +++ b/setup.py @@ -60,6 +60,7 @@ required_modules = [ ('reportlab', 'reportlab module'), ('pychart', 'pychart module'), ('pydot', 'pydot module'), + ('lxml', 'lxml module: pythonic libxml2 and libxslt bindings'), ] def check_modules(): From 2af45b4557709987fe6e61daba7940fc39532648 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Wed, 11 Nov 2009 12:53:44 +0530 Subject: [PATCH 15/60] [IMP] MRP : mrp.routing.workcenter made deletable on cascade effect lp bug: https://launchpad.net/bugs/479747 fixed bzr revid: jvo@tinyerp.com-20091111072344-r5o7k252rqrbhc9w --- addons/mrp/mrp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 0288081148d..33e3eb0d242 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -129,7 +129,7 @@ class mrp_routing_workcenter(osv.osv): 'cycle_nbr': fields.float('Number of Cycle', required=True, help="A cycle is defined in the workcenter definition."), 'hour_nbr': fields.float('Number of Hours', required=True), - 'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True), + 'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True, ondelete='cascade'), 'note': fields.text('Description') } _defaults = { From a5206878193c79eefdd89582381c0c8b6aca2663 Mon Sep 17 00:00:00 2001 From: "NCH(OpenERP)" <> Date: Wed, 11 Nov 2009 18:07:41 +0530 Subject: [PATCH 16/60] Module: mrp_operations Fixed date format problem bzr revid: hda@tinyerp.com-20091111123741-1pagu1r98e8rll0y --- addons/mrp_operations/mrp_operations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index 059f6a5a0e1..0f194b4f4da 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -330,8 +330,8 @@ class mrp_operations_operation(osv.osv): if not i: continue if code_lst[i-1] not in ('resume','start'): continue - a = datetime.datetime.strptime(time_lst[i-1],'%Y:%m:%d %H:%M:%S') - b = datetime.datetime.strptime(time_lst[i],'%Y:%m:%d %H:%M:%S') + a = datetime.datetime.strptime(time_lst[i-1],'%Y-%m-%d %H:%M:%S') + b = datetime.datetime.strptime(time_lst[i],'%Y-%m-%d %H:%M:%S') diff += (b-a).days * 24 diff += (b-a).seconds / (60*60) return diff From 436cfd6954d5ed8e538ae3c4c141e9cf56f75bae Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Thu, 12 Nov 2009 11:12:24 +0530 Subject: [PATCH 17/60] [FIX] Warning : the super of onchange may return {},covered the same lp bug: https://launchpad.net/bugs/480856 fixed bzr revid: jvo@tinyerp.com-20091112054224-sb6q3k0p3g1yfs7v --- addons/warning/warning.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/warning/warning.py b/addons/warning/warning.py index 16d29d91758..6dd8d78f5c7 100644 --- a/addons/warning/warning.py +++ b/addons/warning/warning.py @@ -79,7 +79,7 @@ class sale_order(osv.osv): warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title'] warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message'] - return {'value': result['value'], 'warning':warning} + return {'value': result.get('value',{}), 'warning':warning} sale_order() @@ -107,7 +107,7 @@ class purchase_order(osv.osv): warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title'] warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message'] - return {'value': result['value'], 'warning':warning} + return {'value': result.get('value',{}), 'warning':warning} purchase_order() @@ -146,7 +146,7 @@ class account_invoice(osv.osv): warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title'] warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message'] - return {'value': result['value'], 'warning':warning} + return {'value': result.get('value',{}), 'warning':warning} account_invoice() @@ -174,7 +174,7 @@ class stock_picking(osv.osv): warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title'] warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message'] - return {'value': result['value'], 'warning':warning} + return {'value': result.get('value',{}), 'warning':warning} stock_picking() @@ -229,7 +229,7 @@ class sale_order_line(osv.osv): warning['title'] = title and title +' & '+result['warning']['title'] or result['warning']['title'] warning['message'] = message and message +'\n\n'+result['warning']['message'] or result['warning']['message'] - return {'value': result['value'], 'warning':warning} + return {'value': result.get('value',{}), 'warning':warning} sale_order_line() @@ -260,7 +260,7 @@ class purchase_order_line(osv.osv): warning['title'] = title and title +' & '+result['warning']['title'] or result['warning']['title'] warning['message'] = message and message +'\n\n'+result['warning']['message'] or result['warning']['message'] - return {'value': result['value'], 'warning':warning} + return {'value': result.get('value',{}), 'warning':warning} purchase_order_line() From 1d18ac45cc0354af60ed019ac0f611f6cc0afa31 Mon Sep 17 00:00:00 2001 From: "Ferdinand@Chricar" <> Date: Thu, 12 Nov 2009 11:51:18 +0530 Subject: [PATCH 18/60] [IMP] ir_cron : added active feild on list view lp bug: https://launchpad.net/bugs/480782 fixed bzr revid: jvo@tinyerp.com-20091112062118-wrtw5fa64ta1j3lr --- bin/addons/base/ir/ir.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/addons/base/ir/ir.xml b/bin/addons/base/ir/ir.xml index 9c94c8179f9..a18e4b49b04 100644 --- a/bin/addons/base/ir/ir.xml +++ b/bin/addons/base/ir/ir.xml @@ -1011,6 +1011,7 @@ + From c141ef0840abd01cba567f69fa86abab75134cc7 Mon Sep 17 00:00:00 2001 From: Mantavya Gajjar Date: Thu, 12 Nov 2009 13:33:40 +0530 Subject: [PATCH 19/60] [FIX]: fix the problem that appers in to the account move due to accout voucher bzr revid: mga@tinyerp.com-20091112080340-oeg9zkjwberb3pbf --- addons/account_voucher/__terp__.py | 2 +- addons/account_voucher/account.py | 12 +----------- addons/account_voucher/account_view.xml | 20 ++++---------------- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/addons/account_voucher/__terp__.py b/addons/account_voucher/__terp__.py index 92f6199f3cb..b23c289a8f1 100755 --- a/addons/account_voucher/__terp__.py +++ b/addons/account_voucher/__terp__.py @@ -41,10 +41,10 @@ "update_xml" : [ "voucher_sequence.xml", - "account_view.xml", "account_report.xml", "voucher_wizard.xml", "voucher_view.xml", + "account_view.xml", ], 'certificate': '0037580727101', "active": False, diff --git a/addons/account_voucher/account.py b/addons/account_voucher/account.py index 4006cde9863..71765ef0fb6 100644 --- a/addons/account_voucher/account.py +++ b/addons/account_voucher/account.py @@ -220,17 +220,7 @@ class AccountMove(osv.osv): _inherit = "account.move" _columns = { 'name':fields.char('Name', size=256, required=True, readonly=True, states={'draft':[('readonly',False)]}), - 'voucher_type': fields.selection([ - ('pay_voucher','Cash Payment Voucher'), - ('bank_pay_voucher','Bank Payment Voucher'), - ('rec_voucher','Cash Receipt Voucher'), - ('bank_rec_voucher','Bank Receipt Voucher'), - ('cont_voucher','Contra Voucher'), - ('journal_sale_vou','Journal Sale Voucher'), - ('journal_pur_voucher','Journal Purchase Voucher'), - ('journal_voucher','Journal Voucher'), - ],'Voucher Type', readonly=True, select=True, states={'draft':[('readonly',False)]}), - 'narration':fields.text('Narration'), + 'narration':fields.text('Narration', readonly=True, select=True, states={'draft':[('readonly',False)]}), } AccountMove() diff --git a/addons/account_voucher/account_view.xml b/addons/account_voucher/account_view.xml index 5201e41e468..b415f1af0b9 100755 --- a/addons/account_voucher/account_view.xml +++ b/addons/account_voucher/account_view.xml @@ -1,26 +1,14 @@ - - account.move.type.form.inherit1 + + account.move.type.form.inherit2 account.move form - - - - - - - - - account.move.type.form.inherit2 - - account.move - form - + @@ -120,7 +108,7 @@ - + sub.currency.form From 820e9b38935e6ba6aa1942cd362abf8ca8c48ee2 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Thu, 12 Nov 2009 14:44:53 +0530 Subject: [PATCH 20/60] [FIX] Subscription : Disallowed to change the Object linked to the document type. lp bug: https://launchpad.net/bugs/435298 fixed bzr revid: jvo@tinyerp.com-20091112091453-wus13ocpep0rmgmp --- addons/subscription/subscription.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/subscription/subscription.py b/addons/subscription/subscription.py index 7c4c80f03be..f2426fdd16c 100644 --- a/addons/subscription/subscription.py +++ b/addons/subscription/subscription.py @@ -40,6 +40,12 @@ class subscription_document(osv.osv): _defaults = { 'active' : lambda *a: True, } + + def write(self, cr, uid, ids, vals, context=None): + if 'model' in vals: + raise osv.except_osv(_('Error !'),_('You cannot modify the Object linked to the Document Type!\nCreate another Document instead !')) + return super(subscription_document, self).write(cr, uid, ids, vals, context=context) + subscription_document() class subscription_document_fields(osv.osv): From 0b976c8d12ac00271d5fc3be9504768a869289ff Mon Sep 17 00:00:00 2001 From: "mra (Open ERP)" Date: Thu, 12 Nov 2009 14:49:13 +0530 Subject: [PATCH 21/60] [FIX] membership: change membership product date from and date to value with current year on demo data bzr revid: mra@tinyerp.com-20091112091913-ee8wqyhiicu3awpp --- addons/membership/membership_demo.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/membership/membership_demo.xml b/addons/membership/membership_demo.xml index 35b04539ce3..495050398d1 100644 --- a/addons/membership/membership_demo.xml +++ b/addons/membership/membership_demo.xml @@ -5,8 +5,8 @@ True - 2008-01-01 - 2009-06-01 + 2009-01-01 + 2010-06-01 Membership Product - 1 80 @@ -14,8 +14,8 @@ True - 2008-01-01 - 2009-08-01 + 2009-01-01 + 2010-08-01 Membership Product - 2 80 From 1cbcbffec0111046f09ca8bf6bbe41858d1a02b1 Mon Sep 17 00:00:00 2001 From: "mra (Open ERP)" Date: Fri, 13 Nov 2009 12:03:46 +0530 Subject: [PATCH 22/60] [FIX] membership: invoice membership wizard now calculate tax corectly and on product membership fields make readonly to false bzr revid: mra@tinyerp.com-20091113063346-job7hqhxpvrhy239 --- addons/membership/membership_view.xml | 6 +++--- addons/membership/wizard/invoice_membership.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/membership/membership_view.xml b/addons/membership/membership_view.xml index d30276dae95..b126dbd537e 100644 --- a/addons/membership/membership_view.xml +++ b/addons/membership/membership_view.xml @@ -51,10 +51,10 @@ - + - - + + diff --git a/addons/membership/wizard/invoice_membership.py b/addons/membership/wizard/invoice_membership.py index 8eac255c610..5b5e3c44934 100644 --- a/addons/membership/wizard/invoice_membership.py +++ b/addons/membership/wizard/invoice_membership.py @@ -80,9 +80,9 @@ def _invoice_membership(self, cr, uid, data, context): invoice_obj.write(cr, uid, invoice_id, {'invoice_line':[(6,0,[invoice_line_id])]}) invoice_list.append(invoice_id) if line_value['invoice_line_tax_id']: - invoice_obj.write(cr, uid, [invoice_id], {'tax_line':tax_tab}) - tax_value = invoice_tax_obj.compute(cr, uid, invoice_id).values()[0] - invoice_tax_obj.create(cr, uid, tax_value) + tax_value = invoice_tax_obj.compute(cr, uid, invoice_id).values() + for tax in tax_value: + invoice_tax_obj.create(cr, uid, tax, context=context) value = { 'domain': [ From 4abe8d620ec82cfe7d8740d9e99504d96751ead4 Mon Sep 17 00:00:00 2001 From: "Harry (Open ERP)" Date: Fri, 13 Nov 2009 12:44:18 +0530 Subject: [PATCH 23/60] [FIX] quality_integration_server : fixed problem in integration server on translation checking if translation file is changed on base module bzr revid: hmo@tinyerp.com-20091113071418-6p79ugqwpqkv55ev --- .../quality_integration_server/base_quality_interrogation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/addons/quality_integration_server/base_quality_interrogation.py b/bin/addons/quality_integration_server/base_quality_interrogation.py index ca9bbddc593..0c82a9d4263 100755 --- a/bin/addons/quality_integration_server/base_quality_interrogation.py +++ b/bin/addons/quality_integration_server/base_quality_interrogation.py @@ -337,7 +337,10 @@ if opt.translate_in: translate = opt.translate_in for module_name,po_files in map(lambda x:tuple(x.split(':')),translate.split('+')): for po_file in po_files.split(','): - po_link = '%s/%s/i18n/%s'%(options['addons-path'], module_name, po_file) + if module_name == 'base': + po_link = '%saddons/%s/i18n/%s'%(options['root-path'],module_name,po_file) + else: + po_link = '%s/%s/i18n/%s'%(options['addons-path'], module_name, po_file) options['translate-in'].append(po_link) uri = 'http://localhost:' + str(options['port']) From 4dc22b73e5629a109cb6b0227806db11d3b60e79 Mon Sep 17 00:00:00 2001 From: "UCO,JVO" <> Date: Fri, 13 Nov 2009 12:56:56 +0530 Subject: [PATCH 24/60] [FIX] On Update, if only the size of column is changed,it should reflect into DB bzr revid: jvo@tinyerp.com-20091113072656-ytd8372l270lho75 --- bin/osv/orm.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index c7999671b3a..16c92574936 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1854,8 +1854,18 @@ class orm(orm_template): cr.commit() for c in casts: if (f_pg_type==c[0]) and (f._type==c[1]): - if f_pg_type != f_obj_type: - logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed type to %s." % (k, self._table, c[1])) + # Adding upcoming 6 lines to check whether only the size of the fields got changed or not.E.g. :(16,3) to (16,4) + field_size_change = False + if f.digits: + field_size = (65535 * f.digits[0]) + f.digits[0] + f.digits[1] + if field_size != f_pg_size: + field_size_change = True + + if f_pg_type != f_obj_type or field_size_change: + if f_pg_type != f_obj_type: + logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed type to %s." % (k, self._table, c[1])) + if field_size_change: + logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed in the size." % (k, self._table)) ok = True cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2])) From 0d7e1a5fcfd4934eaba9572dab390b4edfa30d81 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Fri, 13 Nov 2009 19:27:13 +0530 Subject: [PATCH 25/60] [FIX] On update, fields with only numeric/int/float could have digits bzr revid: jvo@tinyerp.com-20091113135713-eiv4kfs9mkn4su3p --- bin/osv/orm.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 16c92574936..1af15c8024c 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1856,10 +1856,11 @@ class orm(orm_template): if (f_pg_type==c[0]) and (f._type==c[1]): # Adding upcoming 6 lines to check whether only the size of the fields got changed or not.E.g. :(16,3) to (16,4) field_size_change = False - if f.digits: - field_size = (65535 * f.digits[0]) + f.digits[0] + f.digits[1] - if field_size != f_pg_size: - field_size_change = True + if f_pg_type in ['int4','numeric','float8']: + if f.digits: + field_size = (65535 * f.digits[0]) + f.digits[0] + f.digits[1] + if field_size != f_pg_size: + field_size_change = True if f_pg_type != f_obj_type or field_size_change: if f_pg_type != f_obj_type: From a29db43ce203a2585c95010733fea7256a43fd14 Mon Sep 17 00:00:00 2001 From: Sebastien LANGE <> Date: Mon, 16 Nov 2009 17:07:10 +0530 Subject: [PATCH 26/60] Fixed Spelling mistake lp bug: https://launchpad.net/bugs/483527 fixed bzr revid: hda@tinyerp.com-20091116113710-ixwxro0bweezjbre --- bin/osv/orm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 1af15c8024c..4fd99b7d433 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1589,7 +1589,7 @@ class orm_memory(orm_template): # get the default values from the context for key in context or {}: - if key.startswith('default_') and (key[8:] in fieds_list): + if key.startswith('default_') and (key[8:] in fields_list): value[key[8:]] = context[key] return value From 32c483bb6ec83f7efe7b474090f9bb8536249226 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Tue, 17 Nov 2009 12:40:35 +0530 Subject: [PATCH 27/60] [FIX] Project : If company has no Project time unit,it would have crashed. lp bug: https://launchpad.net/bugs/481372 fixed bzr revid: jvo@tinyerp.com-20091117071035-9dah99zt6wuavyju --- addons/project/project.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/project/project.py b/addons/project/project.py index aaf16082792..029931ea6a9 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -306,12 +306,14 @@ class task(osv.osv): # Override view according to the company definition # def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False): - tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode + tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode or False f = self.pool.get('res.company').fields_get(cr, uid, ['project_time_mode'], context) - word = dict(f['project_time_mode']['selection'])[tm] + word = 'Hours' + if tm: + word = dict(f['project_time_mode']['selection'])[tm] res = super(task, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar) - if tm=='hours': + if (not tm) or (tm=='hours'): return res eview = etree.fromstring(res['arch']) def _check_rec(eview, tm): From cd74873235d0c12aec517db3bd8c006c181ecd15 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Tue, 17 Nov 2009 12:52:34 +0530 Subject: [PATCH 28/60] [FIX] Priority on fields.function with store dictionary made working. lp bug: https://launchpad.net/bugs/462506 fixed bzr revid: jvo@tinyerp.com-20091117072234-fjb7gcupgnw4q22b --- bin/osv/orm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 4fd99b7d433..a14286b675f 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1997,7 +1997,8 @@ class orm(orm_template): ok = True for x,y,z,e,f in self.pool._store_function[object]: if (x==self._name) and (y==store_field) and (e==fields2): - ok = False + if f==order: + ok = False if ok: self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order)) self.pool._store_function[object].sort(lambda x,y: cmp(x[4],y[4])) From 2cb4136c9f6da3d1a01b7ec05a633102c5287567 Mon Sep 17 00:00:00 2001 From: "DSH (Open ERP)" Date: Tue, 17 Nov 2009 14:42:18 +0530 Subject: [PATCH 29/60] [FIX] act_window False domain problem - produce after dom to lxml conversion bzr revid: dsh@tinyerp.com-20091117091218-4mvoqnf76o7mc0an --- bin/tools/convert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 4d42e0729b7..9f8f2bc55c1 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -372,7 +372,7 @@ form: module.record_id""" % (xml_id,) view_id = False if rec.get('view'): view_id = self.id_get(cr, 'ir.actions.act_window', rec.get('view','').encode('utf-8')) - domain = rec.get('domain','').encode('utf-8') + domain = rec.get('domain','').encode('utf-8') or '{}' context = rec.get('context','').encode('utf-8') or '{}' res_model = rec.get('res_model','').encode('utf-8') src_model = rec.get('src_model','').encode('utf-8') From 862230a6acb507de1d3f2132d158c8368e67430a Mon Sep 17 00:00:00 2001 From: "Alex Joni,PSI(OpenERP)" <> Date: Tue, 17 Nov 2009 15:05:01 +0530 Subject: [PATCH 30/60] [FIX] Base_vat : Romania VAT validation corrected lp bug: https://launchpad.net/bugs/479195 fixed bzr revid: jvo@tinyerp.com-20091117093501-oy4zt46go56bbkr5 --- addons/base_vat/partner.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/base_vat/partner.py b/addons/base_vat/partner.py index e470244e5e4..ca6460620e9 100644 --- a/addons/base_vat/partner.py +++ b/addons/base_vat/partner.py @@ -915,7 +915,8 @@ class res_partner(osv.osv): except: return False - if len(vat) == 10: + if len(vat) >= 2 and len(vat) <= 10: + vat = (10 - len(vat)) * '0' + vat sum = 7 * int(vat[0]) + 5 * int(vat[1]) + 3 * int(vat[2]) + \ 2 * int(vat[3]) + 1 * int(vat[4]) + 7 * int(vat[5]) + \ 5 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8]) From 8deb66a4f15a2da7e8acc96a0b590f83964d3609 Mon Sep 17 00:00:00 2001 From: "HDA (OpenERP)" Date: Tue, 17 Nov 2009 18:15:11 +0530 Subject: [PATCH 31/60] Fixed xml dom problem in export translation. bzr revid: hda@tinyerp.com-20091117124511-lz0ovl4j1rbo3qxj --- bin/tools/translate.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bin/tools/translate.py b/bin/tools/translate.py index 046e4b6136d..ca833dfee6e 100644 --- a/bin/tools/translate.py +++ b/bin/tools/translate.py @@ -345,8 +345,8 @@ def trans_parse_xsl(de): res = [] for n in [i for i in de.getchildren()]: if n.get("t"): - for m in [j for j in n.getchildren()]: - l = m.data.strip().replace('\n',' ') + for m in [j for j in n.getchildren() if j.text]: + l = m.text.strip().replace('\n',' ') if len(l): res.append(l.encode("utf8")) res.extend(trans_parse_xsl(n)) @@ -355,8 +355,8 @@ def trans_parse_xsl(de): def trans_parse_rml(de): res = [] for n in [i for i in de.getchildren()]: - for m in [j for j in n.getchildren()]: - string_list = [s.replace('\n', ' ').strip() for s in re.split('\[\[.+?\]\]', m.data)] + for m in [j for j in n.getchildren() if j.text]: + string_list = [s.replace('\n', ' ').strip() for s in re.split('\[\[.+?\]\]', m.text)] for s in string_list: if s: res.append(s.encode("utf8")) @@ -475,8 +475,8 @@ def trans_generate(lang, modules, dbname=None): # export arch arch = result['arch'] if arch and not isinstance(arch, UpdateableStr): - d = xml.dom.minidom.parseString(arch) - for t in trans_parse_view(d.documentElement): + d = etree.XML(arch) + for t in trans_parse_view(d): push_translation(module, 'wizard_view', name, 0, t) # export button labels @@ -530,10 +530,10 @@ def trans_generate(lang, modules, dbname=None): report_type = "xsl" try: xmlstr = tools.file_open(fname).read() - d = etree.XML()(xmlstr) - for t in parse_func(d.getroot()): + d = etree.XML(xmlstr) + for t in parse_func(d): push_translation(module, report_type, name, 0, t) - except IOError, etree.expatbuilder.expat.ExpatError: + except IOError, etree.XMLSyntaxError: if fname: logger.notifyChannel("i18n", netsvc.LOG_ERROR, "couldn't export translation for report %s %s %s" % (name, report_type, fname)) From efab356429018bd5bb1697833a0f866c1692722c Mon Sep 17 00:00:00 2001 From: "mra (Open ERP)" Date: Wed, 18 Nov 2009 11:07:48 +0530 Subject: [PATCH 32/60] [FIX] solve problem of importing data from csv with constraints available on object bzr revid: mra@tinyerp.com-20091118053748-pmv0wxa5qp5n1qrx --- bin/osv/orm.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index a14286b675f..5318c242ad2 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -832,24 +832,27 @@ class orm_template(object): #try: (res, other, warning, translate, data_id, res_id) = \ process_liness(self, datas, [], current_module, self._name, fields_def) - if len(warning): + if len(warning): cr.rollback() return (-1, res, 'Line ' + str(counter) +' : ' + '!\n'.join(warning), '') - + try: id = ir_model_data_obj._update(cr, uid, self._name, current_module, res, xml_id=data_id, mode=mode, noupdate=noupdate, res_id=res_id, context=context) except Exception, e: import psycopg2 + import osv if isinstance(e,psycopg2.IntegrityError): - msg= _('Insertion Failed!') + msg= _('Insertion Failed! ') for key in self.pool._sql_error.keys(): if key in e[0]: msg = self.pool._sql_error[key] break - return (-1, res,'Line ' + str(counter) +' : ' + msg,'' ) - + return (-1, res, 'Line ' + str(counter) +' : ' + msg, '' ) + if isinstance(e, osv.orm.except_orm ): + msg = _('Insertion Failed! ' + e[1]) + return (-1, res, 'Line ' + str(counter) +' : ' + msg, '' ) for lang in translate: context2 = context.copy() context2['lang'] = lang From 9c806c8d58c33356c2a2009569871b585a2ae0e8 Mon Sep 17 00:00:00 2001 From: "VRA(OpenERP)" <> Date: Wed, 18 Nov 2009 12:49:26 +0530 Subject: [PATCH 33/60] [FIX] Account_invoice_layout : Reports improved and SXWs made compatible to RML bzr revid: jvo@tinyerp.com-20091118071926-mbvsj1mniomge7ho --- .../report/report_account_invoice_layout.rml | 784 +++++++++++------ .../report/special_message_invoice.py | 14 +- .../report/special_message_invoice.rml | 806 ++++++++++++------ 3 files changed, 1067 insertions(+), 537 deletions(-) diff --git a/addons/account_invoice_layout/report/report_account_invoice_layout.rml b/addons/account_invoice_layout/report/report_account_invoice_layout.rml index 74d33a8e5ec..e8f1cee42f3 100644 --- a/addons/account_invoice_layout/report/report_account_invoice_layout.rml +++ b/addons/account_invoice_layout/report/report_account_invoice_layout.rml @@ -1,263 +1,525 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -[[ repeatIn(objects,'o') ]] -[[ setLang(o.partner_id.lang) ]] - - - - - [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] - [[ o.address_invoice_id.title or '' ]] [[ o.address_invoice_id.name ]] - [[ o.address_invoice_id.street ]] - [[ o.address_invoice_id.street2 or '' ]] - [[ o.address_invoice_id.zip or '' ]] [[ o.address_invoice_id.city or '' ]] - [[ o.address_invoice_id.state_id and o.address_invoice_id.state_id.name or '' ]] - [[ o.address_invoice_id.country_id and o.address_invoice_id.country_id.name or '' ]] - - Tel. : [[ o.address_invoice_id.phone or removeParentNode('para') ]] - Fax : [[ o.address_invoice_id.fax or removeParentNode('para') ]] - VAT : [[ o.partner_id.vat or removeParentNode('para') ]] - - - - - - -Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]] -PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma') or removeParentNode('para')) and '' ]] -Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]] -Cancelled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] -Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] -Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] -Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]][[ o.number ]] - - - -Document:[[ o.name ]] - -Invoice Date: [[ formatLang(o.date_invoice,date=True) ]] -Customer Ref:[[ o.address_invoice_id.partner_id.ref or '/' ]] - - - - - -Description / Taxes -Quantity -Unit Price -Disc. (%) -Price - - -
- [[ repeatIn(invoice_lines(o), 'a') ]] - - - [[ a['type']=='text' and removeParentNode('blockTable')]] - [[ (a['type']=='title' or a['type']=='subtotal') and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['name'] ]] / ( [[ a['tax_types'] ]] ) - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['quantity'] ]] - [[ a['uos'] ]] - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['price_unit'] ]] - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['discount'] ]] - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['price_subtotal'] ]] [[ a['currency'] ]] - - - - Note : [[ format(a['note']) or removeParentNode('tr') ]] - - - - - - - - - - [[ a['type']=='text' and format(a['name']) or removeParentNode('blockTable') ]] - [[ a['type']=='text' and '' ]] - - - [[ a['type']!='break' and removeParentNode('pageBreak')]] - - - Description/Taxes [[ a['type']!='break' and removeParentNode('blockTable')]] - Quantity - Unit Price - Disc. (%) - Price - - -
- - - - - - - - - - - - - - - - - - - - Total (Excl. taxes): - [[ '%.2f' % o.amount_untaxed ]] [[o.currency_id.code ]] - - - Taxes: - [[ '%.2f' % o.amount_tax ]] [[o.currency_id.code ]] - - - Total (Incl. taxes): - [[ '%.2f' % o.amount_total ]] [[o.currency_id.code ]] - - - - - - - - - - - Tax - Base - Amount - - - [[ repeatIn(o.tax_line,'t') ]][[ t.name ]] - [[ '%.2f' % t.base ]] - [[ '%.2f' % t.amount]] - - - - - - - - - - - - - - - - - - - - - - -[[ format(o.comment) or removeParentNode('para') ]] -[[ format(o.payment_term and o.payment_term.note) or removeParentNode('para') ]] -
-
\ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ repeatIn(objects,'o') ]] + [[ setLang(o.partner_id.lang) ]] + + + + + + + + + [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] + [[ o.address_invoice_id.title or '' ]] [[ o.address_invoice_id.name ]] + [[ o.address_invoice_id.street ]] + [[ o.address_invoice_id.street2 or '' ]] + [[ o.address_invoice_id.zip or '' ]] [[ o.address_invoice_id.city or '' ]] + [[ o.address_invoice_id.state_id and o.address_invoice_id.state_id.name or '' ]] + [[ o.address_invoice_id.country_id and o.address_invoice_id.country_id.name or '' ]] + + + + Tel. : [[ o.address_invoice_id.phone or removeParentNode('para') ]] + Fax : [[ o.address_invoice_id.fax or removeParentNode('para') ]] + VAT : [[ o.partner_id.vat or removeParentNode('para') ]] + + + + + + + Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]] + PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma2') or removeParentNode('para')) and '' ]] + Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]] + Cancelled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]] + Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] + Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] + Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]] + + + + + + + + + + Document + + + Invoice Date + + + Partner Ref. + + + + + + + [[ o.name ]] + + + [[ formatLang(o.date_invoice,date=True) ]] + + + [[ o.address_invoice_id.partner_id.ref or '' ]] + + + + + + + + + + Description / Taxes + + + Quantity + + + Unit Price + + + Disc. (%) + + + Price + + + +
+ [[ repeatIn(invoice_lines(o), 'a') ]] + + + + [[ a['type']=='text' and removeParentNode('blockTable')]] + + + [[ (a['type']=='title' or a['type']=='subtotal') and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['name'] ]] [[ a['type']=='article' and ('/ (' + a['tax_types'] + ')' ) ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['quantity'] ]] + + + [[ a['uos'] ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['price_unit'] ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['discount'] ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]] [[ a['price_subtotal'] ]] + + + [[ a['currency'] ]] + + + + + + + + + + Note: [[ format(a['note']) or removeParentNode('tr') ]] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ a['type']=='text' and format(a['name']) or removeParentNode('blockTable') ]] + + + [[ a['type']=='text' and '' ]] + + + + [[ a['type']!='break' and removeParentNode('pageBreak')]] + + + + Description / Taxes [[ a['type']!='break' and removeParentNode('blockTable')]] + + + Quantity + + + Unit Price + + + Disc. (%) + + + Price + + + + +
+ + + + + + + + + + + + Net Total: + + + [[ formatLang(o.amount_untaxed) ]] + + + [[ o.currency_id.code ]] + + + + + + + + + + + + + + + Taxes: + + + [[ formatLang(o.amount_tax) ]] + + + [[ o.currency_id.code ]] + + + + + + + + + + + + + + + Total: + + + [[ formatLang(o.amount_total) ]] + + + [[ o.currency_id.code ]] + + + + + + + + + + + + + Tax + + + Base + + + Amount + + + + + + + + + + + +
+ [[ repeatIn(o.tax_line,'t') ]] + + + + [[ t.name ]] + + + [[ formatLang(t.base) ]] + + + [[ (t.tax_code_id and t.tax_code_id.notprintable) and removeParentNode('blockTable') or '' ]] [[ formatLang(t.amount) ]] + + + + + + + + + + + +
+ + + + + + + [[ format(o.comment or removeParentNode('blockTable')) ]] + + + + + + + + + + [[ format((o.payment_term and o.payment_term.note) or removeParentNode('blockTable')) ]] + + + + + + +
+ diff --git a/addons/account_invoice_layout/report/special_message_invoice.py b/addons/account_invoice_layout/report/special_message_invoice.py index 94dff32a54e..e814461ae44 100644 --- a/addons/account_invoice_layout/report/special_message_invoice.py +++ b/addons/account_invoice_layout/report/special_message_invoice.py @@ -132,14 +132,14 @@ class account_invoice_with_message(report_sxw.rml_parse): res['price_subtotal']='' res['currency']='' elif entry.state=='line': - res['quantity']='___________________' - res['price_unit']='______________________' - res['discount']='____________________________________' - res['tax_types']='_____________________' + res['quantity']='_______________' + res['price_unit']='______________' + res['discount']='____________' + res['tax_types']='____________________' res['uos']='_____' - res['name']='______________________________________' - res['price_subtotal']='___________' - res['currency']='_' + res['name']='_______________________________________________' + res['price_subtotal']='____________' + res['currency']='____' elif entry.state=='break': res['type']=entry.state res['name']=entry.name diff --git a/addons/account_invoice_layout/report/special_message_invoice.rml b/addons/account_invoice_layout/report/special_message_invoice.rml index b227ee0c3d0..133fffe5c0f 100644 --- a/addons/account_invoice_layout/report/special_message_invoice.rml +++ b/addons/account_invoice_layout/report/special_message_invoice.rml @@ -1,272 +1,540 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -[[ repeatIn(objects,'o') ]] -[[ setLang(o.partner_id.lang) ]] - - - - - [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] - [[ o.address_invoice_id.title or '' ]] [[ o.address_invoice_id.name ]] - [[ o.address_invoice_id.street ]] - [[ o.address_invoice_id.street2 or '' ]] - [[ o.address_invoice_id.zip or '' ]] [[ o.address_invoice_id.city or '' ]] - [[ o.address_invoice_id.state_id and o.address_invoice_id.state_id.name or '' ]] - [[ o.address_invoice_id.country_id and o.address_invoice_id.country_id.name or '' ]] - - - - Tel. : [[ o.address_invoice_id.phone or removeParentNode('para') ]] - Fax : [[ o.address_invoice_id.fax or removeParentNode('para') ]] - VAT : [[ o.partner_id.vat or removeParentNode('para') ]] - - - - - - -Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]] -PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma') or removeParentNode('para')) and '' ]] -Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]] -Cancelled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]] -Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] -Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] -Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]][[ o.number ]] - - - -Document:[[o.name]] - -Invoice Date: [[ formatLang(o.date_invoice,date=True) ]] -Customer Ref: [[ o.address_invoice_id.partner_id.ref or '/' ]] - - - -Description / Taxes -Quantity -Unit Price -Disc. (%) -Price - - -
- [[ repeatIn(invoice_lines(o), 'a') ]] - - - [[ a['type']=='text' and removeParentNode('blockTable')]] - [[ (a['type']=='title' or a['type']=='subtotal') and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['name'] ]] / ( [[ a['tax_types'] ]] ) - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['quantity'] ]] - [[ a['uos'] ]] - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['price_unit'] ]] - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['discount'] ]] - [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['price_subtotal'] ]] [[ a['currency'] ]] - - - - Note : [[ format(a['note']) or removeParentNode('tr') ]] - - - - - - - - - - [[ a['type']=='text' and format(a['name']) or removeParentNode('blockTable') ]] - [[ a['type']=='text' and '' ]] - - - [[ a['type']!='break' and removeParentNode('pageBreak')]] - - - Description/Taxes [[ a['type']!='break' and removeParentNode('blockTable')]] - Quantity - Unit Price - Disc. (%) - Price - - -
- - - - - - - - - - - - - - - - - - - - Total (Excl. taxes): - [[ '%.2f' % o.amount_untaxed ]] [[o.currency_id.code ]] - - - Taxes: - [[ '%.2f' % o.amount_tax ]] [[o.currency_id.code ]] - - - Total (Incl. taxes): - [[ '%.2f' % o.amount_total ]] [[o.currency_id.code ]] - - - - - - - - - - - Tax - Base - Amount - - - [[ repeatIn(o.tax_line,'t') ]][[ t.name ]] - [[ '%.2f' % t.base ]] - [[ '%.2f' % t.amount]] - - - - - - - - - - - - - - - - - - - - - - -[[ format(o.comment) or removeParentNode('para') ]] -[[ format(o.payment_term and o.payment_term.note) or removeParentNode('para') ]] - - - -
-[[ repeatIn((spcl_msg(data['form']) and spcl_msg(data['form']).splitlines()) or [], 'note') ]] -[[ format(note) or removeParentNode('para') ]] -
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ repeatIn(objects,'o') ]] + [[ setLang(o.partner_id.lang) ]] + + + + + + + + + [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] + [[ o.address_invoice_id.title or '' ]] [[ o.address_invoice_id.name ]] + [[ o.address_invoice_id.street ]] + [[ o.address_invoice_id.street2 or '' ]] + [[ o.address_invoice_id.zip or '' ]] [[ o.address_invoice_id.city or '' ]] + [[ o.address_invoice_id.state_id and o.address_invoice_id.state_id.name or '' ]] + [[ o.address_invoice_id.country_id and o.address_invoice_id.country_id.name or '' ]] + + + + Tel. : [[ o.address_invoice_id.phone or removeParentNode('para') ]] + Fax : [[ o.address_invoice_id.fax or removeParentNode('para') ]] + VAT : [[ o.partner_id.vat or removeParentNode('para') ]] + + + + + + + Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]] + PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma2') or removeParentNode('para')) and '' ]] + Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]] + Cancelled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]] + Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] + Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]] + Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]] + + + + + + + + + + Document + + + Invoice Date + + + Partner Ref. + + + + + + + [[ o.name ]] + + + [[ formatLang(o.date_invoice,date=True) ]] + + + [[ o.address_invoice_id.partner_id.ref or '' ]] + + + + + + + + + + Description / Taxes + + + Quantity + + + Unit Price + + + Disc. (%) + + + Price + + + +
+ [[ repeatIn(invoice_lines(o), 'a') ]] + + + + [[ a['type']=='text' and removeParentNode('blockTable')]] + + + [[ (a['type']=='title' or a['type']=='subtotal') and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['name'] ]] [[ a['type']=='article' and ('/ (' + a['tax_types'] +')' ) ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['quantity'] ]] + + + [[ a['uos'] ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['price_unit'] ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]][[ a['discount'] ]] + + + [[ a['type']=='subtotal' and ( setTag('para','para',{'fontName':'Helvetica-bold'})) ]] [[ a['price_subtotal'] ]] + + + [[ a['currency'] ]] + + + + + + + + + + Note: [[ format(a['note']) or removeParentNode('tr') ]] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ a['type']=='text' and format(a['name']) or removeParentNode('blockTable') ]] + + + [[ a['type']=='text' and '' ]] + + + + [[ a['type']!='break' and removeParentNode('pageBreak')]] + + + + Description / Taxes [[ a['type']!='break' and removeParentNode('blockTable')]] + + + Quantity + + + Unit Price + + + Disc. (%) + + + Price + + + + +
+ + + + + + + + + + + + Net Total: + + + [[ formatLang(o.amount_untaxed) ]] + + + [[ o.currency_id.code ]] + + + + + + + + + + + + + + + Taxes: + + + [[ formatLang(o.amount_tax) ]] + + + [[ o.currency_id.code ]] + + + + + + + + + + + + + + + Total: + + + [[ formatLang(o.amount_total) ]] + + + [[ o.currency_id.code ]] + + + + + + + + + + + + + Tax + + + Base + + + Amount + + + + + + + + + + + +
+ [[ repeatIn(o.tax_line,'t') ]] + + + + [[ t.name ]] + + + [[ formatLang(t.base) ]] + + + [[ (t.tax_code_id and t.tax_code_id.notprintable) and removeParentNode('blockTable') or '' ]] [[ formatLang(t.amount) ]] + + + + + + + + + + + +
+ + + + + + + [[ format(o.comment or removeParentNode('blockTable')) ]] + + + + + + + + + + [[ format((o.payment_term and o.payment_term.note) or removeParentNode('blockTable')) ]] + + + + + + + + + + [[ repeatIn((spcl_msg(data['form']) and spcl_msg(data['form']).splitlines()) or [], 'note') ]] + [[ note or removeParentNode('para') ]] + + + + + + +
From f00cab1850bff234877034bb30a4e866b450a444 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Nov 2009 12:01:06 +0100 Subject: [PATCH 34/60] Fix indentation in account_tax_code bzr revid: xmo@tinyerp.com-20091118110106-u5wwbfv7rqwzkdyb --- addons/account/report/account_tax_code.py | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/addons/account/report/account_tax_code.py b/addons/account/report/account_tax_code.py index f3c3fb75e47..8c1c94552d0 100644 --- a/addons/account/report/account_tax_code.py +++ b/addons/account/report/account_tax_code.py @@ -43,20 +43,20 @@ class account_tax_code_report(rml_parse.rml_parse): if line_ids: move_line_objs = self.pool.get('account.move.line').browse(self.cr,self.uid,line_ids) for line in move_line_objs: - res['date'] = line.date - res['ref'] = line.ref - res['acode'] = line.account_id.code - res['pname'] = '' - res['country'] = '' - - if line.partner_id: - res['pname'] = line.partner_id.name - if line.partner_id.address and line.partner_id.address[0].country_id: - res['country'] = line.partner_id.address[0].country_id.code - res['name'] = line.name - res['debit'] = line.debit - res['credit'] = line.credit - result.append(res) + res['date'] = line.date + res['ref'] = line.ref + res['acode'] = line.account_id.code + res['pname'] = '' + res['country'] = '' + + if line.partner_id: + res['pname'] = line.partner_id.name + if line.partner_id.address and line.partner_id.address[0].country_id: + res['country'] = line.partner_id.address[0].country_id.code + res['name'] = line.name + res['debit'] = line.debit + res['credit'] = line.credit + result.append(res) return result From f4f099b7942925106d1511c1eafbf51b877bdd1d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Nov 2009 12:03:33 +0100 Subject: [PATCH 35/60] Fix bug in account tax code report. Res dict created only once at the start of the function, would lead to all result.append appending the same objects, and result being filled only with a bunch of instances of the last iteration round. Fix by creating new res dict at the start of each round. bzr revid: xmo@tinyerp.com-20091118110333-tc7vygl2bk7cifer --- addons/account/report/account_tax_code.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/report/account_tax_code.py b/addons/account/report/account_tax_code.py index 8c1c94552d0..3e5efa65e9a 100644 --- a/addons/account/report/account_tax_code.py +++ b/addons/account/report/account_tax_code.py @@ -37,12 +37,12 @@ class account_tax_code_report(rml_parse.rml_parse): }) def get_line(self,obj): - res = {} result = [] line_ids = self.pool.get('account.move.line').search(self.cr,self.uid,[('tax_code_id','=',obj.id)]) if line_ids: move_line_objs = self.pool.get('account.move.line').browse(self.cr,self.uid,line_ids) for line in move_line_objs: + res = {} res['date'] = line.date res['ref'] = line.ref res['acode'] = line.account_id.code From 047d799e9794c8983d803d653a866c2f8aa77f9d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Nov 2009 12:10:07 +0100 Subject: [PATCH 36/60] Move unconditional items affectation (and a basic conditional one) into res dict litteral bzr revid: xmo@tinyerp.com-20091118111007-3b1ojrkcmq6wf5sa --- addons/account/report/account_tax_code.py | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/addons/account/report/account_tax_code.py b/addons/account/report/account_tax_code.py index 3e5efa65e9a..83b948f0cce 100644 --- a/addons/account/report/account_tax_code.py +++ b/addons/account/report/account_tax_code.py @@ -42,20 +42,22 @@ class account_tax_code_report(rml_parse.rml_parse): if line_ids: move_line_objs = self.pool.get('account.move.line').browse(self.cr,self.uid,line_ids) for line in move_line_objs: - res = {} - res['date'] = line.date - res['ref'] = line.ref - res['acode'] = line.account_id.code - res['pname'] = '' - res['country'] = '' + res = {'date': line.date, + 'ref': line.ref, + 'acode': line.account_id.code, + 'name': line.name, + 'debit': line.debit, + 'credit': line.credit, + 'pname': line.partner_id and line.partner_id.name or '', + } - if line.partner_id: - res['pname'] = line.partner_id.name - if line.partner_id.address and line.partner_id.address[0].country_id: - res['country'] = line.partner_id.address[0].country_id.code - res['name'] = line.name - res['debit'] = line.debit - res['credit'] = line.credit + if line.partner_id \ + and line.partner_id.address \ + and line.partner_id.address[0].country_id: + res['country'] = line.partner_id.address[0].country_id.code + else: + res['country'] = '' + result.append(res) return result From 00927a64846b188e7c210139e8975f035f733f92 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Nov 2009 12:11:16 +0100 Subject: [PATCH 37/60] Inverse line_ids test to return early and lower indentation level of function body bzr revid: xmo@tinyerp.com-20091118111116-xooviyckwtndpaz2 --- addons/account/report/account_tax_code.py | 43 ++++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/addons/account/report/account_tax_code.py b/addons/account/report/account_tax_code.py index 83b948f0cce..4c284e28528 100644 --- a/addons/account/report/account_tax_code.py +++ b/addons/account/report/account_tax_code.py @@ -37,29 +37,30 @@ class account_tax_code_report(rml_parse.rml_parse): }) def get_line(self,obj): - result = [] line_ids = self.pool.get('account.move.line').search(self.cr,self.uid,[('tax_code_id','=',obj.id)]) - if line_ids: - move_line_objs = self.pool.get('account.move.line').browse(self.cr,self.uid,line_ids) - for line in move_line_objs: - res = {'date': line.date, - 'ref': line.ref, - 'acode': line.account_id.code, - 'name': line.name, - 'debit': line.debit, - 'credit': line.credit, - 'pname': line.partner_id and line.partner_id.name or '', - } + if not line_ids: return [] + + result = [] + move_line_objs = self.pool.get('account.move.line').browse(self.cr,self.uid,line_ids) + for line in move_line_objs: + res = {'date': line.date, + 'ref': line.ref, + 'acode': line.account_id.code, + 'name': line.name, + 'debit': line.debit, + 'credit': line.credit, + 'pname': line.partner_id and line.partner_id.name or '', + } + + if line.partner_id \ + and line.partner_id.address \ + and line.partner_id.address[0].country_id: + res['country'] = line.partner_id.address[0].country_id.code + else: + res['country'] = '' + + result.append(res) - if line.partner_id \ - and line.partner_id.address \ - and line.partner_id.address[0].country_id: - res['country'] = line.partner_id.address[0].country_id.code - else: - res['country'] = '' - - result.append(res) - return result report_sxw.report_sxw('report.account.tax.code.entries', 'account.tax.code', From 63298c2cbf6dc698fe7ef9a0c27a7a43305e1372 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Nov 2009 12:28:55 +0100 Subject: [PATCH 38/60] split get_line into helper functions, map over browse_records instead of imperative iteration bzr revid: xmo@tinyerp.com-20091118112855-2dftiyn131em5nk3 --- addons/account/report/account_tax_code.py | 45 ++++++++++++----------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/addons/account/report/account_tax_code.py b/addons/account/report/account_tax_code.py index 4c284e28528..17b549e1eb1 100644 --- a/addons/account/report/account_tax_code.py +++ b/addons/account/report/account_tax_code.py @@ -26,6 +26,25 @@ import copy from report import report_sxw import re +def _get_country(record): + if record.partner_id \ + and record.partner_id.address \ + and record.partner_id.address[0].country_id: + return record.partner_id.address[0].country_id.code + else: + return '' + +def _record_to_report_line(record): + return {'date': record.date, + 'ref': record.ref, + 'acode': record.account_id.code, + 'name': record.name, + 'debit': record.debit, + 'credit': record.credit, + 'pname': record.partner_id and record.partner_id.name or '', + 'country': _get_country(record) + } + class account_tax_code_report(rml_parse.rml_parse): #_name = 'report.account.tax.code.entries' @@ -40,28 +59,10 @@ class account_tax_code_report(rml_parse.rml_parse): line_ids = self.pool.get('account.move.line').search(self.cr,self.uid,[('tax_code_id','=',obj.id)]) if not line_ids: return [] - result = [] - move_line_objs = self.pool.get('account.move.line').browse(self.cr,self.uid,line_ids) - for line in move_line_objs: - res = {'date': line.date, - 'ref': line.ref, - 'acode': line.account_id.code, - 'name': line.name, - 'debit': line.debit, - 'credit': line.credit, - 'pname': line.partner_id and line.partner_id.name or '', - } - - if line.partner_id \ - and line.partner_id.address \ - and line.partner_id.address[0].country_id: - res['country'] = line.partner_id.address[0].country_id.code - else: - res['country'] = '' - - result.append(res) - - return result + return map(_record_to_report_line, + self.pool.get('account.move.line')\ + .browse(self.cr, self.uid, line_ids)) + report_sxw.report_sxw('report.account.tax.code.entries', 'account.tax.code', 'addons/account/report/account_tax_code.rml', parser=account_tax_code_report, header=False) From ccffde3c9b743eba6d30fd5399f59d05ad3be223 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Nov 2009 12:33:23 +0100 Subject: [PATCH 39/60] Small PEP8 and PEP263 fixes bzr revid: xmo@tinyerp.com-20091118113323-03fo5i7edvcivxmu --- addons/account/report/account_tax_code.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/account/report/account_tax_code.py b/addons/account/report/account_tax_code.py index 17b549e1eb1..3dc73cb4999 100644 --- a/addons/account/report/account_tax_code.py +++ b/addons/account/report/account_tax_code.py @@ -1,4 +1,5 @@ -# -*- encoding: utf-8 -*- +#!/usr/bin/env python +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution @@ -55,15 +56,14 @@ class account_tax_code_report(rml_parse.rml_parse): 'get_line':self.get_line, }) - def get_line(self,obj): - line_ids = self.pool.get('account.move.line').search(self.cr,self.uid,[('tax_code_id','=',obj.id)]) + def get_line(self, obj): + line_ids = self.pool.get('account.move.line').search(self.cr, self.uid, [('tax_code_id','=',obj.id)]) if not line_ids: return [] return map(_record_to_report_line, self.pool.get('account.move.line')\ .browse(self.cr, self.uid, line_ids)) - report_sxw.report_sxw('report.account.tax.code.entries', 'account.tax.code', 'addons/account/report/account_tax_code.rml', parser=account_tax_code_report, header=False) From 5e0481ff69f6044b4a80a8cc17da66eb35f10691 Mon Sep 17 00:00:00 2001 From: "ACH(OpenERP)" <> Date: Wed, 18 Nov 2009 17:40:11 +0530 Subject: [PATCH 40/60] [FIX] Stock : Forecast report: unicode error corrected lp bug: https://launchpad.net/bugs/481524 fixed bzr revid: jvo@tinyerp.com-20091118121011-i9ggw4sze11f1bem --- addons/stock/report/product_stock.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/stock/report/product_stock.py b/addons/stock/report/product_stock.py index 3f1b65b21fb..b5ca5aae0ee 100644 --- a/addons/stock/report/product_stock.py +++ b/addons/stock/report/product_stock.py @@ -57,6 +57,8 @@ class report_stock(report_int): dt_to = now names = dict(pooler.get_pool(cr.dbname).get('product.product').name_get(cr, uid, product_ids)) + for name in names: + names[name] = names[name].encode('utf8') products = {} prods = pooler.get_pool(cr.dbname).get('stock.location')._product_all_get(cr, uid, location_id, product_ids) From ba6ab77a901091275de159039f3eab9f33c81742 Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Thu, 19 Nov 2009 12:33:10 +0530 Subject: [PATCH 41/60] [FIX] Stock : Added translations bzr revid: jvo@tinyerp.com-20091119070310-qamq5vgahyau0ax3 --- addons/stock/i18n/de_DE.po | 5 +++++ addons/stock/i18n/fr_FR.po | 5 +++++ addons/stock/i18n/stock.pot | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/addons/stock/i18n/de_DE.po b/addons/stock/i18n/de_DE.po index 7fbdee98828..6385b61f358 100644 --- a/addons/stock/i18n/de_DE.po +++ b/addons/stock/i18n/de_DE.po @@ -646,6 +646,11 @@ msgstr "Erledigt am" msgid "Expected Shipping Date" msgstr "Erwartete Auslieferung" +#. module: stock +#: rml:stock.picking.list:0 +msgid "Shipping Address :" +msgstr "Lieferanschrift:" + #. module: stock #: view:stock.tracking:0 msgid "Tracking/Serial" diff --git a/addons/stock/i18n/fr_FR.po b/addons/stock/i18n/fr_FR.po index 7a522d0ae68..ede2e856faa 100644 --- a/addons/stock/i18n/fr_FR.po +++ b/addons/stock/i18n/fr_FR.po @@ -646,6 +646,11 @@ msgstr "Date de fin" msgid "Expected Shipping Date" msgstr "Date d'envoi prévue" +#. module: stock +#: rml:stock.picking.list:0 +msgid "Shipping Address :" +msgstr "Adresse de livraison :" + #. module: stock #: view:stock.tracking:0 msgid "Tracking/Serial" diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index f7efc219bb1..b33a6e18ff1 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -646,6 +646,11 @@ msgstr "" msgid "Expected Shipping Date" msgstr "" +#. module: stock +#: rml:stock.picking.list:0 +msgid "Shipping Address :" +msgstr "" + #. module: stock #: view:stock.tracking:0 msgid "Tracking/Serial" From 7fc05f47d1d224be45adbc971951d147d6aa14d8 Mon Sep 17 00:00:00 2001 From: "VRA(OpenERP)" <> Date: Thu, 19 Nov 2009 12:39:17 +0530 Subject: [PATCH 42/60] [FIX] Sale : Passing customer ref. of picking to invoice lp bug: https://launchpad.net/bugs/443132 fixed bzr revid: jvo@tinyerp.com-20091119070917-b8p0hzgki08pyhij --- addons/sale/stock.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/addons/sale/stock.py b/addons/sale/stock.py index 9e3cd377f03..af1bfb2aa69 100644 --- a/addons/sale/stock.py +++ b/addons/sale/stock.py @@ -131,13 +131,19 @@ class stock_picking(osv.osv): for invoice in invoice_obj.browse(cursor, user, invoice_ids, context=context): invoices[invoice.id] = invoice - + for picking in picking_obj.browse(cursor, user, picking_ids, context=context): if not picking.sale_id: continue sale_lines = picking.sale_id.order_line + invoice_created = invoices[result[picking.id]] + + if picking.sale_id.client_order_ref: + inv_name = picking.sale_id.client_order_ref + " : " + invoice_created.name + invoice_obj.write(cursor, user, [invoice_created.id], {'name': inv_name}, context=context) + for sale_line in sale_lines: if sale_line.product_id.type == 'service' and sale_line.invoiced == False: if group: From 47aae24a3a0b6a61412f2b5b1429b74935ea4293 Mon Sep 17 00:00:00 2001 From: "VRA(OpenERP)" <> Date: Thu, 19 Nov 2009 12:45:19 +0530 Subject: [PATCH 43/60] [FIX] Sale/Purcghase : Function fields did not have digits attribute for precision accuracy lp bug: https://launchpad.net/bugs/483583 fixed bzr revid: jvo@tinyerp.com-20091119071519-x938niic7c4uayms --- addons/purchase/purchase.py | 6 +++--- addons/sale/sale.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 521549cf472..46a17ea5ada 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -181,15 +181,15 @@ class purchase_order(osv.osv): "Manual: no invoice will be pre-generated. The accountant will have to encode manually." ), 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Planned Date', type='datetime', help="This is computed as the minimum scheduled date of all purchase order lines' products."), - 'amount_untaxed': fields.function(_amount_all, method=True, string='Untaxed Amount', + 'amount_untaxed': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Untaxed Amount', store={ 'purchase.order.line': (_get_order, None, 10), }, multi="sums"), - 'amount_tax': fields.function(_amount_all, method=True, string='Taxes', + 'amount_tax': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Taxes', store={ 'purchase.order.line': (_get_order, None, 10), }, multi="sums"), - 'amount_total': fields.function(_amount_all, method=True, string='Total', + 'amount_total': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Total', store={ 'purchase.order.line': (_get_order, None, 10), }, multi="sums"), diff --git a/addons/sale/sale.py b/addons/sale/sale.py index d43c7533e86..0b3116f5fe0 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -234,19 +234,19 @@ class sale_order(osv.osv): fnct_search=_invoiced_search, type='boolean'), 'note': fields.text('Notes'), - 'amount_untaxed': fields.function(_amount_all, method=True, string='Untaxed Amount', + 'amount_untaxed': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Untaxed Amount', store = { 'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10), 'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10), }, multi='sums'), - 'amount_tax': fields.function(_amount_all, method=True, string='Taxes', + 'amount_tax': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Taxes', store = { 'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10), 'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10), }, multi='sums'), - 'amount_total': fields.function(_amount_all, method=True, string='Total', + 'amount_total': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Total', store = { 'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10), 'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10), From 2a72c47e521d066f3ce1c2ecc23c4b6e6054d9fd Mon Sep 17 00:00:00 2001 From: "VRA(OpenERP)" <> Date: Fri, 20 Nov 2009 10:56:20 +0530 Subject: [PATCH 44/60] [FIX] Account : Ledger Report Landscape report adjusted for A4. lp bug: https://launchpad.net/bugs/458030 fixed bzr revid: jvo@tinyerp.com-20091120052620-qd1i52t33m6zzg4g --- addons/account/report/general_ledger_landscape.rml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/report/general_ledger_landscape.rml b/addons/account/report/general_ledger_landscape.rml index b0b2181550c..9e937a72baf 100644 --- a/addons/account/report/general_ledger_landscape.rml +++ b/addons/account/report/general_ledger_landscape.rml @@ -1,6 +1,6 @@ -