parent
90e6a956ec
commit
c68600cc53
|
@ -2,6 +2,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<menuitem icon="terp-administration" id="menu_administration" name="Administration" sequence="20"/>
|
||||
<menuitem id="custom_shortcuts" name="Custom Shortcuts" parent="base.menu_administration" sequence="20"/>
|
||||
<menuitem id="next_id_4" name="Low Level Objects" parent="base.menu_administration" sequence="3"/>
|
||||
<menuitem id="menu_low_workflow" name="Workflow Items" parent="base.next_id_4"/>
|
||||
<menuitem id="menu_custom" name="Customization" parent="base.menu_administration" sequence="2"/>
|
||||
|
|
|
@ -78,8 +78,9 @@
|
|||
<form string="Users">
|
||||
<field name="password" password="True" readonly="0"/>
|
||||
<label colspan="4" string="Please note that you will have to logout and relog if you change your password."/>
|
||||
<field name="context_company"/>
|
||||
<field name="context_lang" completion="1" readonly="0"/>
|
||||
<field name="context_tz" completion="1" readonly="0"/>
|
||||
<field name="context_tz" completion="1" readonly="0" colspan="4"/>
|
||||
<newline/>
|
||||
<field colspan="4" name="signature" readonly="0"/>
|
||||
</form>
|
||||
|
@ -112,6 +113,9 @@
|
|||
<page string="Roles">
|
||||
<field colspan="4" nolabel="1" name="roles_id"/>
|
||||
</page>
|
||||
<page string="Accepted Companies">
|
||||
<field colspan="4" nolabel="1" name="company_ids"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -344,13 +344,17 @@
|
|||
<field name="view_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field colspan="4" name="default_user_ids"/>
|
||||
<field colspan="4" name="menus"/>
|
||||
<field colspan="4" name="domain"/>
|
||||
<field colspan="4" name="context"/>
|
||||
<field name="limit"/>
|
||||
<field name="auto_refresh"/>
|
||||
<newline/>
|
||||
<field name="view_mode"/>
|
||||
<field name="filter"/>
|
||||
<field name="view_id"/>
|
||||
<field name="search_view_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -991,7 +995,7 @@
|
|||
</field>
|
||||
</record>
|
||||
<record id="grant_menu_access" model="ir.actions.act_window">
|
||||
<field name="name">Grant Access To Menus</field>
|
||||
<field name="name">Manage Menus</field>
|
||||
<field name="res_model">ir.ui.menu</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="edit_menu"/>
|
||||
|
@ -1023,13 +1027,12 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Scheduled Actions">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1" />
|
||||
<field name="user_id" select="1" />
|
||||
<field name="priority" select="1" />
|
||||
<notebook colspan="4">
|
||||
<page string="Information">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="priority" select="1"/>
|
||||
<newline/>
|
||||
<field name="interval_number"/>
|
||||
<field name="interval_type"/>
|
||||
<newline/>
|
||||
|
|
|
@ -27,6 +27,15 @@ from tools.config import config
|
|||
from tools.translate import _
|
||||
import netsvc
|
||||
import re
|
||||
import copy
|
||||
import sys
|
||||
|
||||
try:
|
||||
from xml import dom, xpath
|
||||
except ImportError:
|
||||
sys.stderr.write("ERROR: Import xpath module\n")
|
||||
sys.stderr.write("ERROR: Try to install the old python-xml package\n")
|
||||
sys.exit(2)
|
||||
|
||||
class actions(osv.osv):
|
||||
_name = 'ir.actions.actions'
|
||||
|
@ -153,6 +162,16 @@ class act_window(osv.osv):
|
|||
(_check_model, 'Invalid model name in the action definition.', ['res_model','src_model'])
|
||||
]
|
||||
|
||||
def get_filters(self, cr, uid, model):
|
||||
cr.execute('select id from ir_act_window a where a.id not in (select act_id from ir_act_window_user_rel) and a.res_model=\''+model+'\' and a.filter=\'1\';')
|
||||
all_ids = cr.fetchall()
|
||||
filter_ids = map(lambda x:x[0],all_ids)
|
||||
act_ids = self.search(cr,uid,[('res_model','=',model),('filter','=',1),('default_user_ids','in',(','.join(map(str,[uid,])),))])
|
||||
act_ids += filter_ids
|
||||
act_ids = list(set(act_ids))
|
||||
my_acts = self.read(cr, uid, act_ids, ['name', 'domain'])
|
||||
return my_acts
|
||||
|
||||
def _views_get_fnc(self, cr, uid, ids, name, arg, context={}):
|
||||
res={}
|
||||
for act in self.browse(cr, uid, ids):
|
||||
|
@ -169,6 +188,46 @@ class act_window(osv.osv):
|
|||
res[act.id].append((False, t))
|
||||
return res
|
||||
|
||||
def _search_view(self, cr, uid, ids, name, arg, context={}):
|
||||
res = {}
|
||||
def encode(s):
|
||||
if isinstance(s, unicode):
|
||||
return s.encode('utf8')
|
||||
return s
|
||||
for act in self.browse(cr, uid, ids):
|
||||
fields_from_fields_get = self.pool.get(act.res_model).fields_get(cr, uid)
|
||||
if act.search_view_id:
|
||||
field_get = self.pool.get(act.res_model).fields_view_get(cr, uid, act.search_view_id.id, 'search', context)
|
||||
fields_from_fields_get.update(field_get['fields'])
|
||||
field_get['fields'] = fields_from_fields_get
|
||||
res[act.id] = str(field_get)
|
||||
else:
|
||||
def process_child(node, new_node, doc):
|
||||
for child in node.childNodes:
|
||||
if child.localName=='field' and child.hasAttribute('select') and child.getAttribute('select')=='1':
|
||||
if child.childNodes:
|
||||
fld = doc.createElement('field')
|
||||
for attr in child.attributes.keys():
|
||||
fld.setAttribute(attr, child.getAttribute(attr))
|
||||
new_node.appendChild(fld)
|
||||
else:
|
||||
new_node.appendChild(child)
|
||||
elif child.localName in ('page','group','notebook'):
|
||||
process_child(child, new_node, doc)
|
||||
|
||||
form_arch = self.pool.get(act.res_model).fields_view_get(cr, uid, False, 'form', context)
|
||||
dom_arc = dom.minidom.parseString(encode(form_arch['arch']))
|
||||
new_node = copy.deepcopy(dom_arc)
|
||||
for child_node in new_node.childNodes[0].childNodes:
|
||||
if child_node.nodeType == child_node.ELEMENT_NODE:
|
||||
new_node.childNodes[0].removeChild(child_node)
|
||||
process_child(dom_arc.childNodes[0],new_node.childNodes[0],dom_arc)
|
||||
|
||||
form_arch['arch'] = new_node.toxml()
|
||||
form_arch['fields'].update(fields_from_fields_get)
|
||||
res[act.id] = str(form_arch)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Action Name', size=64, translate=True),
|
||||
'type': fields.char('Action Type', size=32, required=True),
|
||||
|
@ -188,6 +247,11 @@ class act_window(osv.osv):
|
|||
help='Add an auto-refresh on the view'),
|
||||
'groups_id': fields.many2many('res.groups', 'ir_act_window_group_rel',
|
||||
'act_id', 'gid', 'Groups'),
|
||||
'search_view_id': fields.many2one('ir.ui.view', 'Search View Ref.'),
|
||||
'filter': fields.boolean('Filter'),
|
||||
'default_user_ids': fields.many2many('res.users', 'ir_act_window_user_rel', 'act_id', 'uid', 'Users'),
|
||||
'search_view' : fields.function(_search_view, type='text', method=True, string='Search View'),
|
||||
'menus': fields.char('Menus', size=4096)
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.act_window',
|
||||
|
@ -519,7 +583,7 @@ class actions_server(osv.osv):
|
|||
result = self.pool.get(action.action_id.type).read(cr, uid, action.action_id.id, context=context)
|
||||
return result
|
||||
|
||||
if action.state=='code':
|
||||
if action.state == 'code':
|
||||
localdict = {
|
||||
'self': self.pool.get(action.model_id.model),
|
||||
'context': context,
|
||||
|
@ -542,7 +606,8 @@ class actions_server(osv.osv):
|
|||
pass
|
||||
|
||||
if not address:
|
||||
raise osv.except_osv(_('Error'), _("Please specify the Partner Email address !"))
|
||||
logger.notifyChannel('email', netsvc.LOG_INFO, 'Partner Email address not Specified!')
|
||||
continue
|
||||
if not user:
|
||||
raise osv.except_osv(_('Error'), _("Please specify server option --smtp-from !"))
|
||||
|
||||
|
|
|
@ -33,7 +33,12 @@ import pooler
|
|||
|
||||
def _get_fields_type(self, cr, uid, context=None):
|
||||
cr.execute('select distinct ttype,ttype from ir_model_fields')
|
||||
return cr.fetchall()
|
||||
field_types = cr.fetchall()
|
||||
field_types_copy = field_types
|
||||
for types in field_types_copy:
|
||||
if not hasattr(fields,types[0]):
|
||||
field_types.remove(types)
|
||||
return field_types
|
||||
|
||||
class ir_model(osv.osv):
|
||||
_name = 'ir.model'
|
||||
|
@ -174,8 +179,8 @@ class ir_model_grid(osv.osv):
|
|||
result['group_%d'%group.id] = {'string': '%s'%group.name,'type': 'char','size': 7}
|
||||
return result
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context={}, toolbar=False):
|
||||
result = super(ir_model_grid, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar)
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context={}, toolbar=False, submenu=False):
|
||||
result = super(ir_model_grid, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar, submenu=submenu)
|
||||
groups = self.pool.get('res.groups').search(cr, uid, [])
|
||||
groups_br = self.pool.get('res.groups').browse(cr, uid, groups)
|
||||
cols = ['model', 'name']
|
||||
|
@ -215,6 +220,7 @@ class ir_model_fields(osv.osv):
|
|||
'domain': fields.char('Domain', size=256),
|
||||
'groups': fields.many2many('res.groups', 'ir_model_fields_group_rel', 'field_id', 'group_id', 'Groups'),
|
||||
'view_load': fields.boolean('View Auto-Load'),
|
||||
'selectable': fields.boolean('Selectable'),
|
||||
}
|
||||
_rec_name='field_description'
|
||||
_defaults = {
|
||||
|
@ -227,6 +233,7 @@ class ir_model_fields(osv.osv):
|
|||
'select_level': lambda *a: '0',
|
||||
'size': lambda *a: 64,
|
||||
'field_description': lambda *a: '',
|
||||
'selectable': lambda *a: 1,
|
||||
}
|
||||
_order = "id"
|
||||
_sql_constraints = [
|
||||
|
|
|
@ -87,6 +87,8 @@ class ir_ui_menu(osv.osv):
|
|||
if key in self._cache:
|
||||
if self._cache[key]:
|
||||
result.append(menu.id)
|
||||
elif not menu.groups_id and not menu.action:
|
||||
result.append(menu.id)
|
||||
continue
|
||||
|
||||
self._cache[key] = False
|
||||
|
|
|
@ -60,7 +60,8 @@ class view(osv.osv):
|
|||
('mdx','mdx'),
|
||||
('graph', 'Graph'),
|
||||
('calendar', 'Calendar'),
|
||||
('gantt', 'Gantt')), 'View Type', required=True),
|
||||
('gantt', 'Gantt'),
|
||||
('search','Search')), 'View Type', required=True),
|
||||
'arch': fields.text('View Architecture', required=True),
|
||||
'inherit_id': fields.many2one('ir.ui.view', 'Inherited View', ondelete='cascade'),
|
||||
'field_parent': fields.char('Child Field',size=64),
|
||||
|
|
|
@ -197,8 +197,9 @@ class ir_values(osv.osv):
|
|||
for rec in cr.fetchall():
|
||||
if rec[0] in result_ids:
|
||||
continue
|
||||
result.append(rec)
|
||||
result_ids[rec[0]] = True
|
||||
if rec[2]:
|
||||
result.append(rec)
|
||||
result_ids[rec[0]] = True
|
||||
if len(where_opt):
|
||||
where_opt.pop()
|
||||
else:
|
||||
|
|
|
@ -155,7 +155,7 @@ class module(osv.osv):
|
|||
'latest_version': fields.char('Installed version', size=64, readonly=True),
|
||||
'published_version': fields.char('Published Version', size=64, readonly=True),
|
||||
|
||||
'url': fields.char('URL', size=128),
|
||||
'url': fields.char('URL', size=128, readonly=True),
|
||||
'dependencies_id': fields.one2many('ir.module.module.dependency',
|
||||
'module_id', 'Dependencies', readonly=True),
|
||||
'state': fields.selection([
|
||||
|
@ -211,7 +211,7 @@ class module(osv.osv):
|
|||
mdemo = False
|
||||
for dep in module.dependencies_id:
|
||||
if dep.state == 'unknown':
|
||||
raise orm.except_orm(_('Error'), _('You try to install a module that depends on the module: %s.\nBut this module is not available in your system.') % (dep.name,))
|
||||
raise orm.except_orm(_('Error'), _("You try to install the module '%s' that depends on the module:'%s'.\nBut this module is not available in your system.") % (module.name, dep.name,))
|
||||
ids2 = self.search(cr, uid, [('name','=',dep.name)])
|
||||
if dep.state != newstate:
|
||||
mdemo = self.state_update(cr, uid, ids2, newstate, states_to_update, context, level-1,) or mdemo
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<xsl:template name="stylesheet">
|
||||
<paraStyle name="title" fontName="Helvetica-Bold" fontSize="22" alignment="center"/>
|
||||
|
||||
<paraStyle name="float_right" alignment="right"/>
|
||||
<blockTableStyle id="products">
|
||||
<!--<blockBackground colorName="grey" start="0,0" stop="-1,0"/> -->
|
||||
<lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="-1,0"/>
|
||||
|
@ -86,6 +87,12 @@
|
|||
</font>
|
||||
</para>
|
||||
</xsl:when>
|
||||
<xsl:when test="@tree='float'">
|
||||
<para style="float_right"><font fontName="Helvetica" fontSize="9">
|
||||
<xsl:value-of select="."/>
|
||||
</font></para>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<para>
|
||||
<font fontName="Helvetica" fontSize="9">
|
||||
|
|
|
@ -30,7 +30,7 @@ import res_currency
|
|||
import res_company
|
||||
import res_user
|
||||
import res_request
|
||||
|
||||
import res_lang
|
||||
|
||||
import ir_property
|
||||
|
||||
|
|
|
@ -12,19 +12,19 @@
|
|||
<field name="active" select="2"/>
|
||||
<field name="bic" select="1"/>
|
||||
<newline/>
|
||||
<field name="street" select="2"/>
|
||||
<field name="street2" select="2"/>
|
||||
<newline/>
|
||||
<field name="zip"/>
|
||||
<field name="city"/>
|
||||
<newline/>
|
||||
<field name="country" select="2"/>
|
||||
<field name="state" select="2"/>
|
||||
<newline/>
|
||||
<field name="phone"/>
|
||||
<field name="fax"/>
|
||||
<newline/>
|
||||
<field name="email"/>
|
||||
<group string="Address" colspan="2" col="4">
|
||||
<field name="street" select="2"/>
|
||||
<field name="street2" select="2"/>
|
||||
<field name="zip"/>
|
||||
<field name="city"/>
|
||||
<field name="country" select="2"/>
|
||||
<field name="state" select="2"/>
|
||||
</group>
|
||||
<group string="Communication" colspan="2" col="4">
|
||||
<field name="phone"/>
|
||||
<field name="fax"/>
|
||||
<field name="email"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -307,7 +307,7 @@ class res_partner_address(osv.osv):
|
|||
return []
|
||||
res = []
|
||||
for r in self.read(cr, user, ids, ['name','zip','city','partner_id', 'street']):
|
||||
if context.get('contact_display', 'contact')=='partner':
|
||||
if context.get('contact_display', 'contact')=='partner' and r['partner_id']:
|
||||
res.append((r['id'], r['partner_id'][1]))
|
||||
else:
|
||||
addr = r['name'] or ''
|
||||
|
|
|
@ -141,8 +141,8 @@
|
|||
<field eval="[(6, 0, [ref('res_partner_category_1')])]" name="category_id"/>
|
||||
</record>
|
||||
<record id="res_partner_9" model="res.partner">
|
||||
<field name="website">http://www.openroad.be</field>
|
||||
<field name="name">OpenRoad</field>
|
||||
<field name="website">http://balmerinc.com</field>
|
||||
<field name="name">BalmerInc S.A.</field>
|
||||
<field eval="12000.00" name="credit_limit"/>
|
||||
<field name="ref">or</field>
|
||||
<field name="user_id" ref="user_demo"/>
|
||||
|
@ -174,6 +174,10 @@
|
|||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_11')])]" name="category_id"/>
|
||||
</record>
|
||||
<record id="res_partner_accent" model="res.partner">
|
||||
<field name="name">Université de Liège</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Resource: res.partner.address
|
||||
|
@ -184,9 +188,9 @@
|
|||
<field name="name">Michel Schumacher</field>
|
||||
<field name="zip">1000</field>
|
||||
<field model="res.country" name="country_id" search="[('name','=','Belgium')]"/>
|
||||
<field name="email">info@openroad.be</field>
|
||||
<field name="phone">(+32) 2 123 456</field>
|
||||
<field name="street">Rue du flash 50</field>
|
||||
<field name="email">info@balmerinc.be</field>
|
||||
<field name="phone">(+32)2 211 34 83</field>
|
||||
<field name="street">Rue des Palais 51, bte 33</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_9"/>
|
||||
</record>
|
||||
|
@ -338,6 +342,13 @@
|
|||
<field name="name">Shop 3</field>
|
||||
<field name="partner_id" ref="res_partner_11"/>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_address_accent" model="res.partner.address">
|
||||
<field name="type">default</field>
|
||||
<field name="city">Liège</field>
|
||||
<field name="street">Université de Liège</field>
|
||||
<field name="partner_id" ref="res_partner_accent"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -224,13 +224,17 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partners">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field name="ref" select="1"/>
|
||||
<field name="customer" select="1"/>
|
||||
<field domain="[('domain', '=', 'partner')]" name="title"/>
|
||||
<field name="lang" select="2"/>
|
||||
<field name="supplier" select="2"/>
|
||||
<group col="6" colspan="4">
|
||||
<group colspan="5" col="6">
|
||||
<field name="name" select="1" colspan="6"/>
|
||||
<field name="ref" select="1"/>
|
||||
<field domain="[('domain', '=', 'partner')]" name="title"/>
|
||||
<field name="lang" select="2"/>
|
||||
</group>
|
||||
<group colspan="1" col="2">
|
||||
<field name="customer" select="1"/>
|
||||
<field name="supplier" select="2"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="General">
|
||||
|
@ -287,11 +291,27 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_res_partner_filter" model="ir.ui.view">
|
||||
<field name="name">res.partner.select</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Partner">
|
||||
<group col='6' colspan='4'>
|
||||
<filter string="Customers" icon="terp-partner" domain="[('customer','=',1)]" help="Customer Partners"/>
|
||||
<filter string="Suppliers" icon="terp-partner" domain="[('supplier','=',1)]" help="Supplier Partners"/>
|
||||
<field name="name" select='1'/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_partner_form" model="ir.actions.act_window">
|
||||
<field name="name">Partners</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="search_view_id" ref="view_res_partner_filter"/>
|
||||
</record>
|
||||
<record id="action_partner_form_view1" model="ir.actions.act_window.view">
|
||||
<field eval="10" name="sequence"/>
|
||||
|
@ -317,6 +337,7 @@
|
|||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="domain">[('customer','=',1)]</field>
|
||||
<field name="filter" eval="True"/>
|
||||
</record>
|
||||
<menuitem action="action_partner_customer_form" id="menu_partner_customer_form" parent="menu_partner_form"/>
|
||||
<record id="action_partner_supplier_form" model="ir.actions.act_window">
|
||||
|
@ -326,6 +347,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="domain">[('supplier','=',1)]</field>
|
||||
<field name="context">{'default_customer':0}</field>
|
||||
<field name="filter" eval="True"/>
|
||||
</record>
|
||||
<menuitem action="action_partner_supplier_form" id="menu_partner_supplier_form" parent="menu_partner_form"/>
|
||||
<record id="action_partner_other_form" model="ir.actions.act_window">
|
||||
|
@ -334,6 +356,7 @@
|
|||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="domain">[('supplier','<>',1),('customer','<>',1)]</field>
|
||||
<field name="filter" eval="True"/>
|
||||
</record>
|
||||
<menuitem action="action_partner_other_form" id="menu_partner_other_form" parent="menu_partner_form"/>
|
||||
<record id="action_partner_customer_form_new" model="ir.actions.act_window">
|
||||
|
@ -342,6 +365,7 @@
|
|||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
<field name="view_id" ref="view_partner_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
action="action_partner_customer_form_new"
|
||||
|
@ -498,7 +522,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partner Categories">
|
||||
<tree toolbar="1" string="Partner Categories">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
|
|
@ -40,6 +40,10 @@ class groups(osv.osv):
|
|||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', 'The name of the group must be unique !')
|
||||
]
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
group_name = self.read(cr, uid, [id], ['name'])[0]['name']
|
||||
default.update({'name': group_name +' (copy)'})
|
||||
return super(groups, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if 'name' in vals:
|
||||
|
@ -99,10 +103,23 @@ def _lang_get(self, cr, uid, context={}):
|
|||
def _tz_get(self,cr,uid, context={}):
|
||||
return [(x, x) for x in pytz.all_timezones]
|
||||
|
||||
def _companies_get(self,cr, uid, context={}):
|
||||
res=[]
|
||||
ids = self.pool.get('res.users').browse(cr, uid, uid, context).company_ids
|
||||
res = [(i.id,i.name) for i in ids]
|
||||
return res
|
||||
|
||||
class users(osv.osv):
|
||||
__admin_ids = {}
|
||||
_name = "res.users"
|
||||
#_log_access = False
|
||||
|
||||
def get_current_company(self, cr, uid):
|
||||
res=[]
|
||||
cr.execute('select company_id, res_company.name from res_users left join res_company on res_company.id = company_id where res_users.id=%s' %uid)
|
||||
res = cr.fetchall()
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, select=True),
|
||||
'login': fields.char('Login', size=64, required=True),
|
||||
|
@ -116,8 +133,10 @@ class users(osv.osv):
|
|||
'roles_id': fields.many2many('res.roles', 'res_roles_users_rel', 'uid', 'rid', 'Roles'),
|
||||
'rules_id': fields.many2many('ir.rule.group', 'user_rule_group_rel', 'user_id', 'rule_group_id', 'Rules'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'company_ids':fields.many2many('res.company','res_company_users_rel','user_id','cid','Accepted Companies'),
|
||||
'context_lang': fields.selection(_lang_get, 'Language', required=True),
|
||||
'context_tz': fields.selection(_tz_get, 'Timezone', size=64)
|
||||
'context_tz': fields.selection(_tz_get, 'Timezone', size=64),
|
||||
'context_company': fields.selection(_companies_get, 'Company', size=64),
|
||||
}
|
||||
def read(self,cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||
def override_password(o):
|
||||
|
@ -135,7 +154,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 can not have two users with the same login !'))
|
||||
]
|
||||
|
||||
def _get_admin_id(self, cr):
|
||||
|
@ -182,6 +201,9 @@ class users(osv.osv):
|
|||
ok=False
|
||||
if ok:
|
||||
uid = 1
|
||||
context_company=values.get('context_company',False)
|
||||
if context_company:
|
||||
values.update({'company_id':context_company})
|
||||
res = super(users, self).write(cr, uid, ids, values, *args, **argv)
|
||||
self.company_get.clear_cache(cr.dbname)
|
||||
# Restart the cache on the company_get method
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<rng:ref name="image"/>
|
||||
<rng:ref name="form"/>
|
||||
<rng:ref name="vpaned"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
|
@ -47,12 +48,35 @@
|
|||
<rng:ref name="tree"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="search">
|
||||
<rng:element name="search">
|
||||
<rng:optional><rng:attribute name="string"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="col"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="type"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="position"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="link"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="label" />
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:ref name="search"/>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="image">
|
||||
<rng:element name="image">
|
||||
<rng:attribute name="name"/>
|
||||
|
@ -66,10 +90,25 @@
|
|||
<rng:optional><rng:attribute name="colspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="string"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="angle"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="position"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="fill"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="help"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:text/>
|
||||
<rng:choice>
|
||||
<rng:ref name="notebook"/>
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="hpaned" />
|
||||
<rng:ref name="label" />
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="image"/>
|
||||
<rng:ref name="form"/>
|
||||
<rng:ref name="vpaned"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
@ -153,6 +192,7 @@
|
|||
<rng:ref name="notebook"/>
|
||||
<rng:ref name="hpaned"/>
|
||||
<rng:ref name="vpaned"/>
|
||||
<rng:ref name="filter"/>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
|
@ -176,6 +216,7 @@
|
|||
<rng:optional><rng:attribute name="col"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="select"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="position"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="orientation"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="separator"/>
|
||||
|
@ -183,6 +224,7 @@
|
|||
<rng:ref name="field"/>
|
||||
<rng:ref name="label" />
|
||||
<rng:ref name="group" />
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
|
@ -281,6 +323,7 @@
|
|||
<rng:ref name="button"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="graph"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
|
@ -309,6 +352,7 @@
|
|||
<rng:ref name="field"/>
|
||||
<rng:ref name="label" />
|
||||
<rng:ref name="group" />
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
<rng:ref name="image"/>
|
||||
|
@ -365,6 +409,7 @@
|
|||
<rng:optional><rng:attribute name="position"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="context"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="confirm"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="help"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="form" />
|
||||
|
@ -378,6 +423,45 @@
|
|||
<rng:ref name="page" />
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="filter">
|
||||
<rng:element name="filter">
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="name" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="separator" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="icon" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="string" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="type" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="align" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="colspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="groups"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="readonly"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="position"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="context"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="help"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="domain"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="form" />
|
||||
<rng:ref name="field" />
|
||||
<rng:ref name="tree" />
|
||||
<rng:ref name="notebook" />
|
||||
<rng:ref name="graph" />
|
||||
<rng:ref name="calendar" />
|
||||
<rng:ref name="gantt" />
|
||||
<rng:ref name="xpath" />
|
||||
<rng:ref name="page" />
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
|
@ -389,6 +473,7 @@
|
|||
<rng:start>
|
||||
<rng:choice>
|
||||
<rng:ref name="form" />
|
||||
<rng:ref name="search" />
|
||||
<rng:ref name="group" />
|
||||
<rng:ref name="field" />
|
||||
<rng:ref name="tree" />
|
||||
|
@ -401,6 +486,8 @@
|
|||
<rng:ref name="page" />
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="filter"/>
|
||||
<rng:ref name="label" />
|
||||
</rng:choice>
|
||||
</rng:start>
|
||||
</rng:grammar>
|
||||
|
|
|
@ -314,8 +314,5 @@ except Exception, e:
|
|||
print e
|
||||
clean()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -37,7 +37,7 @@ class expression(object):
|
|||
return isinstance(element, (str, unicode)) and element in ['&', '|', '!']
|
||||
|
||||
def _is_leaf(self, element, internal=False):
|
||||
OPS = ('=', '!=', '<>', '<=', '<', '>', '>=', '=like', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of')
|
||||
OPS = ('=', '!=', '<>', '<=', '<', '>', '>=', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of')
|
||||
INTERNAL_OPS = OPS + ('inselect',)
|
||||
return (isinstance(element, tuple) or isinstance(element, list)) \
|
||||
and len(element) == 3 \
|
||||
|
@ -303,7 +303,7 @@ class expression(object):
|
|||
else:
|
||||
like = operator in ('like', 'ilike', 'not like', 'not ilike')
|
||||
|
||||
op = operator == '=like' and 'like' or operator
|
||||
op = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
|
||||
if left in table._columns:
|
||||
format = like and '%s' or table._columns[left]._symbol_set[0]
|
||||
query = '(%s.%s %s %s)' % (table._table, left, op, format)
|
||||
|
|
|
@ -80,6 +80,7 @@ class _column(object):
|
|||
self.read = False
|
||||
self.view_load = 0
|
||||
self.select = select
|
||||
self.selectable = True
|
||||
for a in args:
|
||||
if args[a]:
|
||||
setattr(self, a, args[a])
|
||||
|
@ -613,6 +614,10 @@ class function(_column):
|
|||
self._type = type
|
||||
self._fnct_search = fnct_search
|
||||
self.store = store
|
||||
|
||||
if not fnct_search and not store:
|
||||
self.selectable = False
|
||||
|
||||
if store:
|
||||
self._classic_read = True
|
||||
self._classic_write = True
|
||||
|
@ -774,6 +779,25 @@ class related(function):
|
|||
obj_name = f['relation']
|
||||
self._relations[-1]['relation'] = f['relation']
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Dummy fields
|
||||
# ---------------------------------------------------------
|
||||
|
||||
class dummy(function):
|
||||
def _fnct_search(self, tobj, cr, uid, obj=None, name=None, domain=None, context={}):
|
||||
return []
|
||||
|
||||
def _fnct_write(self,obj,cr, uid, ids, field_name, values, args, context=None):
|
||||
return False
|
||||
|
||||
def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None):
|
||||
return {}
|
||||
|
||||
def __init__(self, *arg, **args):
|
||||
self.arg = arg
|
||||
self._relations = []
|
||||
super(dummy, self).__init__(self._fnct_read, arg, self._fnct_write, fnct_inv_arg=arg, method=True, fnct_search=None, **args)
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Serialized fields
|
||||
# ---------------------------------------------------------
|
||||
|
|
455
bin/osv/orm.py
455
bin/osv/orm.py
|
@ -40,6 +40,7 @@
|
|||
#
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import calendar
|
||||
import types
|
||||
import string
|
||||
|
@ -50,16 +51,16 @@ 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")
|
||||
sys.exit(2)
|
||||
|
||||
from tools.config import config
|
||||
|
||||
|
@ -190,15 +191,13 @@ class browse_record(object):
|
|||
datas = self._table.read(self._cr, self._uid, ids, fffields, context=self._context, load="_classic_write")
|
||||
if self._fields_process:
|
||||
lang = self._context.get('lang', 'en_US') or 'en_US'
|
||||
lang_obj_ids = self.pool.get('res.lang').search(self._cr, self._uid,[('code','=',lang)])
|
||||
if not lang_obj_ids:
|
||||
raise Exception(_('Language with code "%s" is not defined in your system !\nDefine it through the Administration menu.') % (lang,))
|
||||
lang_obj = self.pool.get('res.lang').browse(self._cr, self._uid,lang_obj_ids[0])
|
||||
lang_obj = self.pool.get('res.lang').browse(self._cr, self._uid,self.pool.get('res.lang').search(self._cr, self._uid,[('code','=',lang)])[0])
|
||||
|
||||
for n, f in ffields:
|
||||
if f._type in self._fields_process:
|
||||
for d in datas:
|
||||
d[n] = self._fields_process[f._type](d[n])
|
||||
if (d[n] is not None) and (d[n] is not False):
|
||||
if d[n]:
|
||||
d[n].set_value(self._cr, self._uid, d[n], self, f, lang_obj)
|
||||
|
||||
|
||||
|
@ -365,6 +364,7 @@ class orm_template(object):
|
|||
'select_level': str(f.select or 0),
|
||||
'readonly':(f.readonly and 1) or 0,
|
||||
'required':(f.required and 1) or 0,
|
||||
'selectable' : (f.selectable and 1) or 0,
|
||||
}
|
||||
if k not in cols:
|
||||
cr.execute('select nextval(%s)', ('ir_model_fields_id_seq',))
|
||||
|
@ -395,12 +395,12 @@ class orm_template(object):
|
|||
cr.commit()
|
||||
cr.execute("""UPDATE ir_model_fields SET
|
||||
model_id=%s, field_description=%s, ttype=%s, relation=%s,
|
||||
view_load=%s, select_level=%s, readonly=%s ,required=%s
|
||||
view_load=%s, select_level=%s, readonly=%s ,required=%s, selectable=%s
|
||||
WHERE
|
||||
model=%s AND name=%s""", (
|
||||
vals['model_id'], vals['field_description'], vals['ttype'],
|
||||
vals['relation'], bool(vals['view_load']),
|
||||
vals['select_level'], bool(vals['readonly']),bool(vals['required']), vals['model'], vals['name']
|
||||
vals['select_level'], bool(vals['readonly']),bool(vals['required']),bool(vals['selectable']),vals['model'], vals['name']
|
||||
))
|
||||
continue
|
||||
cr.commit()
|
||||
|
@ -756,7 +756,7 @@ class orm_template(object):
|
|||
newfd = relation_obj.fields_get(
|
||||
cr, uid, context=context)
|
||||
res = process_liness(self, datas, prefix + [field], current_module, relation_obj._name, newfd, position)
|
||||
(newrow, max2, w2, translate2, data_id2, data_res_id2) = res
|
||||
(newrow, max2, w2, translate2, data_id2, data_res_id2) = res
|
||||
nbrmax = max(nbrmax, max2)
|
||||
warning = warning + w2
|
||||
reduce(lambda x, y: x and y, newrow)
|
||||
|
@ -801,7 +801,7 @@ 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 warning:
|
||||
cr.rollback()
|
||||
return (-1, res, 'Line ' + str(counter) +' : ' + '!\n'.join(warning), '')
|
||||
|
||||
|
@ -907,7 +907,7 @@ class orm_template(object):
|
|||
continue
|
||||
res[f] = {'type': self._columns[f]._type}
|
||||
for arg in ('string', 'readonly', 'states', 'size', 'required',
|
||||
'change_default', 'translate', 'help', 'select'):
|
||||
'change_default', 'translate', 'help', 'select', 'selectable'):
|
||||
if getattr(self._columns[f], arg):
|
||||
res[f][arg] = getattr(self._columns[f], arg)
|
||||
if not read_access:
|
||||
|
@ -969,14 +969,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
|
||||
|
||||
|
@ -984,64 +984,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 = 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
|
||||
|
@ -1052,23 +1051,23 @@ 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:
|
||||
ok = True
|
||||
if user != 1: # admin user has all roles
|
||||
user_roles = usersobj.read(cr, user, [user], ['roles_id'])[0]['roles_id']
|
||||
cr.execute("select role_id from wkf_transition where signal=%s", (button.getAttribute('name'),))
|
||||
cr.execute("select role_id from wkf_transition where signal=%s", (button.get('name'),))
|
||||
roles = cr.fetchall()
|
||||
for role in roles:
|
||||
if role[0]:
|
||||
ok = ok and rolesobj.check(cr, user, user_roles, role[0])
|
||||
|
||||
if not ok:
|
||||
button.setAttribute('readonly', '1')
|
||||
button.set('readonly', '1')
|
||||
else:
|
||||
button.setAttribute('readonly', '0')
|
||||
button.set('readonly', '0')
|
||||
|
||||
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':
|
||||
|
@ -1093,25 +1092,40 @@ class orm_template(object):
|
|||
"""
|
||||
|
||||
arch = ('<?xml version="1.0" encoding="utf-8"?>\n'
|
||||
'<calendar string="%s" date_start="%s"') % (self._description, self._date_name)
|
||||
'<calendar string="%s"') % (self._description)
|
||||
|
||||
if 'user_id' in self._columns:
|
||||
arch += ' color="user_id"'
|
||||
if (self._date_name not in self._columns):
|
||||
date_found = False
|
||||
for dt in ['date','date_start','x_date','x_date_start']:
|
||||
if dt in self._columns:
|
||||
self._date_name = dt
|
||||
date_found = True
|
||||
break
|
||||
|
||||
elif 'partner_id' in self._columns:
|
||||
arch += ' color="partner_id"'
|
||||
if not date_found:
|
||||
raise except_orm(_('Invalid Object Architecture!'),_("Insufficient fields for Calendar View!"))
|
||||
|
||||
if 'date_stop' in self._columns:
|
||||
arch += ' date_stop="date_stop"'
|
||||
if self._date_name:
|
||||
arch +=' date_start="%s"' % (self._date_name)
|
||||
|
||||
elif 'date_end' in self._columns:
|
||||
arch += ' date_stop="date_end"'
|
||||
for color in ["user_id","partner_id","x_user_id","x_partner_id"]:
|
||||
if color in self._columns:
|
||||
arch += ' color="' + color + '"'
|
||||
break
|
||||
|
||||
elif 'date_delay' in self._columns:
|
||||
arch += ' date_delay="date_delay"'
|
||||
dt_stop_flag = False
|
||||
|
||||
elif 'planned_hours' in self._columns:
|
||||
arch += ' date_delay="planned_hours"'
|
||||
for dt_stop in ["date_stop","date_end","x_date_stop","x_date_end"]:
|
||||
if dt_stop in self._columns:
|
||||
arch += ' date_stop="' + dt_stop + '"'
|
||||
dt_stop_flag = True
|
||||
break
|
||||
|
||||
if not dt_stop_flag:
|
||||
for dt_delay in ["date_delay","planned_hours","x_date_delay","x_planned_hours"]:
|
||||
if dt_delay in self._columns:
|
||||
arch += ' date_delay="' + dt_delay + '"'
|
||||
break
|
||||
|
||||
arch += ('>\n'
|
||||
' <field name="%s"/>\n'
|
||||
|
@ -1122,7 +1136,7 @@ class orm_template(object):
|
|||
#
|
||||
# if view_id, view_type is not required
|
||||
#
|
||||
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False):
|
||||
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
|
@ -1133,70 +1147,66 @@ 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_dest = etree.fromstring(encode(inherit))
|
||||
toparse = [ doc_dest ]
|
||||
|
||||
doc_src = dom.minidom.parseString(encode(src))
|
||||
doc_dest = dom.minidom.parseString(encode(inherit))
|
||||
toparse = doc_dest.childNodes
|
||||
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}
|
||||
|
||||
|
@ -1218,6 +1228,17 @@ class orm_template(object):
|
|||
inherit_id IS NULL
|
||||
ORDER BY priority''', (self._name, view_type))
|
||||
sql_res = cr.fetchone()
|
||||
if not sql_res and view_type == 'search':
|
||||
cr.execute('''SELECT
|
||||
arch,name,field_parent,id,type,inherit_id
|
||||
FROM
|
||||
ir_ui_view
|
||||
WHERE
|
||||
model=%s AND
|
||||
type=%s AND
|
||||
inherit_id IS NULL
|
||||
ORDER BY priority''', (self._name, 'form'))
|
||||
sql_res = cr.fetchone()
|
||||
if not sql_res:
|
||||
break
|
||||
ok = sql_res[5]
|
||||
|
@ -1239,7 +1260,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
|
||||
|
@ -1265,16 +1287,24 @@ class orm_template(object):
|
|||
elif view_type == 'calendar':
|
||||
xml = self.__get_default_calendar_view()
|
||||
else:
|
||||
xml = ''
|
||||
result['arch'] = xml
|
||||
raise except_orm(_('Invalid Architecture!'),_("There is no view of type '%s' defined for the structure!") % view_type)
|
||||
result['arch'] = etree.fromstring(encode(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 submenu:
|
||||
if context and context.get('active_id',False):
|
||||
data_menu = self.pool.get('ir.ui.menu').browse(cr, user, context['active_id'], context).action
|
||||
if data_menu:
|
||||
act_id = int(data_menu.split(',')[1])
|
||||
if act_id:
|
||||
data_action = self.pool.get('ir.actions.act_window').browse(cr, user, [act_id], context)[0]
|
||||
result['submenu'] = hasattr(data_action,'menus') and data_action.menus or False
|
||||
if toolbar:
|
||||
def clean(x):
|
||||
x = x[2]
|
||||
|
@ -1415,6 +1445,7 @@ class orm_memory(orm_template):
|
|||
fields_to_read = self._columns.keys()
|
||||
result = []
|
||||
if self.datas:
|
||||
ids_orig = ids
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for id in ids:
|
||||
|
@ -1432,7 +1463,7 @@ class orm_memory(orm_template):
|
|||
res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=result)
|
||||
for record in result:
|
||||
record[f] = res2[record['id']]
|
||||
if isinstance(ids, (int, long)):
|
||||
if isinstance(ids_orig, (int, long)):
|
||||
return result[0]
|
||||
return result
|
||||
|
||||
|
@ -1535,9 +1566,69 @@ class orm_memory(orm_template):
|
|||
value[key[8:]] = context[key]
|
||||
return value
|
||||
|
||||
def _where_calc(self, cr, user, args, active_test=True, context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
args = args[:]
|
||||
res=[]
|
||||
# if the object has a field named 'active', filter out all inactive
|
||||
# records unless they were explicitely asked for
|
||||
if 'active' in self._columns and (active_test and context.get('active_test', True)):
|
||||
if args:
|
||||
active_in_args = False
|
||||
for a in args:
|
||||
if a[0] == 'active':
|
||||
active_in_args = True
|
||||
if not active_in_args:
|
||||
args.insert(0, ('active', '=', 1))
|
||||
else:
|
||||
args = [('active', '=', 1)]
|
||||
if args:
|
||||
import expression
|
||||
e = expression.expression(args)
|
||||
e.parse(cr, user, self, context)
|
||||
res=e.__dict__['_expression__exp']
|
||||
return res or []
|
||||
|
||||
|
||||
def search(self, cr, user, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
return self.datas.keys()
|
||||
if not context:
|
||||
context = {}
|
||||
result = self._where_calc(cr, user, args, context=context)
|
||||
if result==[]:
|
||||
return self.datas.keys()
|
||||
|
||||
res=[]
|
||||
counter=0
|
||||
#Find the value of dict
|
||||
f=False
|
||||
if result:
|
||||
for id, data in self.datas.items():
|
||||
counter=counter+1
|
||||
if limit and (counter >int(limit)):
|
||||
break
|
||||
f = True
|
||||
for arg in result:
|
||||
if arg[1] =='=':
|
||||
val =eval('data[arg[0]]'+'==' +' arg[2]')
|
||||
elif arg[1] in ['<','>','in','not in','<=','>=','<>']:
|
||||
val =eval('data[arg[0]]'+arg[1] +' arg[2]')
|
||||
elif arg[1] in ['ilike']:
|
||||
if str(data[arg[0]]).find(str(arg[2]))!=-1:
|
||||
val= True
|
||||
else:
|
||||
val=False
|
||||
|
||||
if f and val:
|
||||
f = True
|
||||
else:
|
||||
f = False
|
||||
if f:
|
||||
res.append(id)
|
||||
if count:
|
||||
return len(res)
|
||||
return res or []
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
|
@ -1911,22 +2002,25 @@ class orm(orm_template):
|
|||
if not f.store:
|
||||
continue
|
||||
if self._columns[store_field].store is True:
|
||||
sm = {self._name:(lambda self,cr, uid, ids, c={}: ids, None, 10)}
|
||||
sm = {self._name:(lambda self,cr, uid, ids, c={}: ids, None, 10, None)}
|
||||
else:
|
||||
sm = self._columns[store_field].store
|
||||
for object, aa in sm.items():
|
||||
if len(aa)==3:
|
||||
if len(aa)==4:
|
||||
(fnct,fields2,order,length)=aa
|
||||
elif len(aa)==3:
|
||||
(fnct,fields2,order)=aa
|
||||
length = None
|
||||
else:
|
||||
raise except_orm('Error',
|
||||
('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority)}.' % (store_field, self._name)))
|
||||
('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority, time length)}.' % (store_field, self._name)))
|
||||
self.pool._store_function.setdefault(object, [])
|
||||
ok = True
|
||||
for x,y,z,e,f in self.pool._store_function[object]:
|
||||
for x,y,z,e,f,l in self.pool._store_function[object]:
|
||||
if (x==self._name) and (y==store_field) and (e==fields2):
|
||||
ok = False
|
||||
if ok:
|
||||
self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order))
|
||||
self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order, length))
|
||||
self.pool._store_function[object].sort(lambda x,y: cmp(x[4],y[4]))
|
||||
|
||||
for (key, _, msg) in self._sql_constraints:
|
||||
|
@ -2190,7 +2284,10 @@ class orm(orm_template):
|
|||
for f in val:
|
||||
res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=res)
|
||||
for record in res:
|
||||
record[f] = res2[record['id']]
|
||||
if res2:
|
||||
record[f] = res2[record['id']]
|
||||
else:
|
||||
record[f] = []
|
||||
|
||||
#for f in fields_post:
|
||||
# # get the value of that field for all records/ids
|
||||
|
@ -2370,7 +2467,6 @@ class orm(orm_template):
|
|||
if not edit:
|
||||
vals.pop(field)
|
||||
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
if not ids:
|
||||
|
@ -2553,7 +2649,7 @@ class orm(orm_template):
|
|||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'create', context=context)
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'create')
|
||||
|
||||
default = []
|
||||
|
||||
|
@ -2561,12 +2657,12 @@ class orm(orm_template):
|
|||
for (t, c) in self._inherits.items():
|
||||
if c in vals:
|
||||
avoid_table.append(t)
|
||||
for f in self._columns.keys():
|
||||
if (not f in vals) and (not isinstance(self._columns[f], fields.property)):
|
||||
for f in self._columns.keys(): # + self._inherit_fields.keys():
|
||||
if not f in vals:
|
||||
default.append(f)
|
||||
|
||||
for f in self._inherit_fields.keys():
|
||||
if (not f in vals) and (self._inherit_fields[f][0] not in avoid_table) and (not isinstance(self._inherit_fields[f][2], fields.property)):
|
||||
if (not f in vals) and (self._inherit_fields[f][0] not in avoid_table):
|
||||
default.append(f)
|
||||
|
||||
if len(default):
|
||||
|
@ -2575,21 +2671,25 @@ class orm(orm_template):
|
|||
if dv in self._columns and self._columns[dv]._type == 'many2many':
|
||||
if default_values[dv] and isinstance(default_values[dv][0], (int, long)):
|
||||
default_values[dv] = [(6, 0, default_values[dv])]
|
||||
|
||||
vals.update(default_values)
|
||||
|
||||
tocreate = {}
|
||||
for v in self._inherits:
|
||||
if self._inherits[v] not in vals:
|
||||
tocreate[v] = {}
|
||||
|
||||
else:
|
||||
tocreate[v] = {self._inherits[v]:vals[self._inherits[v]]}
|
||||
(upd0, upd1, upd2) = ('', '', [])
|
||||
upd_todo = []
|
||||
|
||||
for v in vals.keys():
|
||||
if v in self._inherit_fields:
|
||||
(table, col, col_detail) = self._inherit_fields[v]
|
||||
tocreate[table][v] = vals[v]
|
||||
del vals[v]
|
||||
else:
|
||||
if (v not in self._inherit_fields) and (v not in self._columns):
|
||||
del vals[v]
|
||||
|
||||
# Try-except added to filter the creation of those records whose filds are readonly.
|
||||
# Example : any dashboard which has all the fields readonly.(due to Views(database views))
|
||||
|
@ -2601,11 +2701,13 @@ class orm(orm_template):
|
|||
|
||||
id_new = cr.fetchone()[0]
|
||||
for table in tocreate:
|
||||
if self._inherits[table] in vals:
|
||||
del vals[self._inherits[table]]
|
||||
id = self.pool.get(table).create(cr, user, tocreate[table])
|
||||
upd0 += ','+self._inherits[table]
|
||||
upd1 += ',%s'
|
||||
upd2.append(id)
|
||||
|
||||
|
||||
#Start : Set bool fields to be False if they are not touched(to make search more powerful)
|
||||
bool_fields = [x for x in self._columns.keys() if self._columns[x]._type=='boolean']
|
||||
|
||||
|
@ -2613,15 +2715,40 @@ class orm(orm_template):
|
|||
if bool_field not in vals:
|
||||
vals[bool_field] = False
|
||||
#End
|
||||
|
||||
for field in vals:
|
||||
for field in vals.copy():
|
||||
fobj = None
|
||||
if field in self._columns:
|
||||
if self._columns[field]._classic_write:
|
||||
upd0 = upd0 + ',"' + field + '"'
|
||||
upd1 = upd1 + ',' + self._columns[field]._symbol_set[0]
|
||||
upd2.append(self._columns[field]._symbol_set[1](vals[field]))
|
||||
else:
|
||||
upd_todo.append(field)
|
||||
fobj = self._columns[field]
|
||||
else:
|
||||
fobj = self._inherit_fields[field][2]
|
||||
if not fobj:
|
||||
continue
|
||||
groups = fobj.write
|
||||
if groups:
|
||||
edit = False
|
||||
for group in groups:
|
||||
module = group.split(".")[0]
|
||||
grp = group.split(".")[1]
|
||||
cr.execute("select count(*) from res_groups_users_rel where gid in (select res_id from ir_model_data where name='%s' and module='%s' and model='%s') and uid=%s" % \
|
||||
(grp, module, 'res.groups', user))
|
||||
readonly = cr.fetchall()
|
||||
if readonly[0][0] >= 1:
|
||||
edit = True
|
||||
break
|
||||
elif readonly[0][0] == 0:
|
||||
edit = False
|
||||
else:
|
||||
edit = False
|
||||
|
||||
if not edit:
|
||||
vals.pop(field)
|
||||
for field in vals:
|
||||
if self._columns[field]._classic_write:
|
||||
upd0 = upd0 + ',"' + field + '"'
|
||||
upd1 = upd1 + ',' + self._columns[field]._symbol_set[0]
|
||||
upd2.append(self._columns[field]._symbol_set[1](vals[field]))
|
||||
else:
|
||||
upd_todo.append(field)
|
||||
if field in self._columns \
|
||||
and hasattr(self._columns[field], 'selection') \
|
||||
and vals[field]:
|
||||
|
@ -2671,25 +2798,20 @@ class orm(orm_template):
|
|||
cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%s', (pleft,))
|
||||
cr.execute('update '+self._table+' set parent_left=%s,parent_right=%s where id=%s', (pleft+1,pleft+2,id_new))
|
||||
|
||||
# default element in context must be removed when call a one2many or many2many
|
||||
# default element in context must be remove when call a one2many or many2many
|
||||
rel_context = context.copy()
|
||||
for c in context.items():
|
||||
if c[0].startswith('default_'):
|
||||
del rel_context[c[0]]
|
||||
|
||||
result = []
|
||||
|
||||
for field in upd_todo:
|
||||
result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or []
|
||||
self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context)
|
||||
self._validate(cr, user, [id_new], context)
|
||||
|
||||
if not context.get('no_store_function', False):
|
||||
result += self._store_get_values(cr, user, [id_new], vals.keys(), context)
|
||||
result.sort()
|
||||
done = []
|
||||
for order, object, ids, fields2 in result:
|
||||
if not (object, ids, fields2) in done:
|
||||
self.pool.get(object)._store_set_values(cr, user, ids, fields2, context)
|
||||
done.append((object, ids, fields2))
|
||||
|
||||
result = self._store_get_values(cr, user, [id_new], vals.keys(), context)
|
||||
for order, object, ids, fields in result:
|
||||
self.pool.get(object)._store_set_values(cr, user, ids, fields, context)
|
||||
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_create(user, self._name, id_new, cr)
|
||||
|
@ -2730,6 +2852,24 @@ class orm(orm_template):
|
|||
return result2
|
||||
|
||||
def _store_set_values(self, cr, uid, ids, fields, context):
|
||||
field_flag = False
|
||||
field_dict = {}
|
||||
if self._log_access:
|
||||
cr.execute('select id,write_date from '+self._table+' where id in ('+','.join(map(str, ids))+')')
|
||||
res = cr.fetchall()
|
||||
for r in res:
|
||||
if r[1]:
|
||||
field_dict.setdefault(r[0], [])
|
||||
res_date = time.strptime((r[1])[:19], '%Y-%m-%d %H:%M:%S')
|
||||
write_date = datetime.datetime.fromtimestamp(time.mktime(res_date))
|
||||
for i in self.pool._store_function.get(self._name, []):
|
||||
if i[5]:
|
||||
up_write_date = write_date + datetime.timedelta(hours=i[5])
|
||||
if datetime.datetime.now() < up_write_date:
|
||||
if i[1] in fields:
|
||||
field_dict[r[0]].append(i[1])
|
||||
if not field_flag:
|
||||
field_flag = True
|
||||
todo = {}
|
||||
keys = []
|
||||
for f in fields:
|
||||
|
@ -2742,6 +2882,10 @@ class orm(orm_template):
|
|||
if key:
|
||||
result = self._columns[val[0]].get(cr, self, ids, val, uid, context=context)
|
||||
for id,value in result.items():
|
||||
if field_flag:
|
||||
for f in value.keys():
|
||||
if f in field_dict[id]:
|
||||
value.pop(f)
|
||||
upd0 = []
|
||||
upd1 = []
|
||||
for v in value:
|
||||
|
@ -2761,6 +2905,11 @@ class orm(orm_template):
|
|||
else:
|
||||
for f in val:
|
||||
result = self._columns[f].get(cr, self, ids, f, uid, context=context)
|
||||
for r in result.keys():
|
||||
if field_flag:
|
||||
if r in field_dict.keys():
|
||||
if f in field_dict[r]:
|
||||
result.pop(r)
|
||||
for id,value in result.items():
|
||||
if self._columns[f]._type in ('many2one', 'one2one'):
|
||||
try:
|
||||
|
|
|
@ -193,7 +193,19 @@ class osv_memory(orm.orm_memory):
|
|||
name = hasattr(cls, '_name') and cls._name or cls._inherit
|
||||
parent_name = hasattr(cls, '_inherit') and cls._inherit
|
||||
if parent_name:
|
||||
raise 'Inherit not supported in osv_memory object !'
|
||||
parent_class = pool.get(parent_name).__class__
|
||||
assert pool.get(parent_name), "parent class %s does not exist in module %s !" % (parent_name, module)
|
||||
nattr = {}
|
||||
for s in ('_columns', '_defaults'):
|
||||
new = copy.copy(getattr(pool.get(parent_name), s))
|
||||
if hasattr(new, 'update'):
|
||||
new.update(cls.__dict__.get(s, {}))
|
||||
else:
|
||||
new.extend(cls.__dict__.get(s, []))
|
||||
nattr[s] = new
|
||||
name = hasattr(cls, '_name') and cls._name or cls._inherit
|
||||
cls = type(name, (cls, parent_class), nattr)
|
||||
|
||||
obj = object.__new__(cls)
|
||||
obj.__init__(pool, cr)
|
||||
return obj
|
||||
|
|
|
@ -28,9 +28,9 @@ _uid_cache = {}
|
|||
def login(db, login, password):
|
||||
cr = pooler.get_db(db).cursor()
|
||||
if password:
|
||||
cr.execute('select id from res_users where login=%s and password=%s and active', (tools.ustr(login), tools.ustr(password)))
|
||||
cr.execute('select id from res_users where login=%s and password=%s and active', (login.encode('utf-8'), password.encode('utf-8')))
|
||||
else:
|
||||
cr.execute('select id from res_users where login=%s and password is null and active', (tools.ustr(login),))
|
||||
cr.execute('select id from res_users where login=%s and password is null and active', (login.encode('utf-8'),))
|
||||
res = cr.fetchone()
|
||||
cr.close()
|
||||
if res:
|
||||
|
|
|
@ -86,7 +86,7 @@ class db(netsvc.Service):
|
|||
serv.actions[id]['progress'] = 0
|
||||
clean = False
|
||||
cr = sql_db.db_connect(db_name).cursor()
|
||||
tools.init_db(cr)
|
||||
# tools.init_db(cr)
|
||||
cr.commit()
|
||||
cr.close()
|
||||
cr = None
|
||||
|
|
|
@ -70,6 +70,7 @@ class configmanager(object):
|
|||
'smtp_server': 'localhost',
|
||||
'smtp_user': False,
|
||||
'smtp_port':25,
|
||||
'smtp_ssl':False,
|
||||
'smtp_password': False,
|
||||
'stop_after_init': False, # this will stop the server after initialization
|
||||
'price_accuracy': 2,
|
||||
|
|
|
@ -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,38 +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'(?<!\\)/')
|
||||
def escape(x):
|
||||
|
@ -205,9 +198,9 @@ 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')
|
||||
|
@ -216,20 +209,20 @@ class xml_import(object):
|
|||
return self.noupdate or (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 = (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 (data_node and data_node.get('uid',''))
|
||||
if len(node_uid):
|
||||
return self.id_get(cr, None, node_uid)
|
||||
return uid
|
||||
|
@ -249,9 +242,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 +262,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:
|
||||
|
@ -302,11 +295,11 @@ form: module.record_id""" % (xml_id,)
|
|||
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,12 @@ 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.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
if rec.get('sequence'):
|
||||
values['sequence'] = int(rec.get('sequence',''))
|
||||
if rec.get('icon'):
|
||||
values['icon'] = str(rec.get('icon',''))
|
||||
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 +566,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 +588,16 @@ 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
|
||||
|
||||
rec_string = rec.getAttribute("string").encode('utf8') or 'unknown'
|
||||
severity = rec.get("severity",'').encode('ascii') or netsvc.LOG_ERROR
|
||||
rec_string = rec.get("string",'').encode('utf8') or 'unknown'
|
||||
|
||||
ids = None
|
||||
eval_dict = {'ref': _ref(self, cr)}
|
||||
|
@ -651,8 +638,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 +648,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,10 +659,10 @@ 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':
|
||||
|
@ -705,15 +692,15 @@ form: module.record_id""" % (xml_id,)
|
|||
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
|
||||
|
@ -842,6 +827,9 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
|
|||
reader.next()
|
||||
|
||||
if not (mode == 'init' or 'id' in fields):
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel("init", netsvc.LOG_ERROR,
|
||||
"Import specification does not contain 'id' and we are in init mode, Cannot continue.")
|
||||
return
|
||||
|
||||
uid = 1
|
||||
|
@ -891,11 +879,12 @@ 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 tools, pooler
|
||||
from osv.orm import BrowseRecordError
|
||||
import csv, re
|
||||
from lxml import etree
|
||||
import osv, tools, pooler
|
||||
import ir
|
||||
import netsvc
|
||||
from tools.misc import UpdateableStr
|
||||
|
@ -166,6 +166,7 @@ class TinyPoFile(object):
|
|||
def next(self):
|
||||
def unquote(str):
|
||||
return str[1:-1].replace("\\n", "\n") \
|
||||
.replace("\\\\ ", "\\ ") \
|
||||
.replace('\\"', '"')
|
||||
|
||||
type = name = res_id = source = trad = None
|
||||
|
@ -248,7 +249,8 @@ class TinyPoFile(object):
|
|||
def write(self, modules, tnrs, source, trad):
|
||||
def quote(s):
|
||||
return '"%s"' % s.replace('"','\\"') \
|
||||
.replace('\n', '\\n"\n"')
|
||||
.replace('\\ ','\\\\ ') \
|
||||
.replace('\n', '\\n"\n"')
|
||||
|
||||
plurial = len(modules) > 1 and 's' or ''
|
||||
self.buffer.write("#. module%s: %s\n" % (plurial, ', '.join(modules)))
|
||||
|
@ -335,10 +337,10 @@ 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)]:
|
||||
l = m.data.strip().replace('\n',' ')
|
||||
for n in [i for i in de.getchildren()]:
|
||||
if n.get("t"):
|
||||
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))
|
||||
|
@ -346,9 +348,9 @@ 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)]:
|
||||
string_list = [s.replace('\n', ' ').strip() for s in re.split('\[\[.+?\]\]', m.data)]
|
||||
for n in [i for i in de.getchildren()]:
|
||||
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"))
|
||||
|
@ -357,15 +359,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 +436,8 @@ def trans_generate(lang, modules, dbname=None):
|
|||
continue
|
||||
|
||||
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 +524,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):
|
||||
push_translation(module, report_type, name, 0, t)
|
||||
except IOError, xml.dom.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))
|
||||
|
||||
|
|
|
@ -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,12 +50,11 @@ 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 trans:
|
||||
node.setAttribute('string', trans)
|
||||
for n in node.childNodes:
|
||||
if node.get('string'):
|
||||
trans = translate(cr, self.wiz_name+','+state, 'wizard_view', lang, node.get('string').encode('utf8'))
|
||||
if trans:
|
||||
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):
|
||||
|
@ -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