Merge and bugfixes from jvo
bzr revid: hda@tinyerp.com-20091105063915-kju1oce56t9g20g5
This commit is contained in:
commit
5ea54704ea
|
@ -11298,3 +11298,63 @@ msgstr ""
|
|||
msgid "Russian / русский язык"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.user:0
|
||||
msgid "You cannot have two users with the same login !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:ir.model.data:0
|
||||
msgid "You cannot have multiple records with the same id for the same module"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:maintenance.contract:0
|
||||
msgid "Your maintenance contract is already subscribed in the system !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:ir.module.module:0
|
||||
msgid "The name of the module must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.partner.function:0
|
||||
msgid "The Code of the Partner Function must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.partner:0
|
||||
msgid "The name of the Partner must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.country:0
|
||||
msgid "The name of the country must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.country:0
|
||||
msgid "The code of the country must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.lang:0
|
||||
msgid "The name of the language must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.lang:0
|
||||
msgid "The code of the language must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: code:addons/osv/osv.py:0
|
||||
#, python-format
|
||||
msgid "Constraint Error"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.translation,type:0
|
||||
msgid "SQL Constraint"
|
||||
msgstr ""
|
|
@ -11311,3 +11311,62 @@ msgstr "Sri Lanka"
|
|||
msgid "Russian / русский язык"
|
||||
msgstr "Russie / русский язык"
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.user:0
|
||||
msgid "You cannot have two users with the same login !"
|
||||
msgstr "Vous ne pouvez pas avoir deux utilisateurs avec le même login!"
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:ir.model.data:0
|
||||
msgid "You cannot have multiple records with the same id for the same module"
|
||||
msgstr "Vous ne pouvez pas avoir de rapports multiples avec le même id pour le même module"
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:maintenance.contract:0
|
||||
msgid "Your maintenance contract is already subscribed in the system !"
|
||||
msgstr "Votre contrat d'entretien est déjà souscrit dans le système ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:ir.module.module:0
|
||||
msgid "The name of the module must be unique !"
|
||||
msgstr "Le nom du module doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.partner.function:0
|
||||
msgid "The Code of the Partner Function must be unique !"
|
||||
msgstr "Le Code de la Fonction de Partenaire doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.partner:0
|
||||
msgid "The name of the Partner must be unique !"
|
||||
msgstr "Le nom du Partenaire doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.country:0
|
||||
msgid "The name of the country must be unique !"
|
||||
msgstr "Le nom du pays doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.country:0
|
||||
msgid "The code of the country must be unique !"
|
||||
msgstr "Le code du pays doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.lang:0
|
||||
msgid "The name of the language must be unique !"
|
||||
msgstr "Le nom de la langue doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.lang:0
|
||||
msgid "The code of the language must be unique !"
|
||||
msgstr "Le code de la langue doit être unique ! "
|
||||
|
||||
#. module: base
|
||||
#: code:osv.pool:0
|
||||
msgid "Constraint Error"
|
||||
msgstr "Erreur de contrainte"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.translation,type:0
|
||||
msgid "SQL Constraint"
|
||||
msgstr "SQL Contrainte"
|
|
@ -419,7 +419,7 @@ class ir_model_data(osv.osv):
|
|||
'module': lambda *a: ''
|
||||
}
|
||||
_sql_constraints = [
|
||||
('module_name_uniq', 'unique(name, module)', 'You can not have multiple records with the same id for the same module'),
|
||||
('module_name_uniq', 'unique(name, module)', 'You cannot have multiple records with the same id for the same module'),
|
||||
]
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
|
|
|
@ -107,6 +107,11 @@ class ir_rule(osv.osv):
|
|||
for rule in self.browse(cr, uid, ids, context):
|
||||
eval_user_data = {'user': self.pool.get('res.users').browse(cr, 1, uid),
|
||||
'time':time}
|
||||
if rule.operand.startswith('user.') and rule.operand.count('.') > 1:
|
||||
#Need to check user.field.field1.field2(if field is False,it will break the chain)
|
||||
op = rule.operand[5:]
|
||||
rule.operand = rule.operand[:5+len(op[:op.find('.')])] +' and '+ rule.operand + ' or False'
|
||||
|
||||
if rule.domain_force:
|
||||
res[rule.id] = eval(rule.domain_force, eval_user_data)
|
||||
else:
|
||||
|
|
|
@ -36,6 +36,7 @@ TRANSLATION_TYPE = [
|
|||
('help', 'Help'),
|
||||
('code', 'Code'),
|
||||
('constraint', 'Constraint'),
|
||||
('sql_constraint', 'SQL Constraint')
|
||||
]
|
||||
|
||||
class ir_translation(osv.osv):
|
||||
|
|
|
@ -166,9 +166,9 @@ class res_partner(osv.osv):
|
|||
'customer': lambda *a: 1,
|
||||
'category_id': _default_category,
|
||||
}
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
def copy(self, cr, uid, id, default={}, context={}):
|
||||
name = self.read(cr, uid, [id], ['name'])[0]['name']
|
||||
default.update({'name': name+' (copy)', 'events':[]})
|
||||
default.update({'name': name+ _(' (copy)'), 'events':[]})
|
||||
return super(res_partner, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def _check_ean_key(self, cr, uid, ids):
|
||||
|
|
|
@ -26,7 +26,6 @@ import ir
|
|||
|
||||
from tools.misc import currency
|
||||
from tools.translate import _
|
||||
from tools import config
|
||||
|
||||
import mx.DateTime
|
||||
from mx.DateTime import RelativeDateTime, now, DateTime, localtime
|
||||
|
@ -68,7 +67,7 @@ class res_currency(osv.osv):
|
|||
if currency.rounding == 0:
|
||||
return 0.0
|
||||
else:
|
||||
return round(amount / currency.rounding, int(config['price_accuracy'])) * currency.rounding
|
||||
return round(amount / currency.rounding) * currency.rounding
|
||||
|
||||
def is_zero(self, cr, uid, currency, amount):
|
||||
return abs(self.round(cr, uid, currency, amount)) < currency.rounding
|
||||
|
|
|
@ -135,7 +135,7 @@ class users(osv.osv):
|
|||
return result
|
||||
|
||||
_sql_constraints = [
|
||||
('login_key', 'UNIQUE (login)', 'You can not have two users with the same login !')
|
||||
('login_key', 'UNIQUE (login)', 'You cannot have two users with the same login !')
|
||||
]
|
||||
|
||||
def _get_admin_id(self, cr):
|
||||
|
|
216
bin/osv/orm.py
216
bin/osv/orm.py
|
@ -50,16 +50,16 @@ import pickle
|
|||
|
||||
import fields
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
import copy
|
||||
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
|
||||
|
||||
|
@ -521,7 +521,9 @@ class orm_template(object):
|
|||
for rr in r :
|
||||
if isinstance(rr.name, browse_record):
|
||||
rr = rr.name
|
||||
dt += rr.name or '' + ','
|
||||
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 '' + ','
|
||||
data[fpos] = dt[:-1]
|
||||
break
|
||||
lines += lines2[1:]
|
||||
|
@ -532,7 +534,8 @@ class orm_template(object):
|
|||
i += 1
|
||||
if i == len(f):
|
||||
if isinstance(r, browse_record):
|
||||
r = r.name
|
||||
r = self.pool.get(r._table_name).name_get(cr, uid, [r.id])
|
||||
r = r and r[0] and r[0][1] or ''
|
||||
data[fpos] = tools.ustr(r or '')
|
||||
return [data] + lines
|
||||
|
||||
|
@ -997,14 +1000,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 +1015,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 +1082,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
|
||||
|
@ -1093,7 +1094,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)
|
||||
|
@ -1104,8 +1105,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 +1112,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 +1179,71 @@ 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)
|
||||
return res and res[0]
|
||||
if node2.tag == 'xpath':
|
||||
res = node.xpath(node2.get('expr'))
|
||||
if res:
|
||||
return res[0]
|
||||
else:
|
||||
return None
|
||||
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)
|
||||
parent = node.getparent()
|
||||
if parent is None:
|
||||
src = copy.deepcopy(node2.getchildren()[0])
|
||||
else:
|
||||
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 +1295,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 +1323,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:
|
||||
|
@ -2145,6 +2145,20 @@ class orm(orm_template):
|
|||
for key, v in r.items():
|
||||
if v == None:
|
||||
r[key] = False
|
||||
if key in self._columns.keys():
|
||||
type = self._columns[key]._type
|
||||
elif key in self._inherit_fields.keys():
|
||||
type = self._inherit_fields[key][2]._type
|
||||
else:
|
||||
continue
|
||||
if type == 'reference' and v:
|
||||
model,ref_id = v.split(',')
|
||||
table = self.pool.get(model)._table
|
||||
cr.execute('select id from "%s" where id=%s' % (table,ref_id))
|
||||
id_exist = cr.fetchone()
|
||||
if not id_exist:
|
||||
cr.execute('update "'+self._table+'" set "'+key+'"=NULL where "%s"=%s' %(key,''.join("'"+str(v)+"'")))
|
||||
r[key] = ''
|
||||
|
||||
if isinstance(ids, (int, long)):
|
||||
return result and result[0] or False
|
||||
|
@ -3045,6 +3059,4 @@ class orm(orm_template):
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -34,6 +34,8 @@ from psycopg2 import IntegrityError
|
|||
from netsvc import Logger, LOG_ERROR
|
||||
from tools.misc import UpdateableDict
|
||||
|
||||
from tools.translate import _
|
||||
|
||||
module_list = []
|
||||
module_class_list = {}
|
||||
class_pool = {}
|
||||
|
@ -64,7 +66,7 @@ class osv_pool(netsvc.Service):
|
|||
except IntegrityError, inst:
|
||||
for key in self._sql_error.keys():
|
||||
if key in inst[0]:
|
||||
self.abortResponse(1, 'Constraint Error', 'warning', self._sql_error[key])
|
||||
self.abortResponse(1, _('Constraint Error'), 'warning', _(self._sql_error[key]))
|
||||
self.abortResponse(1, 'Integrity Error', 'warning', inst[0])
|
||||
except Exception, e:
|
||||
import traceback, sys
|
||||
|
|
|
@ -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 = '<?xml version="1.0"?>\n'+_process("".join([i.toxml().encode("utf8") for i in node.childNodes]), idref)
|
||||
# txt = '<?xml version="1.0"?>\n'+"".join([i.toxml().encode("utf8") for i in node.childNodes]) % idref
|
||||
|
||||
txt = '<?xml version="1.0"?>\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'(?<!\\)/')
|
||||
|
@ -205,31 +199,31 @@ class xml_import(object):
|
|||
|
||||
@staticmethod
|
||||
def nodeattr2bool(node, attr, default=False):
|
||||
if not node.hasAttribute(attr):
|
||||
if not node.get(attr):
|
||||
return default
|
||||
val = node.getAttribute(attr).strip()
|
||||
val = node.get(attr).strip()
|
||||
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.getAttribute('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:
|
||||
context = {}
|
||||
|
||||
node_context = node.getAttribute("context").encode('utf8')
|
||||
node_context = node.get("context",'').encode('utf8')
|
||||
if len(node_context):
|
||||
context.update(eval(node_context, eval_dict))
|
||||
|
||||
return context
|
||||
|
||||
def get_uid(self, cr, uid, data_node, node):
|
||||
node_uid = node.getAttribute('uid') or (data_node and data_node.getAttribute('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
|
||||
|
@ -249,9 +243,9 @@ form: module.record_id""" % (xml_id,)
|
|||
self.logger.notifyChannel('init', netsvc.LOG_ERROR, 'id: %s is to long (max: 64)'% (id,))
|
||||
|
||||
def _tag_delete(self, cr, rec, data_node=None):
|
||||
d_model = rec.getAttribute("model")
|
||||
d_search = rec.getAttribute("search")
|
||||
d_id = rec.getAttribute("id")
|
||||
d_model = rec.get("model",'')
|
||||
d_search = rec.get("search",'')
|
||||
d_id = rec.get("id",'')
|
||||
ids = []
|
||||
if len(d_search):
|
||||
ids = self.pool.get(d_model).search(cr,self.uid,eval(d_search))
|
||||
|
@ -269,24 +263,24 @@ form: module.record_id""" % (xml_id,)
|
|||
def _tag_report(self, cr, rec, data_node=None):
|
||||
res = {}
|
||||
for dest,f in (('name','string'),('model','model'),('report_name','name')):
|
||||
res[dest] = rec.getAttribute(f).encode('utf8')
|
||||
res[dest] = rec.get(f,'').encode('utf8')
|
||||
assert res[dest], "Attribute %s of report is empty !" % (f,)
|
||||
for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')):
|
||||
if rec.hasAttribute(field):
|
||||
res[dest] = rec.getAttribute(field).encode('utf8')
|
||||
if rec.hasAttribute('auto'):
|
||||
res['auto'] = eval(rec.getAttribute('auto'))
|
||||
if rec.hasAttribute('sxw'):
|
||||
sxw_content = misc.file_open(rec.getAttribute('sxw')).read()
|
||||
if rec.get(field):
|
||||
res[dest] = rec.get(field,'').encode('utf8')
|
||||
if rec.get('auto'):
|
||||
res['auto'] = eval(rec.get('auto',''))
|
||||
if rec.get('sxw'):
|
||||
sxw_content = misc.file_open(rec.get('sxw','')).read()
|
||||
res['report_sxw_content'] = sxw_content
|
||||
if rec.hasAttribute('header'):
|
||||
res['header'] = eval(rec.getAttribute('header'))
|
||||
res['multi'] = rec.hasAttribute('multi') and eval(rec.getAttribute('multi'))
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
if rec.get('header'):
|
||||
res['header'] = eval(rec.get('header',''))
|
||||
res['multi'] = rec.get('multi','') and eval(rec.get('multi',''))
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
|
||||
if rec.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
if rec.get('groups'):
|
||||
g_names = rec.get('groups','').split(',')
|
||||
groups_value = []
|
||||
groups_obj = self.pool.get('res.groups')
|
||||
for group in g_names:
|
||||
|
@ -300,13 +294,12 @@ 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.hasAttribute('menu') or eval(rec.getAttribute('menu')):
|
||||
keyword = str(rec.getAttribute('keyword') or 'client_print_multi')
|
||||
|
||||
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'])]
|
||||
value = 'ir.actions.report.xml,'+str(id)
|
||||
replace = rec.hasAttribute('replace') and rec.getAttribute("replace") or True
|
||||
replace = rec.get("replace",'') or True
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id)
|
||||
return False
|
||||
|
||||
|
@ -319,16 +312,16 @@ form: module.record_id""" % (xml_id,)
|
|||
return False
|
||||
|
||||
def _tag_wizard(self, cr, rec, data_node=None):
|
||||
string = rec.getAttribute("string").encode('utf8')
|
||||
model = rec.getAttribute("model").encode('utf8')
|
||||
name = rec.getAttribute("name").encode('utf8')
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
string = rec.get("string",'').encode('utf8')
|
||||
model = rec.get("model",'').encode('utf8')
|
||||
name = rec.get("name",'').encode('utf8')
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
multi = rec.hasAttribute('multi') and eval(rec.getAttribute('multi'))
|
||||
multi = rec.get('multi','') and eval(rec.get('multi',''))
|
||||
res = {'name': string, 'wiz_name': name, 'multi': multi, 'model': model}
|
||||
|
||||
if rec.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
if rec.get('groups'):
|
||||
g_names = rec.get('groups','').split(',')
|
||||
groups_value = []
|
||||
groups_obj = self.pool.get('res.groups')
|
||||
for group in g_names:
|
||||
|
@ -343,20 +336,19 @@ form: module.record_id""" % (xml_id,)
|
|||
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.wizard", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
|
||||
self.idref[xml_id] = int(id)
|
||||
# ir_set
|
||||
if (not rec.hasAttribute('menu') or eval(rec.getAttribute('menu'))) and id:
|
||||
keyword = str(rec.getAttribute('keyword') or 'client_action_multi')
|
||||
if (not rec.get('menu') or eval(rec.get('menu',''))) and id:
|
||||
keyword = str(rec.get('keyword','') or 'client_action_multi')
|
||||
keys = [('action',keyword),('res_model',model)]
|
||||
value = 'ir.actions.wizard,'+str(id)
|
||||
replace = rec.hasAttribute('replace') and \
|
||||
rec.getAttribute("replace") or True
|
||||
replace = rec.get("replace",'') or True
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id)
|
||||
return False
|
||||
|
||||
def _tag_url(self, cr, rec, data_node=None):
|
||||
url = rec.getAttribute("string").encode('utf8')
|
||||
target = rec.getAttribute("target").encode('utf8')
|
||||
name = rec.getAttribute("name").encode('utf8')
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
url = rec.get("string",'').encode('utf8')
|
||||
target = rec.get("target",'').encode('utf8')
|
||||
name = rec.get("name",'').encode('utf8')
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
|
||||
res = {'name': name, 'url': url, 'target':target}
|
||||
|
@ -364,34 +356,31 @@ form: module.record_id""" % (xml_id,)
|
|||
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
|
||||
self.idref[xml_id] = int(id)
|
||||
# ir_set
|
||||
if (not rec.hasAttribute('menu') or eval(rec.getAttribute('menu'))) and id:
|
||||
keyword = str(rec.getAttribute('keyword') or 'client_action_multi')
|
||||
if (not rec.get('menu') or eval(rec.get('menu',''))) and id:
|
||||
keyword = str(rec.get('keyword','') or 'client_action_multi')
|
||||
keys = [('action',keyword)]
|
||||
value = 'ir.actions.url,'+str(id)
|
||||
replace = rec.hasAttribute('replace') and \
|
||||
rec.getAttribute("replace") or True
|
||||
replace = rec.get("replace",'') or True
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=xml_id)
|
||||
return False
|
||||
|
||||
def _tag_act_window(self, cr, rec, data_node=None):
|
||||
name = rec.hasAttribute('name') and rec.getAttribute('name').encode('utf-8')
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
name = rec.get('name','').encode('utf-8')
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
type = rec.hasAttribute('type') and rec.getAttribute('type').encode('utf-8') or 'ir.actions.act_window'
|
||||
type = rec.get('type','').encode('utf-8') or 'ir.actions.act_window'
|
||||
view_id = False
|
||||
if rec.hasAttribute('view'):
|
||||
view_id = self.id_get(cr, 'ir.actions.act_window', rec.getAttribute('view').encode('utf-8'))
|
||||
domain = rec.hasAttribute('domain') and rec.getAttribute('domain').encode('utf-8')
|
||||
context = rec.hasAttribute('context') and rec.getAttribute('context').encode('utf-8') or '{}'
|
||||
res_model = rec.getAttribute('res_model').encode('utf-8')
|
||||
src_model = rec.hasAttribute('src_model') and rec.getAttribute('src_model').encode('utf-8')
|
||||
view_type = rec.hasAttribute('view_type') and rec.getAttribute('view_type').encode('utf-8') or 'form'
|
||||
view_mode = rec.hasAttribute('view_mode') and rec.getAttribute('view_mode').encode('utf-8') or 'tree,form'
|
||||
usage = rec.hasAttribute('usage') and rec.getAttribute('usage').encode('utf-8')
|
||||
limit = rec.hasAttribute('limit') and rec.getAttribute('limit').encode('utf-8')
|
||||
auto_refresh = rec.hasAttribute('auto_refresh') \
|
||||
and rec.getAttribute('auto_refresh').encode('utf-8')
|
||||
# groups_id = rec.hasAttribute('groups') and rec.getAttribute('groups').encode('utf-8')
|
||||
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')
|
||||
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')
|
||||
view_type = rec.get('view_type','').encode('utf-8') or 'form'
|
||||
view_mode = rec.get('view_mode','').encode('utf-8') or 'tree,form'
|
||||
usage = rec.get('usage','').encode('utf-8')
|
||||
limit = rec.get('limit','').encode('utf-8')
|
||||
auto_refresh = rec.get('auto_refresh','').encode('utf-8')
|
||||
|
||||
# def ref() added because , if context has ref('id') eval wil use this ref
|
||||
|
||||
|
@ -417,8 +406,8 @@ form: module.record_id""" % (xml_id,)
|
|||
# 'groups_id':groups_id,
|
||||
}
|
||||
|
||||
if rec.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
if rec.get('groups'):
|
||||
g_names = rec.get('groups','').split(',')
|
||||
groups_value = []
|
||||
groups_obj = self.pool.get('res.groups')
|
||||
for group in g_names:
|
||||
|
@ -430,8 +419,8 @@ form: module.record_id""" % (xml_id,)
|
|||
groups_value.append((4, group_id))
|
||||
res['groups_id'] = groups_value
|
||||
|
||||
if rec.hasAttribute('target'):
|
||||
res['target'] = rec.getAttribute('target')
|
||||
if rec.get('target'):
|
||||
res['target'] = rec.get('target','')
|
||||
id = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.actions.act_window', self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
|
||||
self.idref[xml_id] = int(id)
|
||||
|
||||
|
@ -439,7 +428,7 @@ form: module.record_id""" % (xml_id,)
|
|||
keyword = 'client_action_relate'
|
||||
keys = [('action', keyword), ('res_model', res_model)]
|
||||
value = 'ir.actions.act_window,'+str(id)
|
||||
replace = rec.hasAttribute('replace') and rec.getAttribute('replace') or True
|
||||
replace = rec.get('replace','') or True
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id)
|
||||
# TODO add remove ir.model.data
|
||||
return False
|
||||
|
@ -448,8 +437,8 @@ form: module.record_id""" % (xml_id,)
|
|||
if not self.mode=='init':
|
||||
return False
|
||||
res = {}
|
||||
for field in [i for i in rec.childNodes if (i.nodeType == i.ELEMENT_NODE and i.nodeName=="field")]:
|
||||
f_name = field.getAttribute("name").encode('utf-8')
|
||||
for field in [i for i in rec.getchildren() if (i.tag=="field")]:
|
||||
f_name = field.get("name",'').encode('utf-8')
|
||||
f_val = _eval_xml(self,field,self.pool, cr, self.uid, self.idref)
|
||||
res[f_name] = f_val
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None))
|
||||
|
@ -458,21 +447,21 @@ form: module.record_id""" % (xml_id,)
|
|||
def _tag_workflow(self, cr, rec, data_node=None):
|
||||
if self.isnoupdate(data_node) and self.mode != 'init':
|
||||
return
|
||||
model = str(rec.getAttribute('model'))
|
||||
w_ref = rec.getAttribute('ref')
|
||||
model = str(rec.get('model',''))
|
||||
w_ref = rec.get('ref','')
|
||||
if len(w_ref):
|
||||
id = self.id_get(cr, model, w_ref)
|
||||
else:
|
||||
assert rec.childNodes, 'You must define a child node if you dont give a ref'
|
||||
element_childs = [i for i in rec.childNodes if i.nodeType == i.ELEMENT_NODE]
|
||||
assert len(element_childs) == 1, 'Only one child node is accepted (%d given)' % len(rec.childNodes)
|
||||
assert rec.getchildren(), 'You must define a child node if you dont give a ref'
|
||||
element_childs = [i for i in rec.getchildren()]
|
||||
assert len(element_childs) == 1, 'Only one child node is accepted (%d given)' % len(rec.getchildren())
|
||||
id = _eval_xml(self, element_childs[0], self.pool, cr, self.uid, self.idref)
|
||||
|
||||
uid = self.get_uid(cr, self.uid, data_node, rec)
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, model,
|
||||
id,
|
||||
str(rec.getAttribute('action')), cr)
|
||||
str(rec.get('action','')), cr)
|
||||
return False
|
||||
|
||||
#
|
||||
|
@ -483,12 +472,12 @@ form: module.record_id""" % (xml_id,)
|
|||
# parent="parent_id"
|
||||
#
|
||||
def _tag_menuitem(self, cr, rec, data_node=None):
|
||||
rec_id = rec.getAttribute("id").encode('ascii')
|
||||
rec_id = rec.get("id",'').encode('ascii')
|
||||
self._test_xml_id(rec_id)
|
||||
m_l = map(escape, escape_re.split(rec.getAttribute("name").encode('utf8')))
|
||||
m_l = map(escape, escape_re.split(rec.get("name",'').encode('utf8')))
|
||||
|
||||
values = {'parent_id': False}
|
||||
if not rec.hasAttribute('parent'):
|
||||
if not rec.get('parent'):
|
||||
pid = False
|
||||
for idx, menu_elem in enumerate(m_l):
|
||||
if pid:
|
||||
|
@ -500,7 +489,7 @@ form: module.record_id""" % (xml_id,)
|
|||
values = {'parent_id': pid,'name':menu_elem}
|
||||
elif res:
|
||||
pid = res[0]
|
||||
xml_id = idx==len(m_l)-1 and rec.getAttribute('id').encode('utf8')
|
||||
xml_id = idx==len(m_l)-1 and rec.get('id','').encode('utf8')
|
||||
try:
|
||||
npid = self.pool.get('ir.model.data')._update_dummy(cr, self.uid, 'ir.ui.menu', self.module, xml_id, idx==len(m_l)-1)
|
||||
except:
|
||||
|
@ -510,18 +499,18 @@ form: module.record_id""" % (xml_id,)
|
|||
self.logger.notifyChannel("init", netsvc.LOG_WARNING, 'Warning no ID for submenu %s of menu %s !' % (menu_elem, str(m_l)))
|
||||
pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
|
||||
else:
|
||||
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.getAttribute('parent'))
|
||||
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.get('parent',''))
|
||||
values = {'parent_id': menu_parent_id}
|
||||
if rec.hasAttribute('name'):
|
||||
values['name'] = rec.getAttribute('name')
|
||||
if rec.get('name'):
|
||||
values['name'] = rec.get('name','')
|
||||
try:
|
||||
res = [ self.id_get(cr, 'ir.ui.menu', rec.getAttribute('id')) ]
|
||||
res = [ self.id_get(cr, 'ir.ui.menu', rec.get('id','')) ]
|
||||
except:
|
||||
res = None
|
||||
|
||||
if rec.hasAttribute('action'):
|
||||
a_action = rec.getAttribute('action').encode('utf8')
|
||||
a_type = rec.getAttribute('type').encode('utf8') or 'act_window'
|
||||
if rec.get('action'):
|
||||
a_action = rec.get('action','').encode('utf8')
|
||||
a_type = rec.get('type','').encode('utf8') or 'act_window'
|
||||
icons = {
|
||||
"act_window": 'STOCK_NEW',
|
||||
"report.xml": 'STOCK_PASTE',
|
||||
|
@ -560,13 +549,13 @@ form: module.record_id""" % (xml_id,)
|
|||
resw = cr.fetchone()
|
||||
if (not values.get('name', False)) and resw:
|
||||
values['name'] = resw[0]
|
||||
if rec.hasAttribute('sequence'):
|
||||
values['sequence'] = int(rec.getAttribute('sequence'))
|
||||
if rec.hasAttribute('icon'):
|
||||
values['icon'] = str(rec.getAttribute('icon'))
|
||||
if rec.get('sequence'):
|
||||
values['sequence'] = int(rec.get('sequence',''))
|
||||
if rec.get('icon'):
|
||||
values['icon'] = str(rec.get('icon',''))
|
||||
|
||||
if rec.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
if rec.get('groups'):
|
||||
g_names = rec.get('groups','').split(',')
|
||||
groups_value = []
|
||||
groups_obj = self.pool.get('res.groups')
|
||||
for group in g_names:
|
||||
|
@ -578,16 +567,16 @@ form: module.record_id""" % (xml_id,)
|
|||
groups_value.append((4, group_id))
|
||||
values['groups_id'] = groups_value
|
||||
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
pid = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.ui.menu', self.module, values, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode, res_id=res and res[0] or False)
|
||||
|
||||
if rec_id and pid:
|
||||
self.idref[rec_id] = int(pid)
|
||||
|
||||
if rec.hasAttribute('action') and pid:
|
||||
a_action = rec.getAttribute('action').encode('utf8')
|
||||
a_type = rec.getAttribute('type').encode('utf8') or 'act_window'
|
||||
if rec.get('action') and pid:
|
||||
a_action = rec.get('action','').encode('utf8')
|
||||
a_type = rec.get('type','').encode('utf8') or 'act_window'
|
||||
a_id = self.id_get(cr, 'ir.actions.%s' % a_type, a_action)
|
||||
action = "ir.actions.%s,%d" % (a_type, a_id)
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id)
|
||||
|
@ -600,17 +589,17 @@ form: module.record_id""" % (xml_id,)
|
|||
if self.isnoupdate(data_node) and self.mode != 'init':
|
||||
return
|
||||
|
||||
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)
|
||||
rec_src = rec.getAttribute("search").encode('utf8')
|
||||
rec_src_count = rec.getAttribute("count")
|
||||
rec_src = rec.get("search",'').encode('utf8')
|
||||
rec_src_count = rec.get("count",'')
|
||||
|
||||
severity = rec.getAttribute("severity").encode('ascii') or netsvc.LOG_ERROR
|
||||
severity = rec.get("severity",'').encode('ascii') or netsvc.LOG_ERROR
|
||||
|
||||
rec_string = rec.getAttribute("string").encode('utf8') or 'unknown'
|
||||
rec_string = rec.get("string",'').encode('utf8') or 'unknown'
|
||||
|
||||
ids = None
|
||||
eval_dict = {'ref': _ref(self, cr)}
|
||||
|
@ -651,8 +640,8 @@ form: module.record_id""" % (xml_id,)
|
|||
globals['floatEqual'] = self._assert_equals
|
||||
globals['ref'] = ref
|
||||
globals['_ref'] = ref
|
||||
for test in [i for i in rec.childNodes if (i.nodeType == i.ELEMENT_NODE and i.nodeName=="test")]:
|
||||
f_expr = test.getAttribute("expr").encode('utf-8')
|
||||
for test in [i for i in rec.getchildren() if (i.tag=="test")]:
|
||||
f_expr = test.get("expr",'').encode('utf-8')
|
||||
expected_value = _eval_xml(self, test, self.pool, cr, uid, self.idref, context=context) or True
|
||||
expression_value = eval(f_expr, globals)
|
||||
if expression_value != expected_value: # assertion failed
|
||||
|
@ -661,7 +650,7 @@ form: module.record_id""" % (xml_id,)
|
|||
' xmltag: %s\n' \
|
||||
' expected value: %r\n' \
|
||||
' obtained value: %r\n' \
|
||||
% (rec_string, test.toxml(), expected_value, expression_value)
|
||||
% (rec_string, etree.tostring(test), expected_value, expression_value)
|
||||
self.logger.notifyChannel('init', severity, msg)
|
||||
sevval = getattr(logging, severity.upper())
|
||||
if sevval >= config['assert_exit_level']:
|
||||
|
@ -672,12 +661,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:
|
||||
|
@ -699,21 +687,20 @@ 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
|
||||
|
||||
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 +748,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 <terp/> is deprecated, use <openerp/>")
|
||||
|
||||
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 +876,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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -132,10 +132,18 @@ class GettextAlias(object):
|
|||
|
||||
cr = frame.f_locals.get('cr')
|
||||
lang = (frame.f_locals.get('context') or {}).get('lang', False)
|
||||
|
||||
if not (cr and lang):
|
||||
args = frame.f_locals.get('args',False)
|
||||
if args:
|
||||
lang = args[-1].get('lang',False)
|
||||
if frame.f_globals.get('pooler',False):
|
||||
cr = pooler.get_db(frame.f_globals['pooler'].pool_dic.keys()[0]).cursor()
|
||||
|
||||
if not (lang and cr):
|
||||
return source
|
||||
|
||||
cr.execute('select value from ir_translation where lang=%s and type=%s and src=%s', (lang, 'code', source))
|
||||
cr.execute('select value from ir_translation where lang=%s and type in (%s,%s) and src=%s', (lang, 'code','sql_constraint', source))
|
||||
res_trans = cr.fetchone()
|
||||
return res_trans and res_trans[0] or source
|
||||
_ = GettextAlias()
|
||||
|
@ -335,9 +343,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 +354,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 +365,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 +442,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 +530,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))
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue