bzr revid: hda@tinyerp.com-20090917072712-l7220bbv1gq4uckc
This commit is contained in:
HDA (OpenERP) 2009-09-17 12:57:12 +05:30
parent 90e6a956ec
commit c68600cc53
28 changed files with 820 additions and 412 deletions

View File

@ -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"/>

View File

@ -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>

View File

@ -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/>

View File

@ -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 !"))

View File

@ -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 = [

View File

@ -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

View File

@ -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),

View File

@ -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:

View File

@ -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

View File

@ -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">

View File

@ -30,7 +30,7 @@ import res_currency
import res_company
import res_user
import res_request
import res_lang
import ir_property

View File

@ -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>

View File

@ -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 ''

View File

@ -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>

View File

@ -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','&lt;&gt;',1),('customer','&lt;&gt;',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>

View File

@ -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

View File

@ -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>

View File

@ -314,8 +314,5 @@ except Exception, e:
print e
clean()
sys.exit(1)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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)

View File

@ -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
# ---------------------------------------------------------

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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,

View File

@ -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()

View File

@ -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))

View File

@ -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)