merging from trunk
bzr revid: mga@tinyerp.com-20080910071243-v53xq2dtk2s7fyrn
This commit is contained in:
commit
2ce1603aee
|
@ -173,7 +173,10 @@ def create_graph(module_list, force=None):
|
|||
for module in module_list:
|
||||
if module[-4:]=='.zip':
|
||||
module = module[:-4]
|
||||
mod_path = get_module_path(module)
|
||||
try:
|
||||
mod_path = get_module_path(module)
|
||||
except IOError:
|
||||
continue
|
||||
terp_file = get_module_resource(module, '__terp__.py')
|
||||
if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path):
|
||||
try:
|
||||
|
@ -235,7 +238,11 @@ def load_module_graph(cr, graph, status=None, **kwargs):
|
|||
sys.stdout.flush()
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
modules = pool.instanciate(m, cr)
|
||||
cr.execute('select state, demo from ir_module_module where name=%s', (m,))
|
||||
|
||||
cr.execute('select id from ir_module_module where name=%s', (m,))
|
||||
mid = int(cr.rowcount and cr.fetchone()[0] or 0)
|
||||
|
||||
cr.execute('select state, demo from ir_module_module where id=%d', (mid,))
|
||||
(package_state, package_demo) = (cr.rowcount and cr.fetchone()) or ('uninstalled', False)
|
||||
idref = {}
|
||||
status['progress'] = (float(statusi)+0.4)/len(graph)
|
||||
|
@ -267,31 +274,23 @@ def load_module_graph(cr, graph, status=None, **kwargs):
|
|||
tools.convert_csv_import(cr, m, os.path.basename(xml), tools.file_open(opj(m, xml)).read(), idref, noupdate=True)
|
||||
else:
|
||||
tools.convert_xml_import(cr, m, tools.file_open(opj(m, xml)), idref, noupdate=True, **kwargs)
|
||||
cr.execute('update ir_module_module set demo=%s where name=%s', (True, package.name))
|
||||
cr.execute('update ir_module_module set demo=%s where id=%d', (True, mid))
|
||||
package_todo.append(package.name)
|
||||
cr.execute("update ir_module_module set state='installed' where state in ('to upgrade', 'to install') and name=%s", (package.name,))
|
||||
|
||||
# check if all model of the module have at least a access rule.
|
||||
# TODO: improve this query which is very slow !!!
|
||||
cr.execute(""" SELECT name
|
||||
FROM ir_model m
|
||||
WHERE EXISTS (SELECT 1
|
||||
FROM ir_model_data
|
||||
WHERE module = %s
|
||||
AND model = m.name
|
||||
)
|
||||
AND NOT EXISTS (SELECT 1
|
||||
FROM ir_model_access
|
||||
WHERE model_id = m.id
|
||||
)
|
||||
""", (m,))
|
||||
|
||||
for (model,) in cr.fetchall():
|
||||
logger.notifyChannel('init', netsvc.LOG_WARNING, 'addon:%s:object %s has no access rules!' % (m,model,))
|
||||
cr.execute("update ir_module_module set state='installed' where state in ('to upgrade', 'to install') and id=%d", (mid,))
|
||||
|
||||
cr.commit()
|
||||
|
||||
# Update translations for all installed languages
|
||||
modobj = pool.get('ir.module.module')
|
||||
modobj.update_translations(cr, 1, [mid], None)
|
||||
|
||||
cr.commit()
|
||||
statusi+=1
|
||||
|
||||
cr.execute("""select model,name from ir_model where id not in (select model_id from ir_model_access)""")
|
||||
for (model,name) in cr.fetchall():
|
||||
logger.notifyChannel('init', netsvc.LOG_WARNING, 'addon:object %s (%s) has no access rules!' % (model,name))
|
||||
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
cr.execute('select * from ir_model where state=%s', ('manual',))
|
||||
for model in cr.dictfetchall():
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved.
|
||||
# Copyright (c) 2008 Camptocamp SA
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
@ -37,6 +38,8 @@
|
|||
"init_xml" : [
|
||||
"base_data.xml",
|
||||
"base_menu.xml",
|
||||
"base_security.xml",
|
||||
"res/res_security.xml",
|
||||
],
|
||||
"demo_xml" : [
|
||||
"base_demo.xml",
|
||||
|
@ -44,6 +47,7 @@
|
|||
"res/partner/crm_demo.xml",
|
||||
],
|
||||
"update_xml" : [
|
||||
"ir.model.access.csv",
|
||||
"base_update.xml",
|
||||
"ir/wizard/wizard_menu_view.xml",
|
||||
"ir/ir.xml",
|
||||
|
@ -68,6 +72,3 @@
|
|||
"active": True,
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -148,9 +148,6 @@ CREATE TABLE res_users (
|
|||
);
|
||||
alter table res_users add constraint res_users_login_uniq unique (login);
|
||||
|
||||
insert into res_users (id,login,password,name,action_id,active) values (1,'root',NULL,'Root',NULL,False);
|
||||
select setval('res_users_id_seq', 2);
|
||||
|
||||
CREATE TABLE res_groups (
|
||||
id serial NOT NULL,
|
||||
name varchar(32) NOT NULL,
|
||||
|
@ -328,4 +325,14 @@ CREATE TABLE ir_model_data (
|
|||
res_id integer, primary key(id)
|
||||
);
|
||||
|
||||
---------------------------------
|
||||
-- Users
|
||||
---------------------------------
|
||||
|
||||
insert into res_users (id,login,password,name,action_id,active) values (1,'admin',NULL,'Administrator',NULL,True);
|
||||
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_root','base','res.users',True,1);
|
||||
|
||||
-- Compatibility purpose, to remove V6.0
|
||||
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_admin','base','res.users',True,1);
|
||||
|
||||
select setval('res_users_id_seq', 2);
|
||||
|
|
|
@ -23,17 +23,6 @@
|
|||
<field eval="'[(\'parent_id\',\'=\',False)]'" name="domain"/>
|
||||
</record>
|
||||
|
||||
<record id="group_admin" model="res.groups">
|
||||
<field name="name">Administration/Administrator</field>
|
||||
</record>
|
||||
|
||||
<record id="group_extended" model="res.groups">
|
||||
<field name="name">Extended View</field>
|
||||
</record>
|
||||
<record id="group_no_one" model="res.groups">
|
||||
<field name="name">No One</field>
|
||||
</record>
|
||||
|
||||
<record id="lang_en" model="res.lang">
|
||||
<field name="code">en_US</field>
|
||||
<field name="name">English</field>
|
||||
|
@ -1309,7 +1298,7 @@
|
|||
<field name="accuracy">4</field>
|
||||
</record>
|
||||
<record id="rateVEB" model="res.currency.rate">
|
||||
<field name="rate">1.0</field>
|
||||
<field name="rate">3132.9</field>
|
||||
<field name="currency_id" ref="VEB"/>
|
||||
<field eval="time.strftime('%Y-01-01')" name="name"/>
|
||||
</record>
|
||||
|
@ -1498,17 +1487,5 @@
|
|||
<test expr="currency_id.code == 'eur'.upper()"/>
|
||||
<test expr="name">Tiny sprl</test>
|
||||
</assert>
|
||||
|
||||
<record id="user_admin" model="res.users">
|
||||
<field name="login">admin</field>
|
||||
<field name="password">admin</field>
|
||||
<field name="name">Administrator</field>
|
||||
<field name="signature">Administrator</field>
|
||||
<field name="action_id" ref="action_menu_admin"/>
|
||||
<field name="menu_id" ref="action_menu_admin"/>
|
||||
<field name="address_id" ref="main_address"/>
|
||||
<field eval="[(6,0,[group_admin])]" name="groups_id"/>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
</record>
|
||||
</data>
|
||||
</terp>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<field name="menu_id" ref="action_menu_admin"/>
|
||||
<field name="address_id" ref="main_address"/>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
<field name="groups_id" eval="('base.group_user')"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
</terp>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<terp>
|
||||
<data>
|
||||
<menuitem groups="group_admin" icon="terp-administration" id="menu_administration" name="Administration" sequence="20"/>
|
||||
<menuitem icon="terp-administration" id="menu_administration" name="Administration" sequence="20"/>
|
||||
<menuitem id="menu_custom" name="Custom" parent="base.menu_administration" sequence="2"/>
|
||||
<menuitem id="menu_translation" name="Translations" parent="base.menu_administration" sequence="4"/>
|
||||
<menuitem id="menu_translation_app" name="Application Terms" parent="base.menu_translation" sequence="4"/>
|
||||
<menuitem id="menu_translation_export" name="Import / Export" parent="base.menu_translation" sequence="4"/>
|
||||
<menuitem id="menu_users" name="Users" parent="base.menu_administration" sequence="6"/>
|
||||
<menuitem id="menu_security" name="Security" parent="base.menu_administration" sequence="8"/>
|
||||
<menuitem id="menu_management" name="Modules Management" parent="base.menu_administration" sequence="10"/>
|
||||
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
</terp>
|
||||
|
|
|
@ -1,662 +1,160 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data noupdate="1">
|
||||
<record id="access_ui_menu" model="ir.model.access">
|
||||
<field name="name">UI menu</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.ui.menu')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_ui_menu_admin" model="ir.model.access">
|
||||
<field name="name">UI menu</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.ui.menu')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_act_window" model="ir.model.access">
|
||||
<field name="name">Act window</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.act_window')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_act_window_admin" model="ir.model.access">
|
||||
<field name="name">Act window</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.act_window')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_actions" model="ir.model.access">
|
||||
<field name="name">Actions</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.actions')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_actions_admin" model="ir.model.access">
|
||||
<field name="name">Actions</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.actions')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_actions_report_custom" model="ir.model.access">
|
||||
<field name="name">Actions Report Custom</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.report.custom')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_actions_report_custom_admin" model="ir.model.access">
|
||||
<field name="name">Actions Report Custom</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.report.custom')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_actions_report_xml" model="ir.model.access">
|
||||
<field name="name">Actions Report XML</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.report.xml')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_actions_report_xml_admin" model="ir.model.access">
|
||||
<field name="name">Actions Report XML</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.report.xml')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_actions_act_window_view" model="ir.model.access">
|
||||
<field name="name">Actions Act Window view</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.act_window.view')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_actions_act_window_view_admin" model="ir.model.access">
|
||||
<field name="name">Actions Act Window view</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.act_window.view')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_actions_wizard" model="ir.model.access">
|
||||
<field name="name">Actions Wizard</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.wizard')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_actions_wizard_admin" model="ir.model.access">
|
||||
<field name="name">Actions Wizard</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.wizard')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_actions_url" model="ir.model.access">
|
||||
<field name="name">Actions URL</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.url')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_actions_url_admin" model="ir.model.access">
|
||||
<field name="name">Actions URL</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.url')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_groups" model="ir.model.access">
|
||||
<field name="name">Groups</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.groups')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_groups_admin" model="ir.model.access">
|
||||
<field name="name">Groups</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.groups')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_roles" model="ir.model.access">
|
||||
<field name="name">Roles</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.roles')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_roles_admin" model="ir.model.access">
|
||||
<field name="name">Roles</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.roles')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_lang" model="ir.model.access">
|
||||
<field name="name">Lang</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.lang')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_lang_admin" model="ir.model.access">
|
||||
<field name="name">Lang</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.lang')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_country" model="ir.model.access">
|
||||
<field name="name">Country</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.country')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_country_admin" model="ir.model.access">
|
||||
<field name="name">Country</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.country')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_country_state" model="ir.model.access">
|
||||
<field name="name">Country State</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.country.state')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_country_state_admin" model="ir.model.access">
|
||||
<field name="name">Country State</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.country.state')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_currency" model="ir.model.access">
|
||||
<field name="name">Currency</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.currency')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_currency_admin" model="ir.model.access">
|
||||
<field name="name">Currency</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.currency')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_currency_rate" model="ir.model.access">
|
||||
<field name="name">Currency Rate</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.currency.rate')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_currency_rate_admin" model="ir.model.access">
|
||||
<field name="name">Currency Rate</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.currency.rate')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_company" model="ir.model.access">
|
||||
<field name="name">Company</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.company')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_company_admin" model="ir.model.access">
|
||||
<field name="name">Company</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.company')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_res_users" model="ir.model.access">
|
||||
<field name="name">Users</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.users')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_res_users_admin" model="ir.model.access">
|
||||
<field name="name">Users</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.users')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_cron" model="ir.model.access">
|
||||
<field name="name">Cron</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.cron')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_cron_admin" model="ir.model.access">
|
||||
<field name="name">Cron</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.cron')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_model" model="ir.model.access">
|
||||
<field name="name">Model</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_model_admin" model="ir.model.access">
|
||||
<field name="name">Model</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_model_fields" model="ir.model.access">
|
||||
<field name="name">Model Fields</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model.fields')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_model_fields_admin" model="ir.model.access">
|
||||
<field name="name">Model Fields</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model.fields')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_model_access" model="ir.model.access">
|
||||
<field name="name">Model Access</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model.access')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_model_access_admin" model="ir.model.access">
|
||||
<field name="name">Model Access</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model.access')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_model_data" model="ir.model.access">
|
||||
<field name="name">Model Data</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model.data')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_model_data_admin" model="ir.model.access">
|
||||
<field name="name">Model Data</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.model.data')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_report_custom" model="ir.model.access">
|
||||
<field name="name">Report Custom</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.report.custom')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_report_custom_admin" model="ir.model.access">
|
||||
<field name="name">Report Custom</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.report.custom')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_report_custom_fields" model="ir.model.access">
|
||||
<field name="name">Report Custom Fields</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.report.custom.fields')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_report_custom_fields_admin" model="ir.model.access">
|
||||
<field name="name">Report Custom Fields</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.report.custom.fields')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_rule_group" model="ir.model.access">
|
||||
<field name="name">Rule group</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.rule.group')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_rule_group_admin" model="ir.model.access">
|
||||
<field name="name">Rule group</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.rule.group')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_rule" model="ir.model.access">
|
||||
<field name="name">Rule</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.rule')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_rule_admin" model="ir.model.access">
|
||||
<field name="name">Rule</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.rule')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_sequence_type" model="ir.model.access">
|
||||
<field name="name">Sequence Type</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.sequence.type')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_sequence_type_admin" model="ir.model.access">
|
||||
<field name="name">Sequence Type</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.sequence.type')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_sequence" model="ir.model.access">
|
||||
<field name="name">Sequence</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.sequence')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_sequence_admin" model="ir.model.access">
|
||||
<field name="name">Sequence</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.sequence')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_view" model="ir.model.access">
|
||||
<field name="name">View</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.ui.view')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_view_admin" model="ir.model.access">
|
||||
<field name="name">View</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.ui.view')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_workflow" model="ir.model.access">
|
||||
<field name="name">Workflow</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'workflow')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_workflow_admin" model="ir.model.access">
|
||||
<field name="name">Workflow</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'workflow')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_workflow_activity" model="ir.model.access">
|
||||
<field name="name">Workflow Activity</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'workflow.activity')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_workflow_activity_admin" model="ir.model.access">
|
||||
<field name="name">Workflow Activity</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'workflow.activity')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_workflow_transition" model="ir.model.access">
|
||||
<field name="name">Workflow Transition</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'workflow.transition')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_workflow_transition_admin" model="ir.model.access">
|
||||
<field name="name">Workflow Transition</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'workflow.transition')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_module_repository" model="ir.model.access">
|
||||
<field name="name">Module Repository</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.repository')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_module_repository_admin" model="ir.model.access">
|
||||
<field name="name">Module Repository</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.repository')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_module_category" model="ir.model.access">
|
||||
<field name="name">Module Category</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.category')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_module_category_admin" model="ir.model.access">
|
||||
<field name="name">Module Category</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.category')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_module_module" model="ir.model.access">
|
||||
<field name="name">Module</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.module')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_module_module_admin" model="ir.model.access">
|
||||
<field name="name">Module</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.module')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_module_dependency" model="ir.model.access">
|
||||
<field name="name">Module Dependency</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.module.dependency')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="False" name="perm_write"/>
|
||||
<field eval="False" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
<record id="access_module_dependency_admin" model="ir.model.access">
|
||||
<field name="name">Module Dependency</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.module.module.dependency')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="True" name="perm_unlink"/>
|
||||
</record>
|
||||
|
||||
<record id="access_ui_menu" model="ir.model.access">
|
||||
<field name="name">Internal Request</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'res.request')]"/>
|
||||
<field eval="True" name="perm_read"/>
|
||||
<field eval="True" name="perm_write"/>
|
||||
<field eval="True" name="perm_create"/>
|
||||
<field eval="False" name="perm_unlink"/>
|
||||
</record>
|
||||
</data>
|
||||
</terp>
|
||||
<data noupdate="1">
|
||||
|
||||
<!--
|
||||
Users Groups
|
||||
-->
|
||||
<record model="res.groups" id="group_system">
|
||||
<field name="name">Administrator / Configuration</field>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_erp_manager">
|
||||
<field name="name">Administrator / Access Rights</field>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_user">
|
||||
<field name="name">Employee</field>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_account_manager">
|
||||
<field name="name">Account Manager</field>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_extended">
|
||||
<field name="name">Useability / Extended View</field>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_no_one">
|
||||
<field name="name">Useability / No One</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Users
|
||||
-->
|
||||
<record model="res.users" id="base.user_root">
|
||||
<field name="signature">Administrator</field>
|
||||
<field name="address_id" ref="main_address"/>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
<field name="action_id" ref="action_menu_admin"/>
|
||||
<field name="menu_id" ref="action_menu_admin"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Access
|
||||
-->
|
||||
|
||||
<!--Don't remove after-->
|
||||
<record model="ir.model.access" id="access_ir_actions_employee">
|
||||
<field name="name">ir.actions.actions Employee</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.actions')]"/>
|
||||
<field name="group_id" ref="group_user"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_ir_actions_act_window_employee">
|
||||
<field name="name">ir.actions.act_window Employee</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.act_window')]"/>
|
||||
<field name="group_id" ref="group_user"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_ir_actions_act_window_employee">
|
||||
<field name="name">ir.actions.act_window_close System</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.act_window_close')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_ir_actions_act_window_employee">
|
||||
<field name="name">ir.actions.act_window_close System</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.report.xml')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_ir_actions_act_window_employee">
|
||||
<field name="name">ir.actions.act_window_close System</field>
|
||||
<field model="ir.model" name="model_id" search="[('model', '=', 'ir.actions.wizard')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_workflow_group_system">
|
||||
<field name="name">workflow group_system</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'workflow')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_workflow_activity_group_system">
|
||||
<field name="name">workflow_activity group_system</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'workflow.activity')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_workflow_instance_group_system">
|
||||
<field name="name">workflow_instance group_system</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'workflow.instance')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_workflow_transition_group_system">
|
||||
<field name="name">workflow_transition group_system</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'workflow.transition')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_workflow_triggers_group_system">
|
||||
<field name="name">workflow_triggers group_system</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'workflow.triggers')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_workflow_workitem_group_system">
|
||||
<field name="name">workflow_workitem group_system</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'workflow.workitem')]"/>
|
||||
<field name="group_id" ref="group_system"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
<!--Don't remove before-->
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
|
|
@ -6,26 +6,7 @@
|
|||
Languages
|
||||
======================
|
||||
-->
|
||||
<record id="view_lang" model="ir.ui.view">
|
||||
<field name="name">Languages</field>
|
||||
<field name="model">res.lang</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Language">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="translatable"/>
|
||||
<field name="direction"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_lang" model="ir.actions.act_window">
|
||||
<field name="name">Languages</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.lang</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem id="next_id_2" name="Interface" parent="base.menu_custom"/><menuitem action="action_lang" id="menu_action_lang" parent="next_id_2"/>
|
||||
<menuitem id="next_id_2" name="Interface" parent="base.menu_custom"/>
|
||||
|
||||
<!--
|
||||
======================
|
||||
|
@ -48,6 +29,14 @@
|
|||
</page>
|
||||
<page string="Access Rights">
|
||||
<field colspan="4" name="model_access" nolabel="1">
|
||||
<tree string="Access Rules" editable="top">
|
||||
<field name="model_id"/>
|
||||
<field name="perm_read"/>
|
||||
<field name="perm_write"/>
|
||||
<field name="perm_create"/>
|
||||
<field name="perm_unlink"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
<form string="Access Controls">
|
||||
<field colspan="4" name="name" select="1"/>
|
||||
<field name="model_id" select="1"/>
|
||||
|
@ -60,7 +49,13 @@
|
|||
</field>
|
||||
</page>
|
||||
<page string="Rules">
|
||||
<field colspan="4" name="rule_groups" nolabel="1"/>
|
||||
<field colspan="4" name="rule_groups" nolabel="1">
|
||||
<tree string="Rules">
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="global"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page><page string="Notes">
|
||||
<field colspan="4" name="comment" nolabel="1"/>
|
||||
</page>
|
||||
|
@ -162,6 +157,8 @@
|
|||
<page string="Internal Header/Footer">
|
||||
<field colspan="4" name="rml_header2" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Configuration">
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -189,6 +186,7 @@
|
|||
<field name="name" select="1"/>
|
||||
<newline/>
|
||||
<field name="login" select="1"/>
|
||||
<newline/>
|
||||
<field name="password" required="1"/>
|
||||
<field colspan="4" name="signature"/>
|
||||
<separator string="Assign Groups to Define Access Rights" colspan="4"/>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,76 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_ir_attachment_group_user,"ir_attachment group_system_user",model_ir_attachment,group_user,1,1,1,1
|
||||
access_ir_attachment_group_system,"ir_attachment group_system",model_ir_attachment,,1,0,0,0
|
||||
access_ir_cron_group_cron,"ir_cron group_cron",model_ir_cron,group_system,1,1,1,1
|
||||
access_ir_default_group_system,"ir_default group_system",model_ir_default,,1,1,1,1
|
||||
access_ir_exports_group_system,"ir_exports group_system",model_ir_exports,,1,1,1,1
|
||||
access_ir_exports_line_group_system,"ir_exports_line group_system",model_ir_exports_line,,1,1,1,1
|
||||
access_ir_model_group_system,"ir_model group_system",model_ir_model,,1,0,0,0
|
||||
access_ir_model_access_group_system,"ir_model_access group_system",model_ir_model_access,,1,0,0,0
|
||||
access_ir_model_config_group_system,"ir_model_config group_system",model_ir_model_config,,1,0,0,0
|
||||
access_ir_model_data_group_user,"ir_model_data group_user",model_ir_model_data,,1,0,0,0
|
||||
access_ir_model_fields_group_user,"ir_model_fields group_user",model_ir_model_fields,,1,0,0,0
|
||||
access_ir_module_category_group_user,"ir_module_category group_user",model_ir_module_category,group_system,1,0,0,0
|
||||
access_ir_module_module_group_user,"ir_module_module group_user",model_ir_module_module,group_system,1,1,1,1
|
||||
access_ir_module_module_configuration_step_group_system,"ir_module_module_configuration_step group_system",model_ir_module_module_configuration_step,group_system,1,1,1,1
|
||||
access_ir_module_module_configuration_wizard_group_system,"ir_module_module_configuration_wizard group_system",model_ir_module_module_configuration_wizard,group_system,1,1,1,1
|
||||
access_ir_module_module_dependency_group_system,"ir_module_module_dependency group_system",model_ir_module_module_dependency,group_system,1,1,1,1
|
||||
access_ir_module_repository_group_system,"ir_module_repository group_system",model_ir_module_repository,group_system,1,1,1,1
|
||||
access_ir_property_group_user,"ir_property group_user",model_ir_property,,1,0,0,0
|
||||
access_ir_report_custom_group_system,"ir_report_custom group_system",model_ir_report_custom,,1,0,0,0
|
||||
access_ir_report_custom_fields_group_system,"ir_report_custom_fields group_system",model_ir_report_custom_fields,,1,0,0,0
|
||||
access_ir_rule_group_user,"ir_rule group_user",model_ir_rule,,1,0,0,0
|
||||
access_ir_rule_group_group_user,"ir_rule_group group_user",model_ir_rule_group,,1,0,0,0
|
||||
access_ir_sequence_group_user,"ir_sequence group_user",model_ir_sequence,,1,1,1,1
|
||||
access_ir_sequence_type_group_user,"ir_sequence_type group_user",model_ir_sequence_type,,1,0,0,0
|
||||
access_ir_translation_group_system,"ir_translation group_system",model_ir_translation,,1,1,1,1
|
||||
access_ir_ui_menu_group_user,"ir_ui_menu group_user",model_ir_ui_menu,,1,0,0,0
|
||||
access_ir_ui_view_group_user,"ir_ui_view group_user",model_ir_ui_view,,1,0,0,0
|
||||
access_ir_ui_view_sc_group_user,"ir_ui_view_sc group_user",model_ir_ui_view_sc,,1,1,1,1
|
||||
access_ir_values_group_erp_manager,"ir_values group_erp_manager",model_ir_values,,1,1,1,1
|
||||
access_wizard_ir_model_menu_create_group_system,"wizard_ir_model_menu_create group_system",model_wizard_ir_model_menu_create,group_system,1,1,1,1
|
||||
access_wizard_ir_model_menu_create_line_group_system,"wizard_ir_model_menu_create_line group_system",model_wizard_ir_model_menu_create_line,group_system,1,1,1,1
|
||||
access_wizard_module_lang_export_group_system,"wizard_module_lang_export group_system",model_wizard_module_lang_export,group_system,1,1,1,1
|
||||
access_res_company_group_erp_manager,"res_company group_erp_manager",model_res_company,group_erp_manager,1,1,1,1
|
||||
access_res_company_group_user,"res_company group_user",model_res_company,,1,0,0,0
|
||||
access_res_country_group_all,"res_country group_user_all",model_res_country,,1,0,0,0
|
||||
access_res_country_state_group_all,"res_country_state group_user_all",model_res_country_state,,1,0,0,0
|
||||
access_res_country_group_user,"res_country group_user",model_res_country,group_partner_manager,1,1,1,1
|
||||
access_res_country_state_group_user,"res_country_state group_user",model_res_country_state,group_partner_manager,1,1,1,1
|
||||
access_res_currency_group_all,"res_currency group_all",model_res_currency,,1,0,0,0
|
||||
access_res_currency_rate_group_all,"res_currency_rate group_all",model_res_currency_rate,,1,0,0,0
|
||||
access_res_currency_group_user,"res_currency group_user",model_res_currency,group_user,1,1,1,1
|
||||
access_res_currency_rate_group_user,"res_currency_rate group_user",model_res_currency_rate,group_user,1,1,1,1
|
||||
access_res_groups_group_erp_manager,"res_groups group_erp_manager",model_res_groups,group_erp_manager,1,1,1,1
|
||||
access_res_groups_group_user,"res_groups group_user",model_res_groups,,1,0,0,0
|
||||
access_res_lang_group_all,"res_lang group_all",model_res_lang,,1,0,0,0
|
||||
access_res_lang_group_user,"res_lang group_user",model_res_lang,group_system,1,1,1,1
|
||||
access_res_partner_group_partner_manager,"res_partner group_partner_manager",model_res_partner,group_partner_manager,1,1,1,1
|
||||
access_res_partner_group_user,"res_partner group_user",model_res_partner,,1,0,0,0
|
||||
access_res_partner_address_group_partner_manager,"res_partner_address group_partner_manager",model_res_partner_address,group_partner_manager,1,1,1,1
|
||||
access_res_partner_address_group_user,"res_partner_address group_user",model_res_partner_address,,1,0,0,0
|
||||
access_res_partner_bank_group_user,"res_partner_bank group_user",model_res_partner_bank,,1,0,0,0
|
||||
access_res_partner_bank_group_partner_manager,"res_partner_bank group_partner_manager",model_res_partner_bank,group_partner_manager,1,1,1,1
|
||||
access_res_partner_bank_type_group_partner_manager,"res_partner_bank_type group_partner_manager",model_res_partner_bank_type,group_partner_manager,1,1,1,1
|
||||
access_res_partner_bank_type_group_user,"res_partner_bank_type group_user",model_res_partner_bank_type,,1,0,0,0
|
||||
access_res_partner_bank_type_field_group_partner_manager,"res_partner_bank_type_field group_partner_manager",model_res_partner_bank_type_field,group_partner_manager,1,1,1,1
|
||||
access_res_partner_bank_type_field_group_user,"res_partner_bank_type_field group_user",model_res_partner_bank_type_field,,1,0,0,0
|
||||
access_res_partner_canal_group_user,"res_partner_canal group_user",model_res_partner_canal,,1,0,0,0
|
||||
access_res_partner_canal_group_partner_manager,"res_partner_canal group_partner_manager",model_res_partner_canal,group_partner_manager,1,1,1,1
|
||||
access_res_partner_category_group_user,"res_partner_category group_user",model_res_partner_category,group_partner_manager,1,1,1,0
|
||||
access_res_partner_category_group_partner_manager,"res_partner_category group_partner_manager",model_res_partner_category,,1,0,0,1
|
||||
access_res_partner_event_group_user,"res_partner_event group_user",model_res_partner_event,,1,1,1,1
|
||||
access_res_partner_event_type_group_partner_manager,"res_partner_event_type group_partner_manager",model_res_partner_event_type,group_partner_manager,1,1,1,1
|
||||
access_res_partner_event_type_group_user,"res_partner_event_type group_user",model_res_partner_event_type,,1,0,0,0
|
||||
access_res_partner_function_group_user,"res_partner_function group_user",model_res_partner_function,group_partner_manager,1,1,1,1
|
||||
access_res_partner_function_group_partner_manager,"res_partner_function group_partner_manager",model_res_partner_function,,1,0,0,0
|
||||
access_res_partner_som_group_user,"res_partner_som group_user",model_res_partner_som,group_partner_manager,1,1,1,1
|
||||
access_res_partner_som_group_partner_manager,"res_partner_som group_partner_manager",model_res_partner_som,,1,0,0,0
|
||||
access_res_partner_title_group_user,"res_partner_title group_user",model_res_partner_title,group_partner_manager,1,1,1,1
|
||||
access_res_partner_title_group_partner_manager,"res_partner_title group_partner_manager",model_res_partner_title,,1,0,0,0
|
||||
access_res_request_group_user,"res_request group_user",model_res_request,,1,1,1,1
|
||||
access_res_request_history_group_user,"res_request_history group_user",model_res_request_history,,1,1,1,1
|
||||
access_res_request_link_group_system,"res_request_link group_system",model_res_request_link,group_system,1,1,1,1
|
||||
access_res_request_link_group_user,"res_request_link group_user",model_res_request_link,,1,0,0,0
|
||||
access_res_users_group_user,"res_users group_user",model_res_users,,1,0,0,0
|
||||
access_res_users_group_erp_manager,"res_users group_erp_manager",model_res_users,group_erp_manager,1,1,1,1
|
|
|
@ -49,8 +49,8 @@
|
|||
<field name="context">{'read':'default'}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="next_id_4" name="Low Level" parent="menu_custom"/>
|
||||
<menuitem action="act_values_form" id="menu_values_form" parent="next_id_4"/>
|
||||
<menuitem id="next_id_4" name="Low Level" parent="menu_custom"/>
|
||||
<menuitem action="act_values_form" id="menu_values_form" parent="next_id_4"/>
|
||||
|
||||
<!-- Sequences -->
|
||||
|
||||
|
@ -97,7 +97,8 @@
|
|||
<field name="view_id" ref="sequence_view_tree"/>
|
||||
<field name="context">{'active_test': False}</field>
|
||||
</record>
|
||||
<menuitem id="next_id_5" name="Sequences" parent="base.menu_custom"/><menuitem action="ir_sequence_form" id="menu_ir_sequence_form" parent="next_id_5"/>
|
||||
<menuitem id="next_id_5" name="Sequences" parent="base.menu_custom"/>
|
||||
<menuitem action="ir_sequence_form" id="menu_ir_sequence_form" parent="next_id_5"/>
|
||||
|
||||
<!-- Sequences Types -->
|
||||
|
||||
|
@ -112,7 +113,7 @@
|
|||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="ir_sequence_type" model="ir.actions.act_window">
|
||||
<field name="name">Sequence Types</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
|
@ -157,7 +158,8 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="action_view_tree"/>
|
||||
</record>
|
||||
<menuitem id="next_id_6" name="Actions" parent="base.next_id_4"/><menuitem action="ir_sequence_actions" id="menu_ir_sequence_actions" parent="next_id_6"/>
|
||||
<menuitem id="next_id_6" name="Actions" parent="base.next_id_4"/>
|
||||
<menuitem action="ir_sequence_actions" id="menu_ir_sequence_actions" parent="next_id_6"/>
|
||||
|
||||
<record id="act_report_custom_view" model="ir.ui.view">
|
||||
<field name="name">ir.actions.report.custom</field>
|
||||
|
@ -209,6 +211,7 @@
|
|||
<field name="usage"/>
|
||||
<field name="header"/>
|
||||
<field name="report_type"/>
|
||||
<field name="attachment"/>
|
||||
<field colspan="4" name="groups_id"/>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -222,6 +225,8 @@
|
|||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="report_name"/>
|
||||
<field name="report_type"/>
|
||||
<field name="attachment"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -608,8 +613,8 @@
|
|||
<field name="view_id" ref="view_report_custom_form"/>
|
||||
</record>
|
||||
<!--
|
||||
<menuitem name="Administration/Report/Report Custom" action="action_report_custom"/>
|
||||
-->
|
||||
<menuitem name="Administration/Report/Report Custom" action="action_report_custom"/>
|
||||
-->
|
||||
|
||||
<!-- model -->
|
||||
<record id="view_model_form" model="ir.ui.view">
|
||||
|
@ -634,21 +639,32 @@
|
|||
<field name="state"/>
|
||||
</tree>
|
||||
<form string="Fields Description">
|
||||
<field name="name" select="1"/>
|
||||
<field colspan="4" name="field_description" select="1"/>
|
||||
<field name="ttype" select="1"/>
|
||||
<field name="relation" select="1"/>
|
||||
|
||||
<field name="required" select="2"/>
|
||||
<field name="readonly" select="2"/>
|
||||
|
||||
<field name="size" select="1"/>
|
||||
<field name="on_delete" select="1"/>
|
||||
<field name="select_level" select="2"/>
|
||||
<field name="translate"/>
|
||||
<field name="selection"/>
|
||||
<field name="domain"/>
|
||||
<field name="state" readonly="1"/>
|
||||
<group colspan="4" col="4">
|
||||
<field name="name" select="1"/>
|
||||
<field colspan="4" name="field_description" select="2"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Field Type" colspan="2"/>
|
||||
<field name="ttype" select="2"/>
|
||||
<field name="relation" select="2"/>
|
||||
<field name="selection"/>
|
||||
<field name="size"/>
|
||||
<field name="state"/>
|
||||
<field name="domain"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Properties" colspan="2"/>
|
||||
<field name="required" select="2"/>
|
||||
<field name="readonly" select="2"/>
|
||||
<field name="select_level"/>
|
||||
<field name="translate"/>
|
||||
<field name="relate"/>
|
||||
<field name="on_delete"/>
|
||||
</group>
|
||||
<separator string="Security on Groups" colspan="4"/>
|
||||
<field name="groups" colspan="4" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
<separator colspan="4" string="Status"/>
|
||||
|
@ -657,7 +673,19 @@
|
|||
<button colspan="2" name="%(act_menu_create)d" string="Create a Menu" type="action" target="new"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Information">
|
||||
<page string="Access Rights">
|
||||
<field colspan="4" name="access_ids" select="1" nolabel="1">
|
||||
<tree string="Access Rules" editable="bottom" colspan="4">
|
||||
<field name="group_id"/>
|
||||
<field name="perm_read"/>
|
||||
<field name="perm_write"/>
|
||||
<field name="perm_create"/>
|
||||
<field name="perm_unlink"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Notes">
|
||||
<field colspan="4" name="info" nolabel="1" select="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -686,22 +714,33 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Fields">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model_id" readonly="1"/>
|
||||
<field colspan="4" name="field_description" select="2"/>
|
||||
<field name="ttype" select="2"/>
|
||||
<field name="relation" select="2"/>
|
||||
|
||||
<field name="required" select="2"/>
|
||||
<field name="readonly" select="2"/>
|
||||
|
||||
<field name="size" select="1"/>
|
||||
<field name="on_delete" select="1"/>
|
||||
<field name="select_level" select="2"/>
|
||||
<field name="translate"/>
|
||||
<field name="selection"/>
|
||||
<field name="domain"/>
|
||||
<field name="state" readonly="1"/>
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field colspan="4" name="field_description" select="2"/>
|
||||
<field name="model_id" readonly="1"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Field Type" colspan="2"/>
|
||||
<field name="ttype" select="2"/>
|
||||
<field name="relation" select="2"/>
|
||||
<field name="selection"/>
|
||||
<field name="size"/>
|
||||
<field name="state"/>
|
||||
<field name="domain"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Properties" colspan="2"/>
|
||||
<field name="required" select="2"/>
|
||||
<field name="readonly" select="2"/>
|
||||
<field name="select_level"/>
|
||||
<field name="translate"/>
|
||||
<field name="relate"/>
|
||||
<field name="on_delete"/>
|
||||
</group>
|
||||
<separator string="Security on Groups" colspan="4"/>
|
||||
<field name="groups" colspan="4" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -727,7 +766,7 @@
|
|||
<field name="view_id" ref="view_model_tree"/>
|
||||
</record>
|
||||
<menuitem id="next_id_9" name="Database Structure" parent="base.menu_custom"/>
|
||||
<menuitem action="action_model_model" id="ir_model_model_menu" parent="next_id_9"/>
|
||||
<menuitem action="action_model_model" id="ir_model_model_menu" parent="next_id_9"/>
|
||||
|
||||
<record id="action_model_fields" model="ir.actions.act_window">
|
||||
<field name="name">Fields</field>
|
||||
|
@ -776,13 +815,21 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_translation_tree"/>
|
||||
</record>
|
||||
<menuitem action="action_translation" id="menu_action_translation" parent="base.menu_translation"/>
|
||||
|
||||
<menuitem action="action_translation" id="menu_action_translation" parent="base.menu_translation_app"/>
|
||||
<record id="action_translation_untrans" model="ir.actions.act_window">
|
||||
<field name="name">Untranslated terms</field>
|
||||
<field name="res_model">ir.translation</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_translation_tree"/>
|
||||
<field name="domain">[('value','=','')]</field>
|
||||
</record>
|
||||
<menuitem action="action_translation_untrans" id="menu_action_translation_untrans" parent="menu_action_translation"/>
|
||||
|
||||
<!--
|
||||
=============================================================
|
||||
Menu Edition
|
||||
=============================================================
|
||||
-->
|
||||
=============================================================
|
||||
Menu Edition
|
||||
=============================================================
|
||||
-->
|
||||
|
||||
<record id="shortcut_form" model="ir.ui.view">
|
||||
<field name="name">ir.ui.view_sc</field>
|
||||
|
@ -831,8 +878,8 @@
|
|||
<field colspan="4" name="parent_id" select="1"/>
|
||||
<field name="action"/>
|
||||
<field colspan="4" name="groups_id"/>
|
||||
<field name="icon" on_change="onchange_icon(icon)"/>
|
||||
<field name="icon_pict" widget="picture" nolabel="1"/>
|
||||
<field name="icon" on_change="onchange_icon(icon)"/>
|
||||
<field name="icon_pict" widget="picture" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -845,10 +892,10 @@
|
|||
<menuitem action="grant_menu_access" id="menu_grant_menu_access" parent="base.menu_security"/>
|
||||
|
||||
<!--
|
||||
=============================================================
|
||||
Cron Jobs
|
||||
=============================================================
|
||||
-->
|
||||
=============================================================
|
||||
Cron Jobs
|
||||
=============================================================
|
||||
-->
|
||||
<record id="ir_cron_view_tree" model="ir.ui.view">
|
||||
<field name="name">ir.cron.tree</field>
|
||||
<field name="model">ir.cron</field>
|
||||
|
@ -863,7 +910,7 @@
|
|||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="ir_cron_view" model="ir.ui.view">
|
||||
<record id="ir_cron_view" model="ir.ui.view">
|
||||
<field name="name">ir.cron.form</field>
|
||||
<field name="model">ir.cron</field>
|
||||
<field name="type">form</field>
|
||||
|
@ -895,7 +942,8 @@
|
|||
<field name="context">{'active_test': False}</field>
|
||||
<field name="view_id" ref="ir_cron_view_tree"/>
|
||||
</record>
|
||||
<menuitem id="next_id_10" name="Scheduler" parent="base.menu_custom"/><menuitem action="ir_cron_act" id="menu_ir_cron_act" parent="next_id_10"/>
|
||||
<menuitem id="next_id_10" name="Scheduler" parent="base.menu_custom"/>
|
||||
<menuitem action="ir_cron_act" id="menu_ir_cron_act" parent="next_id_10"/>
|
||||
|
||||
|
||||
<record id="ir_access_view_tree" model="ir.ui.view">
|
||||
|
@ -903,7 +951,7 @@
|
|||
<field name="model">ir.model.access</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Access controls">
|
||||
<tree string="Access Controls">
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="group_id"/>
|
||||
|
@ -919,7 +967,7 @@
|
|||
<field name="model">ir.model.access</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Access controls">
|
||||
<form string="Access Controls">
|
||||
<field colspan="4" name="name" select="1"/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="group_id" select="1"/>
|
||||
|
@ -932,15 +980,16 @@
|
|||
</field>
|
||||
</record>
|
||||
<record id="ir_access_act" model="ir.actions.act_window">
|
||||
<field name="name">Access controls</field>
|
||||
<field name="name">Access Controls List</field>
|
||||
<field name="res_model">ir.model.access</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="ir_access_view_tree"/>
|
||||
</record>
|
||||
<menuitem action="ir_access_act" id="menu_ir_access_act" parent="base.menu_security"/>
|
||||
<menuitem name="Access Controls" id="menu_security_access" parent="menu_security"/>
|
||||
<menuitem action="ir_access_act" id="menu_ir_access_act" parent="menu_security_access"/>
|
||||
|
||||
<!-- Rules -->
|
||||
|
||||
|
||||
<record id="view_rule_group_form" model="ir.ui.view">
|
||||
<field name="name">Record rules</field>
|
||||
<field name="model">ir.rule.group</field>
|
||||
|
@ -1039,54 +1088,54 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Server Action">
|
||||
<field name="name" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="sequence" select="2"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Python Code" attrs="{'invisible':[('state','!=','python')]}">
|
||||
<separator colspan="4" string="Python code"/>
|
||||
<field name="code" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
|
||||
<page string="Trigger" attrs="{'invisible':[('state','!=','trigger')]}">
|
||||
<separator colspan="4" string="Trigger Configuration"/>
|
||||
<field name="trigger_obj_id" select="2" colspan="4"/>
|
||||
<field name="trigger_name" select="2"/>
|
||||
</page>
|
||||
|
||||
<page string="Email / SMS" attrs="{'invisible':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','object_create'), ('state','=','object_write'), ('state','=','client_action'), ('state','=','other')]}">
|
||||
<separator colspan="4" string="Email Configuration"/>
|
||||
<field name="address" domain="[('model_id','=',model_id)]"/>
|
||||
<field name="message" select="2" colspan="4" widget="html_tag"/>
|
||||
<newline/>
|
||||
<label colspan="4" string="Access all the fields related to the current object easily just by defining name of the attribute, i.e. [[partner_id.name]] for Invoice Object"/>
|
||||
</page>
|
||||
|
||||
<page string="Create / Write" attrs="{'invisible':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','sms'), ('state','=','email'), ('state','=','client_action'), ('state','=','other')]}">
|
||||
<separator colspan="4" string="Fields Mapping"/>
|
||||
<field name="otype"/>
|
||||
<field name="srcmodel_id" select="2" attrs="{'readonly':[('type','=','copy'),('state','=','write_create')]}"/>
|
||||
<field name="fields_lines" nolabel="1" select="2" colspan="4">
|
||||
<tree string="Field Mappings" editable="top">
|
||||
<field name="col1" domain="[('model_id','=',parent.srcmodel_id or parent.model_id)]"/>
|
||||
<field name="type"/>
|
||||
<field name="value" colsapan="4"/>
|
||||
</tree>
|
||||
<form string="Field Mapping">
|
||||
<field name="col1" domain="[('model_id','=',parent.srcmodel_id or parent.model_id)]"/>
|
||||
<field name="type"/>
|
||||
<field name="value" colsapan="4"/>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
<page string="Other Actions" attrs="{'invisible':[('state','!=','other')]}">
|
||||
<separator colspan="4" string="Other Actions Configuration"/>
|
||||
<field name="child_ids" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
|
||||
</notebook>
|
||||
<notebook colspan="4">
|
||||
<page string="Python Code" attrs="{'invisible':[('state','!=','python')]}">
|
||||
<separator colspan="4" string="Python code"/>
|
||||
<field name="code" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
|
||||
<page string="Trigger" attrs="{'invisible':[('state','!=','trigger')]}">
|
||||
<separator colspan="4" string="Trigger Configuration"/>
|
||||
<field name="trigger_obj_id" select="2" colspan="4"/>
|
||||
<field name="trigger_name" select="2"/>
|
||||
</page>
|
||||
|
||||
<page string="Email / SMS" attrs="{'invisible':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','object_create'), ('state','=','object_write'), ('state','=','client_action'), ('state','=','other')]}">
|
||||
<separator colspan="4" string="Email Configuration"/>
|
||||
<field name="address" domain="[('model_id','=',model_id)]"/>
|
||||
<field name="message" select="2" colspan="4" widget="html_tag"/>
|
||||
<newline/>
|
||||
<label colspan="4" string="Access all the fields related to the current object easily just by defining name of the attribute, i.e. [[partner_id.name]] for Invoice Object"/>
|
||||
</page>
|
||||
|
||||
<page string="Create / Write" attrs="{'invisible':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','sms'), ('state','=','email'), ('state','=','client_action'), ('state','=','other')]}">
|
||||
<separator colspan="4" string="Fields Mapping"/>
|
||||
<field name="otype"/>
|
||||
<field name="srcmodel_id" select="2" attrs="{'readonly':[('type','=','copy'),('state','=','write_create')]}"/>
|
||||
<field name="fields_lines" nolabel="1" select="2" colspan="4">
|
||||
<tree string="Field Mappings" editable="top">
|
||||
<field name="col1" domain="[('model_id','=',parent.srcmodel_id or parent.model_id)]"/>
|
||||
<field name="type"/>
|
||||
<field name="value" colsapan="4"/>
|
||||
</tree>
|
||||
<form string="Field Mapping">
|
||||
<field name="col1" domain="[('model_id','=',parent.srcmodel_id or parent.model_id)]"/>
|
||||
<field name="type"/>
|
||||
<field name="value" colsapan="4"/>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
<page string="Other Actions" attrs="{'invisible':[('state','!=','other')]}">
|
||||
<separator colspan="4" string="Other Actions Configuration"/>
|
||||
<field name="child_ids" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
|
||||
</notebook>
|
||||
<field name="usage"/>
|
||||
<field name="type"/>
|
||||
</form>
|
||||
|
@ -1114,19 +1163,28 @@
|
|||
<field name="context">{'key':'server_action'}</field>
|
||||
</record>
|
||||
<menuitem action="action_server_action" id="menu_server_action" parent="base.next_id_6"/>
|
||||
|
||||
<record id="view_model_fields_tree" model="ir.ui.view">
|
||||
|
||||
<record id="view_model_fields_tree" model="ir.ui.view">
|
||||
<field name="name">ir.model.fields.tree</field>
|
||||
<field name="model">ir.model.fields</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Fields">
|
||||
<field name="complete_name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="complete_name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="name"/>
|
||||
<field name="field_description"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_model_grid_security">
|
||||
<field name="name">Access Controls Grid</field>
|
||||
<field name="res_model">ir.model.grid</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem action="action_model_grid_security" id="menu_ir_access_grid" parent="menu_security_access"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
|
|
@ -128,8 +128,8 @@ class report_xml(osv.osv):
|
|||
('raw', 'raw'),
|
||||
('sxw', 'sxw'),
|
||||
], string='Type', required=True),
|
||||
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups')
|
||||
|
||||
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'),
|
||||
'attachment': fields.char('Save As Attachment Prefix', size=32, help='This is the prefix of the file name the print will be saved as attachement. Keep empty to not save the printed reports')
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.report.xml',
|
||||
|
@ -138,6 +138,7 @@ class report_xml(osv.osv):
|
|||
'header': lambda *a: True,
|
||||
'report_sxw_content': lambda *a: False,
|
||||
'report_type': lambda *a: 'pdf',
|
||||
'attachment': lambda *a: False,
|
||||
}
|
||||
|
||||
report_xml()
|
||||
|
@ -154,7 +155,7 @@ class act_window(osv.osv):
|
|||
if (not act.view_ids):
|
||||
modes = act.view_mode.split(',')
|
||||
find = False
|
||||
if act.view_id.id:
|
||||
if act.view_id:
|
||||
res[act.id].append((act.view_id.id, act.view_id.type))
|
||||
for t in modes:
|
||||
if act.view_id and (t == act.view_id.type) and not find:
|
||||
|
@ -560,7 +561,3 @@ class act_window_close(osv.osv):
|
|||
'type': lambda *a: 'ir.actions.act_window_close',
|
||||
}
|
||||
act_window_close()
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Copyright (c) 2008 Camptocamp SA
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
@ -50,13 +50,13 @@ class ir_model(osv.osv):
|
|||
'model': fields.char('Object Name', size=64, required=True, search=1),
|
||||
'info': fields.text('Information'),
|
||||
'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True),
|
||||
'state': fields.selection([('manual','Custom Object'),('base','Base Field')],'Manualy Created',readonly=1),
|
||||
'state': fields.selection([('manual','Custom Object'),('base','Base Object')],'Manualy Created',readonly=1),
|
||||
'access_ids': fields.one2many('ir.model.access', 'model_id', 'Access'),
|
||||
}
|
||||
_defaults = {
|
||||
'model': lambda *a: 'x_',
|
||||
'state': lambda self,cr,uid,ctx={}: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
|
||||
}
|
||||
|
||||
def _check_model_name(self, cr, uid, ids):
|
||||
for model in self.browse(cr, uid, ids):
|
||||
if model.state=='manual':
|
||||
|
@ -97,6 +97,103 @@ class ir_model(osv.osv):
|
|||
x_custom_model._rec_name = x_custom_model._columns.keys()[0]
|
||||
ir_model()
|
||||
|
||||
|
||||
class ir_model_grid(osv.osv):
|
||||
_name = 'ir.model.grid'
|
||||
_table = 'ir_model'
|
||||
_description = "Objects Security Grid"
|
||||
_rec_name = 'name'
|
||||
_columns = {
|
||||
'name': fields.char('Object', size=64),
|
||||
'model': fields.char('Object Name', size=64),
|
||||
}
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
raise osv.except_osv('Error !', 'You cannot add an entry to this view !')
|
||||
|
||||
def unlink(self, *args, **argv):
|
||||
raise osv.except_osv('Error !', 'You cannot add an entry to this view !')
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||
result = super(osv.osv, self).read(cr, uid, ids, fields, context, load)
|
||||
allgr = self.pool.get('res.groups').search(cr, uid, [], context=context)
|
||||
acc_obj = self.pool.get('ir.model.access')
|
||||
for res in result:
|
||||
rules = acc_obj.search(cr, uid, [('model_id', '=', res['id'])])
|
||||
rules_br = acc_obj.browse(cr, uid, rules, context=context)
|
||||
for g in allgr:
|
||||
res['group_'+str(g)] = ''
|
||||
for rule in rules_br:
|
||||
perm_list = []
|
||||
if rule.perm_read:
|
||||
perm_list.append('r')
|
||||
if rule.perm_write:
|
||||
perm_list.append('w')
|
||||
if rule.perm_create:
|
||||
perm_list.append('c')
|
||||
if rule.perm_unlink:
|
||||
perm_list.append('u')
|
||||
perms = ",".join(perm_list)
|
||||
if rule.group_id:
|
||||
res['group_%d'%rule.group_id.id] = perms
|
||||
else:
|
||||
res['group_0'] = perms
|
||||
return result
|
||||
|
||||
#
|
||||
# This function do not write fields from ir.model because
|
||||
# access rights may be different for managing models and
|
||||
# access rights
|
||||
#
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
vals_new = vals.copy()
|
||||
acc_obj = self.pool.get('ir.model.access')
|
||||
for grid in self.browse(cr, uid, ids, context=context):
|
||||
model_id = grid.id
|
||||
perms_rel = ['read','write','create','unlink']
|
||||
for val in vals:
|
||||
if not val[:6]=='group_':
|
||||
continue
|
||||
group_id = int(val[6:]) or False
|
||||
rules = acc_obj.search(cr, uid, [('model_id', '=', model_id),('group_id', '=', group_id)])
|
||||
if not rules:
|
||||
rules = [acc_obj.create(cr, uid, {
|
||||
'name': grid.name,
|
||||
'model_id':model_id,
|
||||
'group_id':group_id
|
||||
}) ]
|
||||
vals = dict(map(lambda x: ('perm_'+x, x[0] in (vals[val] or '')), perms_rel))
|
||||
acc_obj.write(cr, uid, rules, vals, context=context)
|
||||
return True
|
||||
|
||||
def fields_get(self, cr, uid, fields=None, context=None, read_access=True):
|
||||
result = super(ir_model_grid, self).fields_get(cr, uid, fields, context)
|
||||
groups = self.pool.get('res.groups').search(cr, uid, [])
|
||||
groups_br = self.pool.get('res.groups').browse(cr, uid, groups)
|
||||
result['group_0'] = {'string': 'All Users','type': 'char','size': 7}
|
||||
for group in groups_br:
|
||||
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)
|
||||
groups = self.pool.get('res.groups').search(cr, uid, [])
|
||||
groups_br = self.pool.get('res.groups').browse(cr, uid, groups)
|
||||
cols = ['model', 'name']
|
||||
xml = '''<?xml version="1.0"?>
|
||||
<%s editable="bottom">
|
||||
<field name="name" select="1" readonly="1"/>
|
||||
<field name="model" select="1" readonly="1"/>
|
||||
<field name="group_0"/>
|
||||
''' % (view_type,)
|
||||
for group in groups_br:
|
||||
xml += '''<field name="group_%d"/>''' % (group.id, )
|
||||
xml += '''</%s>''' % (view_type,)
|
||||
result['arch'] = xml
|
||||
result['fields'] = self.fields_get(cr, uid, cols, context)
|
||||
return result
|
||||
ir_model_grid()
|
||||
|
||||
class ir_model_fields(osv.osv):
|
||||
_name = 'ir.model.fields'
|
||||
_description = "Fields"
|
||||
|
@ -176,7 +273,7 @@ class ir_model_access(osv.osv):
|
|||
res = False
|
||||
grouparr = group.split('.')
|
||||
if grouparr:
|
||||
cr.execute("select * from res_groups_users_rel where uid=" + str(uid) + " and gid in(select res_id from ir_model_data where module='%s' and name='%s')" % (grouparr[0], grouparr[1]))
|
||||
cr.execute("select * from res_groups_users_rel where uid=" + str(uid) + " and gid in(select res_id from ir_model_data where module=%s and name=%s)", (grouparr[0], grouparr[1],))
|
||||
r = cr.fetchall()
|
||||
if not r:
|
||||
res = False
|
||||
|
@ -186,30 +283,29 @@ class ir_model_access(osv.osv):
|
|||
res = False
|
||||
return res
|
||||
|
||||
def check_groups_by_id(self, cr, uid, group_id):
|
||||
cr.execute("select * from res_groups_users_rel where uid=%i and gid=%i", (uid, group_id,))
|
||||
r = cr.fetchall()
|
||||
if not r:
|
||||
res = False
|
||||
else:
|
||||
res = True
|
||||
return res
|
||||
|
||||
def check(self, cr, uid, model_name, mode='read',raise_exception=True):
|
||||
assert mode in ['read','write','create','unlink'], 'Invalid access mode for security'
|
||||
if uid == 1:
|
||||
# Users root have all access (Todo: exclude xml-rpc requests)
|
||||
if uid==1:
|
||||
return True
|
||||
|
||||
|
||||
assert mode in ['read','write','create','unlink'], 'Invalid access mode'
|
||||
|
||||
# We check if a specific rule exists
|
||||
cr.execute('SELECT MAX(CASE WHEN perm_'+mode+' THEN 1 else 0 END) '
|
||||
'FROM ir_model_access a '
|
||||
'JOIN ir_model m '
|
||||
'ON (a.model_id=m.id) '
|
||||
'JOIN res_groups_users_rel gu '
|
||||
'ON (gu.gid = a.group_id) '
|
||||
'WHERE m.model = %s AND gu.uid = %s', (model_name, uid,))
|
||||
'from ir_model_access a join ir_model m on (m.id=a.model_id) '
|
||||
'join res_groups_users_rel gu on (gu.gid = a.group_id) '
|
||||
'where m.model=%s and gu.uid=%s', (model_name, uid,))
|
||||
r = cr.fetchall()
|
||||
if r[0][0] == None:
|
||||
cr.execute('SELECT MAX(CASE WHEN perm_'+mode+' THEN 1 else 0 END) '
|
||||
'FROM ir_model_access a '
|
||||
'JOIN ir_model m '
|
||||
'ON (a.model_id = m.id) '
|
||||
'WHERE a.group_id IS NULL AND m.model = %s', (model_name,))
|
||||
r= cr.fetchall()
|
||||
if r[0][0] == None:
|
||||
return True # Changed waiting final rules
|
||||
#return False # by default, the user had no access
|
||||
|
||||
|
||||
if not r[0][0]:
|
||||
if raise_exception:
|
||||
msgs = {
|
||||
|
@ -218,14 +314,13 @@ class ir_model_access(osv.osv):
|
|||
'create': _('You can not create this kind of document! (%s)'),
|
||||
'unlink': _('You can not delete this document! (%s)'),
|
||||
}
|
||||
# due to the assert at the begin of the function, we will never have a KeyError
|
||||
raise except_orm(_('AccessError'), msgs[mode] % model_name )
|
||||
return r[0][0]
|
||||
|
||||
check = tools.cache()(check)
|
||||
|
||||
#
|
||||
# Methods to clean the cache on the Check Method.
|
||||
# Check rights on actions
|
||||
#
|
||||
def write(self, cr, uid, *args, **argv):
|
||||
res = super(ir_model_access, self).write(cr, uid, *args, **argv)
|
||||
|
@ -239,6 +334,10 @@ class ir_model_access(osv.osv):
|
|||
res = super(ir_model_access, self).unlink(cr, uid, *args, **argv)
|
||||
self.check()
|
||||
return res
|
||||
def read(self, cr, uid, *args, **argv):
|
||||
res = super(ir_model_access, self).read(cr, uid, *args, **argv)
|
||||
self.check()
|
||||
return res
|
||||
ir_model_access()
|
||||
|
||||
class ir_model_data(osv.osv):
|
||||
|
@ -266,7 +365,7 @@ class ir_model_data(osv.osv):
|
|||
|
||||
def _get_id(self,cr, uid, module, xml_id):
|
||||
ids = self.search(cr, uid, [('module','=',module),('name','=', xml_id)])
|
||||
assert len(ids)==1, '%d reference(s) to %s. You should have only one !' % (len(ids),xml_id)
|
||||
assert len(ids)==1, '%d reference(s) to %s. You should have one and only one !' % (len(ids),xml_id)
|
||||
return ids[0]
|
||||
_get_id = tools.cache()(_get_id)
|
||||
|
||||
|
@ -430,6 +529,38 @@ class ir_model_data(osv.osv):
|
|||
return True
|
||||
ir_model_data()
|
||||
|
||||
class ir_model_config(osv.osv):
|
||||
_name = 'ir.model.config'
|
||||
_columns = {
|
||||
'password': fields.char('Password', size=64),
|
||||
'password_check': fields.char('confirmation', size=64),
|
||||
}
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context={}):
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'form',
|
||||
'res_model': 'ir.module.module.configuration.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target':'new',
|
||||
}
|
||||
|
||||
def action_update_pw(self, cr, uid, ids, context={}):
|
||||
res = self.read(cr,uid,ids)[0]
|
||||
root = self.pool.get('res.users').browse(cr, uid, [1])[0]
|
||||
self.unlink(cr, uid, [res['id']])
|
||||
if res['password']!=res['password_check']:
|
||||
raise except_orm(_('Error'), _("Password mismatch !"))
|
||||
elif not res['password']:
|
||||
raise except_orm(_('Error'), _("Password empty !"))
|
||||
self.pool.get('res.users').write(cr, uid, [root.id], {'password':res['password']})
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'form',
|
||||
'res_model': 'ir.module.module.configuration.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target':'new',
|
||||
}
|
||||
ir_model_config()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@ class ir_sequence(osv.osv):
|
|||
return (s or '') % {'year':time.strftime('%Y'), 'month': time.strftime('%m'), 'day':time.strftime('%d')}
|
||||
|
||||
def get_id(self, cr, uid, sequence_id, test='id=%d'):
|
||||
cr.execute('lock table ir_sequence')
|
||||
cr.execute('select id,number_next,number_increment,prefix,suffix,padding from ir_sequence where '+test+' and active=True', (sequence_id,))
|
||||
cr.execute('select id,number_next,number_increment,prefix,suffix,padding from ir_sequence where '+test+' and active=True FOR UPDATE', (sequence_id,))
|
||||
res = cr.dictfetchone()
|
||||
if res:
|
||||
cr.execute('update ir_sequence set number_next=number_next+number_increment where id=%d and active=True', (res['id'],))
|
||||
|
|
|
@ -54,34 +54,45 @@ class workflow(osv.osv):
|
|||
return super(workflow, self).write(cr, user, ids, vals, context=context)
|
||||
|
||||
#
|
||||
# scale = [stepx, stepy, posx, posy ]
|
||||
# scale = (vertical-distance, horizontal-distance, min-node-width(optional), min-node-height(optional), margin(default=20))
|
||||
#
|
||||
|
||||
|
||||
def graph_get(self, cr, uid, id, scale, context={}):
|
||||
|
||||
nodes= []
|
||||
nodes_name = []
|
||||
transitions = []
|
||||
start = []
|
||||
tres = {}
|
||||
no_ancester = []
|
||||
workflow = self.browse(cr, uid, id, context)
|
||||
for a in workflow.activities:
|
||||
nodes.append((a.id,a.name))
|
||||
nodes_name.append((a.id,a.name))
|
||||
nodes.append(a.id)
|
||||
if a.flow_start:
|
||||
start.append((a.id,a.name))
|
||||
start.append(a.id)
|
||||
else:
|
||||
if not a.in_transitions:
|
||||
no_ancester.append(a.id)
|
||||
|
||||
for t in a.out_transitions:
|
||||
transitions.append( ((a.id,a.name), (t.act_to.id,t.act_to.name)) )
|
||||
tres[t.id] = (a.id,t.act_to.id)
|
||||
g = graph(nodes, transitions)
|
||||
transitions.append((a.id, t.act_to.id))
|
||||
tres[t.id] = (a.id, t.act_to.id)
|
||||
|
||||
|
||||
g = graph(nodes, transitions, no_ancester)
|
||||
g.process(start)
|
||||
g.scale(*scale)
|
||||
result = g.result_get()
|
||||
results = {}
|
||||
|
||||
|
||||
for r in result.items():
|
||||
r[1]['name'] = r[0][1]
|
||||
results[str(r[0][0])] = r[1]
|
||||
return {'node': results, 'transition': tres}
|
||||
|
||||
for node in nodes_name:
|
||||
results[str(node[0])] = result[node[0]]
|
||||
results[str(node[0])]['name'] = node[1]
|
||||
|
||||
return {'nodes': results, 'transitions': tres}
|
||||
|
||||
|
||||
def create(self, cr, user, vals, context=None):
|
||||
if not context:
|
||||
|
|
|
@ -40,6 +40,8 @@ import zipimport
|
|||
|
||||
import wizard
|
||||
import addons
|
||||
import pooler
|
||||
import netsvc
|
||||
|
||||
ver_regexp = re.compile("^(\\d+)((\\.\\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\\d*)*)(-r(\\d+))?$")
|
||||
suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$")
|
||||
|
@ -270,20 +272,22 @@ class module(osv.osv):
|
|||
def state_update(self, cr, uid, ids, newstate, states_to_update, context={}, level=50):
|
||||
if level<1:
|
||||
raise orm.except_orm(_('Error'), _('Recursion error in modules dependencies !'))
|
||||
demo = True
|
||||
demo = False
|
||||
for module in self.browse(cr, uid, ids):
|
||||
mdemo = True
|
||||
mdemo = False
|
||||
go_deeper = False
|
||||
for dep in module.dependencies_id:
|
||||
if dep.state == 'unknown':
|
||||
raise orm.except_orm(_('Error'), _('Unmet dependency: %s') % (dep.name,))
|
||||
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,))
|
||||
if dep.state != newstate:
|
||||
go_deeper = True
|
||||
ids2 = self.search(cr, uid, [('name','=',dep.name)])
|
||||
mdemo = self.state_update(cr, uid, ids2, newstate, states_to_update, context, level-1,) and mdemo
|
||||
if not module.dependencies_id:
|
||||
mdemo = self.state_update(cr, uid, ids2, newstate, states_to_update, context, level-1,) or mdemo
|
||||
if not go_deeper:
|
||||
mdemo = module.demo
|
||||
if module.state in states_to_update:
|
||||
self.write(cr, uid, [module.id], {'state': newstate, 'demo':mdemo})
|
||||
demo = demo and mdemo
|
||||
demo = demo or mdemo
|
||||
return demo
|
||||
|
||||
def button_install(self, cr, uid, ids, context={}):
|
||||
|
@ -317,19 +321,8 @@ class module(osv.osv):
|
|||
def button_upgrade_cancel(self, cr, uid, ids, context={}):
|
||||
self.write(cr, uid, ids, {'state': 'installed'})
|
||||
return True
|
||||
def button_update_translations(self, cr, uid, ids, context={}):
|
||||
cr.execute('select code from res_lang where translatable=TRUE')
|
||||
langs = [l[0] for l in cr.fetchall()]
|
||||
modules = self.read(cr, uid, ids, ['name'])
|
||||
for module in modules:
|
||||
files = self.get_module_info(module['name']).get('translations', {})
|
||||
for lang in langs:
|
||||
if files.has_key(lang):
|
||||
filepath = files[lang]
|
||||
# if filepath does not contain :// we prepend the path of the module
|
||||
if filepath.find('://') == -1:
|
||||
filepath = addons.get_module_resource(module['name'], filepath)
|
||||
tools.trans_load(filepath, lang)
|
||||
def button_update_translations(self, cr, uid, ids, context=None):
|
||||
self.update_translations(cr, uid, ids)
|
||||
return True
|
||||
|
||||
# update the list of available packages
|
||||
|
@ -525,6 +518,28 @@ class module(osv.osv):
|
|||
dep_ids = map(lambda x:x[0],cr.fetchall())
|
||||
if len(dep_ids):
|
||||
self.action_install(cr,uid,dep_ids,context=context)
|
||||
|
||||
def update_translations(self, cr, uid, ids, filter_lang=None):
|
||||
logger = netsvc.Logger()
|
||||
|
||||
if not filter_lang:
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
lang_obj=pool.get('res.lang')
|
||||
lang_ids=lang_obj.search(cr, uid, [('translatable', '=', True)])
|
||||
filter_lang= [lang.code for lang in lang_obj.browse(cr, uid, lang_ids)]
|
||||
elif not isinstance(filter_lang, (list, tuple)):
|
||||
filter_lang = [filter_lang]
|
||||
|
||||
for mod in self.browse(cr, uid, ids):
|
||||
if mod.state != 'installed':
|
||||
continue
|
||||
|
||||
for lang in filter_lang:
|
||||
f = os.path.join(tools.config['addons_path'], mod.name, 'i18n', lang + '.po')
|
||||
if os.path.exists(f):
|
||||
logger.notifyChannel("init", netsvc.LOG_INFO, 'addons %s: loading translation file for language %s' % (mod.name, lang))
|
||||
tools.trans_load(cr.dbname, f, lang, verbose=False)
|
||||
|
||||
module()
|
||||
|
||||
class module_dependency(osv.osv):
|
||||
|
@ -566,7 +581,7 @@ class module_config_wizard_step(osv.osv):
|
|||
'note':fields.text('Text'),
|
||||
'action_id':fields.many2one('ir.actions.act_window', 'Action', select=True,required=True, ondelete='cascade'),
|
||||
'sequence':fields.integer('Sequence'),
|
||||
'state':fields.selection([('open', 'Open'),('done', 'Done'),('skip','Skip')], string='State', required=True)
|
||||
'state':fields.selection([('open', 'Not Started'),('done', 'Done'),('skip','Skipped')], string='State', required=True)
|
||||
}
|
||||
_defaults={
|
||||
'state': lambda *a: 'open',
|
||||
|
@ -641,6 +656,7 @@ class module_configuration(osv.osv_memory):
|
|||
'state': 'done',
|
||||
}, context=context)
|
||||
return{
|
||||
'view_mode': item.action_id.view_mode,
|
||||
'view_type': item.action_id.view_type,
|
||||
'view_id':item.action_id.view_id and [item.action_id.view_id.id] or False,
|
||||
'res_model': item.action_id.res_model,
|
||||
|
@ -650,8 +666,3 @@ class module_configuration(osv.osv_memory):
|
|||
return {'type':'ir.actions.act_window_close' }
|
||||
module_configuration()
|
||||
|
||||
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -5,99 +5,104 @@
|
|||
<field name="name">Import module</field>
|
||||
<field name="wiz_name">base.module.import</field>
|
||||
</record>
|
||||
<menuitem action="wizard_base_module_import" id="menu_wizard_module_import" parent="base.menu_management" type="wizard"/>
|
||||
<menuitem action="wizard_base_module_import" id="menu_wizard_module_import" parent="menu_management" type="wizard"/>
|
||||
|
||||
<record id="wizard_update" model="ir.actions.wizard">
|
||||
<field name="name">Download module list</field>
|
||||
<field name="name">Update Modules List</field>
|
||||
<field name="wiz_name">module.module.update</field>
|
||||
</record>
|
||||
<menuitem action="wizard_update" groups="group_admin" icon="STOCK_CONVERT" id="menu_module_update" parent="base.menu_management" type="wizard"/>
|
||||
<menuitem action="wizard_update" icon="STOCK_CONVERT" id="menu_module_update" parent="menu_management" type="wizard"/>
|
||||
|
||||
<wizard id="wizard_upgrade" model="ir.module.module" name="module.upgrade" string="Apply Scheduled Upgrades"/>
|
||||
<menuitem action="wizard_upgrade" id="menu_wizard_upgrade" parent="base.menu_management" type="wizard"/>
|
||||
<menuitem action="wizard_upgrade" id="menu_wizard_upgrade" parent="menu_management" type="wizard"/>
|
||||
|
||||
<record id="wizard_lang_install" model="ir.actions.wizard">
|
||||
<field name="name">Install new language file</field>
|
||||
<field name="name">Reload an Official Translation</field>
|
||||
<field name="wiz_name">module.lang.install</field>
|
||||
</record>
|
||||
<menuitem action="wizard_lang_install" id="menu_wizard_lang_install" parent="base.menu_translation" type="wizard"/>
|
||||
<menuitem action="wizard_lang_install" id="menu_wizard_lang_install" parent="menu_translation" type="wizard"/>
|
||||
|
||||
<record id="wizard_lang_export" model="ir.ui.view">
|
||||
<field name="name">Export Language</field>
|
||||
<record id="wizard_lang_export" model="ir.ui.view">
|
||||
<field name="name">Export a Translation File</field>
|
||||
<field name="model">wizard.module.lang.export</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form col="3" string="Export language">
|
||||
<image name="gtk-dialog-info"/>
|
||||
<group col="2" states="choose" fill="0" height="500">
|
||||
<separator string="Export translation file" colspan="2"/>
|
||||
<field name="lang" width="300"/>
|
||||
<field name="format"/>
|
||||
<field name="modules" width="500" height="200"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<newline/><label/>
|
||||
</group>
|
||||
<group col="1" states="get" fill="0">
|
||||
<separator string="Export done"/>
|
||||
<field name="data" readonly="1" nolabel="1"/>
|
||||
<field name="advice" nolabel="1" height="80"/>
|
||||
</group>
|
||||
<group col="2" colspan="3" fill="0">
|
||||
<button states="choose" icon="gtk-cancel" name="act_cancel" special="cancel" string="Cancel" type="object"/>
|
||||
<button states="choose" icon="gtk-ok" name="act_getfile" string="Get file" type="object"/>
|
||||
<button states="get" icon="gtk-close" name="act_destroy" special="cancel" string="Close" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
<field name="arch" type="xml">
|
||||
<form col="3" string="Export language">
|
||||
<notebook>
|
||||
<page string="Export Data">
|
||||
<group col="2" states="choose" fill="0" height="500">
|
||||
<separator string="Export translation file" colspan="2"/>
|
||||
<field name="lang" width="300" required="1"/>
|
||||
<field name="format" required="1"/>
|
||||
<field name="modules" width="500" height="200"/>
|
||||
|
||||
<field name="state" invisible="1"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Help">
|
||||
<label align="0.0" colspan="4" string="The official translations pack of all OpenERP/OpenObjects module are managed through launchpad. We use their online interface to synchronize all translations efforts."/>
|
||||
<label align="0.0" colspan="4" string="To improve some terms of the official translations of OpenERP, you should modify the terms directly on the launchpad interface. If you made lots of translations for your own module, you can also publish all your translation at once."/>
|
||||
<label align="0.0" colspan="4" string="To browse official translations, you can visit this link: "/>
|
||||
<label align="0.0" colspan="4" string="https://translations.launchpad.net/openobject"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="1" states="get" fill="0">
|
||||
<separator string="Export done"/>
|
||||
<field name="data" readonly="1" nolabel="1"/>
|
||||
<field name="advice" nolabel="1" height="80"/>
|
||||
</group>
|
||||
<group col="2" colspan="3" fill="0">
|
||||
<button states="choose" icon="gtk-cancel" name="act_cancel" special="cancel" string="Cancel" type="object"/>
|
||||
<button states="choose" icon="gtk-ok" name="act_getfile" string="Get file" type="object"/>
|
||||
<button states="get" icon="gtk-close" name="act_destroy" special="cancel" string="Close" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_wizard_lang_export" model="ir.actions.act_window">
|
||||
<field name="name">Export language</field>
|
||||
<record id="action_wizard_lang_export" model="ir.actions.act_window">
|
||||
<field name="name">Export a Translation File</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">wizard.module.lang.export</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<menuitem action="action_wizard_lang_export" id="menu_wizard_lang_export" parent="base.menu_translation"/>
|
||||
<menuitem action="action_wizard_lang_export" id="menu_wizard_lang_export" parent="menu_translation_export"/>
|
||||
|
||||
<record id="wizard_lang_import" model="ir.actions.wizard">
|
||||
<field name="name">Import language</field>
|
||||
<field name="name">Import a Translation File</field>
|
||||
<field name="wiz_name">module.lang.import</field>
|
||||
</record>
|
||||
<menuitem action="wizard_lang_import" id="menu_wizard_lang_import" parent="base.menu_translation" type="wizard"/>
|
||||
|
||||
<record id="wizard_lang_import" model="ir.actions.wizard">
|
||||
<field name="name">Import language</field>
|
||||
<field name="wiz_name">module.lang.import</field>
|
||||
</record>
|
||||
<menuitem action="wizard_lang_import" id="menu_wizard_lang_import" parent="base.menu_translation" type="wizard"/>
|
||||
|
||||
<record id="wizard_update_translations" model="ir.ui.view">
|
||||
<menuitem action="wizard_lang_import" id="menu_wizard_lang_import" parent="menu_translation_export" type="wizard"/>
|
||||
|
||||
<record id="wizard_update_translations" model="ir.ui.view">
|
||||
<field name="name">Update Translations</field>
|
||||
<field name="model">wizard.module.update_translations</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form col="3" string="Update Translations">
|
||||
<image name="gtk-dialog-info"/>
|
||||
<group col="2" fill="0" height="500">
|
||||
<field name="lang" width="300"/>
|
||||
</group>
|
||||
<group col="2" colspan="3" fill="0">
|
||||
<button icon="gtk-cancel" name="act_cancel" special="cancel" string="Cancel" type="object"/>
|
||||
<button icon="gtk-ok" name="act_update" string="Update" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
<field name="arch" type="xml">
|
||||
<form col="3" string="Update Translations">
|
||||
<image name="gtk-dialog-info"/>
|
||||
<group col="2" fill="0" height="500">
|
||||
<field name="lang" width="300"/>
|
||||
</group>
|
||||
<label align="0.0" colspan="4" string="This wizard will detect new terms in the application so that you can update them manually."/>
|
||||
<separator colspan="4"/>
|
||||
<group col="2" colspan="4" fill="0">
|
||||
<button icon="gtk-cancel" name="act_cancel" special="cancel" string="Cancel" type="object"/>
|
||||
<button icon="gtk-ok" name="act_update" string="Update" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_wizard_update_translations" model="ir.actions.act_window">
|
||||
<field name="name">Update Translations</field>
|
||||
<record id="action_wizard_update_translations" model="ir.actions.act_window">
|
||||
<field name="name">Resynchronise Terms</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">wizard.module.update_translations</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<menuitem action="action_wizard_update_translations" id="menu_wizard_update_translations" parent="base.menu_translation"/>
|
||||
<menuitem action="action_wizard_update_translations" id="menu_wizard_update_translations" parent="menu_translation_app"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
|
|
@ -44,7 +44,7 @@ class wizard_export_lang(osv.osv_memory):
|
|||
lang_obj=pooler.get_pool(cr.dbname).get('res.lang')
|
||||
ids=lang_obj.search(cr, uid, ['&', ('active', '=', True), ('translatable', '=', True),])
|
||||
langs=lang_obj.browse(cr, uid, ids)
|
||||
return [('', _('New language'))] + [(lang.code, lang.name) for lang in langs]
|
||||
return [(lang.code, lang.name) for lang in langs]
|
||||
|
||||
|
||||
def act_cancel(self, cr, uid, ids, context=None):
|
||||
|
@ -56,28 +56,31 @@ class wizard_export_lang(osv.osv_memory):
|
|||
|
||||
def act_getfile(self, cr, uid, ids, context=None):
|
||||
this = self.browse(cr, uid, ids)[0]
|
||||
mods = map(lambda m: m.name, this.modules)
|
||||
mods = map(lambda m: m.name, this.modules) or ['all']
|
||||
mods.sort()
|
||||
buf=StringIO.StringIO()
|
||||
|
||||
tools.trans_export(this.lang, mods, buf, this.format, dbname=cr.dbname)
|
||||
|
||||
if this.format == 'csv':
|
||||
this.advice = _("Save this document to a .CSV file and open it with your favourite spreadsheet software. The file encoding is UTF-8. You have to translate the latest column before reimporting it.")
|
||||
elif this.format == 'po':
|
||||
ext = this.lang and '.po' or '.pot'
|
||||
this.advice = _("Save this document to a %s file and edit it with a specific software or a text editor. The file encoding is UTF-8." % (ext,))
|
||||
if not this.lang:
|
||||
this.format = 'pot'
|
||||
this.advice = _("Save this document to a %s file and edit it with a specific software or a text editor. The file encoding is UTF-8.") % ('.'+this.format,)
|
||||
elif this.format == 'tgz':
|
||||
ext = this.lang and '.po' or '.pot'
|
||||
this.advice = _('Save this document to a .tgz file. This archive containt UTF-8 %s files and may be uploaded to launchpad.' % (ext,))
|
||||
|
||||
this.advice = _('Save this document to a .tgz file. This archive containt UTF-8 %s files and may be uploaded to launchpad.') % (ext,)
|
||||
|
||||
this.name = "%s.%s" % (this.lang or _('new'), this.format)
|
||||
|
||||
out=base64.encodestring(buf.getvalue())
|
||||
buf.close()
|
||||
return self.write(cr, uid, ids, {'state':'get', 'data':out, 'advice':this.advice}, context=context)
|
||||
return self.write(cr, uid, ids, {'state':'get', 'data':out, 'advice':this.advice, 'name':this.name}, context=context)
|
||||
|
||||
_name = "wizard.module.lang.export"
|
||||
_columns = {
|
||||
'lang': fields.selection(_get_languages, 'Language'), # not required: unset = new language
|
||||
'name': fields.char('Filename', 16, readonly=True),
|
||||
'lang': fields.selection(_get_languages, 'Language', help='To export a new language, do not select a language.'), # not required: unset = new language
|
||||
'format': fields.selection( ( ('csv','CSV File'), ('po','PO File'), ('tgz', 'TGZ Archive')), 'File Format', required=True),
|
||||
'modules': fields.many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', 'Modules', domain=[('state','=','installed')]),
|
||||
'data': fields.binary('File', readonly=True),
|
||||
|
@ -86,7 +89,8 @@ class wizard_export_lang(osv.osv_memory):
|
|||
('get','get'), # get the file
|
||||
) ),
|
||||
}
|
||||
_defaults = { 'state': lambda *a: 'choose', }
|
||||
_defaults = { 'state': lambda *a: 'choose',
|
||||
}
|
||||
wizard_export_lang()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
import wizard
|
||||
import tools
|
||||
import pooler
|
||||
|
||||
view_form_end = """<?xml version="1.0"?>
|
||||
<form string="Language file loaded.">
|
||||
|
@ -55,9 +56,11 @@ view_form = """<?xml version="1.0"?>
|
|||
class wizard_lang_install(wizard.interface):
|
||||
def _lang_install(self, cr, uid, data, context):
|
||||
lang = data['form']['lang']
|
||||
if lang and lang != 'en_US':
|
||||
filename = tools.config["root_path"] + "/i18n/" + lang + ".csv"
|
||||
tools.trans_load(cr.dbname, filename, lang)
|
||||
if lang:
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
modobj = cr.pool.get('ir.module.module')
|
||||
mids = modobj.search(cr, uid, [('state', '=', 'installed')])
|
||||
modobj.update_translations(cr, uid, mids, lang)
|
||||
return {}
|
||||
|
||||
def _get_language(sel, cr, uid, context):
|
||||
|
|
|
@ -101,14 +101,12 @@ class wizard_info_get(wizard.interface):
|
|||
mod_obj.download(cr, uid, ids, context=context)
|
||||
cr.commit()
|
||||
db, pool = pooler.restart_pool(cr.dbname, update_module=True)
|
||||
|
||||
lang_obj=pool.get('res.lang')
|
||||
lang_ids=lang_obj.search(cr, uid, [])
|
||||
langs=lang_obj.browse(cr, uid, lang_ids)
|
||||
for lang in langs:
|
||||
if lang.code and lang.code != 'en_US':
|
||||
filename=os.path.join(tools.config["root_path"], "i18n", lang.code + ".csv")
|
||||
tools.trans_load(cr.dbname, filename, lang.code)
|
||||
|
||||
# Update translations for all installed languages
|
||||
cr = db.cursor()
|
||||
modobj = pool.get('ir.module.module')
|
||||
mids = modobj.search(cr, uid, [('state', '=', 'installed')])
|
||||
modobj.update_translations(cr, uid, mids, None)
|
||||
return {}
|
||||
|
||||
def _config(self, cr, uid, data, context=None):
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</record>
|
||||
|
||||
<menuitem id="menu_localisation" name="Localisation" parent="menu_base_config"/>
|
||||
<menuitem action="action_country" groups="group_admin" id="menu_country_partner" parent="menu_localisation"/>
|
||||
<menuitem action="action_country" id="menu_country_partner" parent="menu_localisation"/>
|
||||
|
||||
<!--
|
||||
State
|
||||
|
@ -78,7 +78,7 @@
|
|||
<field name="view_id" ref="view_country_state_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_country_state" groups="group_admin" id="menu_country_state_partner" parent="menu_localisation"/>
|
||||
<menuitem action="action_country_state" id="menu_country_state_partner" parent="menu_localisation"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -19,7 +19,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem id="next_id_14" name="Partner Events" parent="base.menu_base_config"/><menuitem action="res_partner_canal-act" groups="group_admin" id="menu_res_partner_canal-act" parent="next_id_14"/>
|
||||
<menuitem id="next_id_14" name="Partner Events" parent="base.menu_base_config"/><menuitem action="res_partner_canal-act" id="menu_res_partner_canal-act" parent="next_id_14"/>
|
||||
|
||||
<record id="res_partner_event_type-view" model="ir.ui.view">
|
||||
<field name="name">res.partner.event.type.form</field>
|
||||
|
@ -53,7 +53,7 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'active_test': False}</field>
|
||||
</record>
|
||||
<menuitem action="res_partner_event_type-act" groups="group_admin" id="menu_res_partner_event_type-act" parent="base.next_id_14"/>
|
||||
<menuitem action="res_partner_event_type-act" id="menu_res_partner_event_type-act" parent="base.next_id_14"/>
|
||||
|
||||
<record id="res_partner_som_tree-view" model="ir.ui.view">
|
||||
<field name="name">res.partner.som.tree</field>
|
||||
|
@ -84,7 +84,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem action="res_partner_som-act" groups="group_admin" id="menu_res_partner_som-act" parent="base.next_id_14"/>
|
||||
<menuitem action="res_partner_som-act" id="menu_res_partner_som-act" parent="base.next_id_14"/>
|
||||
|
||||
<record id="res_partner_event-wopartner-view_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.event.form</field>
|
||||
|
|
|
@ -83,7 +83,7 @@ class res_partner_category(osv.osv):
|
|||
_description='Partner Categories'
|
||||
_name = 'res.partner.category'
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', required=True, size=64),
|
||||
'name': fields.char('Category Name', required=True, size=64, translate=True),
|
||||
'parent_id': fields.many2one('res.partner.category', 'Parent Category', select=True),
|
||||
'complete_name': fields.function(_name_get_fnc, method=True, type="char", string='Name'),
|
||||
'child_ids': fields.one2many('res.partner.category', 'parent_id', 'Childs Category'),
|
||||
|
@ -142,7 +142,6 @@ class res_partner(osv.osv):
|
|||
'user_id': fields.many2one('res.users', 'Dedicated Salesman', help='The internal user that is in charge of communicating with this partner if any.'),
|
||||
'responsible': fields.many2one('res.users', 'Users'),
|
||||
'vat': fields.char('VAT',size=32 ,help="Value Added Tax number"),
|
||||
'vat_subject': fields.boolean('Subjected to the VAT'),
|
||||
'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
|
||||
'website': fields.char('Website',size=64),
|
||||
'comment': fields.text('Notes'),
|
||||
|
@ -277,7 +276,7 @@ class res_partner_address(osv.osv):
|
|||
_name = 'res.partner.address'
|
||||
_order = 'id'
|
||||
_columns = {
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade', select=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='cascade', select=True),
|
||||
'type': fields.selection( [ ('default','Default'),('invoice','Invoice'), ('delivery','Delivery'), ('contact','Contact'), ('other','Other') ],'Address Type'),
|
||||
'function': fields.many2one('res.partner.function', 'Function'),
|
||||
'title': fields.selection(_contact_title_get, 'Title', size=32),
|
||||
|
|
|
@ -195,7 +195,7 @@
|
|||
<record id="res_partner_11" model="res.partner">
|
||||
<field name="name">Leclerc</field>
|
||||
<field eval="1200.00" name="credit_limit"/>
|
||||
<field name="user_id" ref="user_admin"/>
|
||||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_0')])]" name="category_id"/>
|
||||
</record>
|
||||
<record id="res_partner_14" model="res.partner">
|
||||
|
@ -210,7 +210,7 @@
|
|||
<field name="ean13">3020178570171</field>
|
||||
<field name="parent_id" ref="res_partner_14"/>
|
||||
<field eval="1500.00" name="credit_limit"/>
|
||||
<field name="user_id" ref="user_admin"/>
|
||||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_11')])]" name="category_id"/>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<data>
|
||||
<menuitem icon="terp-partner" id="menu_base_partner" name="Partners" sequence="0"/>
|
||||
|
||||
<menuitem groups="group_admin" id="menu_base_config" name="Configuration" parent="menu_base_partner" sequence="1"/>
|
||||
<menuitem id="menu_base_config" name="Configuration" parent="menu_base_partner" sequence="1"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
|
@ -38,7 +38,7 @@
|
|||
<field name="res_model">res.partner.function</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem action="action_partner_function_form" groups="group_admin" id="menu_partner_function_form" parent="base.menu_base_config"/>
|
||||
<menuitem action="action_partner_function_form" id="menu_partner_function_form" parent="base.menu_base_config"/>
|
||||
|
||||
<!--
|
||||
=====================
|
||||
|
@ -173,7 +173,7 @@
|
|||
<field name="res_model">res.partner.title</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem action="action_partner_title" groups="group_admin" id="menu_partner_title" parent="base.menu_base_config"/>
|
||||
<menuitem action="action_partner_title" id="menu_partner_title" parent="base.menu_base_config"/>
|
||||
|
||||
<!--
|
||||
=======================
|
||||
|
@ -310,6 +310,14 @@
|
|||
<field name="domain">[('supplier','<>',1),('customer','<>',1)]</field>
|
||||
</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">
|
||||
<field name="name">New Partner</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
</record>
|
||||
<menuitem action="action_partner_customer_form_new" id="menu_partner_customer_form_new" parent="menu_partner_form"/>
|
||||
|
||||
<record id="view_payterm_form" model="ir.ui.view">
|
||||
<field name="name">res.payterm</field>
|
||||
|
|
|
@ -21,6 +21,6 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="context">{'active_test': False}</field>
|
||||
</record>
|
||||
<menuitem action="res_lang_act_window" id="menu_res_lang_act_window" parent="base.menu_translation"/>
|
||||
<menuitem action="res_lang_act_window" id="menu_res_lang_act_window" parent="base.menu_translation_app"/>
|
||||
</data>
|
||||
</terp>
|
||||
</terp>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<terp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="res.groups" id="group_partner_manager">
|
||||
<field name="name">Partner Manager</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -2,6 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Copyright (c) 2008 Camptocamp SA
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
@ -29,11 +30,13 @@
|
|||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
from osv.orm import except_orm
|
||||
import tools
|
||||
import pytz
|
||||
|
||||
class groups(osv.osv):
|
||||
_name = "res.groups"
|
||||
_order = 'name'
|
||||
_columns = {
|
||||
'name': fields.char('Group Name', size=64, required=True),
|
||||
'model_access': fields.one2many('ir.model.access', 'group_id', 'Access Controls'),
|
||||
|
@ -71,7 +74,8 @@ class roles(osv.osv):
|
|||
_columns = {
|
||||
'name': fields.char('Role Name', size=64, required=True),
|
||||
'parent_id': fields.many2one('res.roles', 'Parent', select=True),
|
||||
'child_id': fields.one2many('res.roles', 'parent_id', 'Childs')
|
||||
'child_id': fields.one2many('res.roles', 'parent_id', 'Childs'),
|
||||
'users': fields.many2many('res.users', 'res_roles_users_rel', 'rid', 'uid', 'Users'),
|
||||
}
|
||||
_defaults = {
|
||||
}
|
||||
|
@ -108,6 +112,7 @@ class users(osv.osv):
|
|||
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action'),
|
||||
'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'),
|
||||
'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'),
|
||||
'context_lang': fields.selection(_lang_get, 'Language', required=True),
|
||||
'context_tz': fields.selection(_tz_get, 'Timezone', size=64)
|
||||
|
@ -164,7 +169,7 @@ class users(osv.osv):
|
|||
|
||||
def unlink(self, cr, uid, ids):
|
||||
if 1 in ids:
|
||||
raise osv.except_osv(_('Can not remove root user!'), _('You can not remove the root user as it is used internally for resources created by Tiny ERP (updates, module installation, ...)'))
|
||||
raise osv.except_osv(_('Can not remove root user!'), _('You can not remove the admin user as it is used internally for resources created by OpenERP (updates, module installation, ...)'))
|
||||
return super(users, self).unlink(cr, uid, ids)
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80):
|
||||
|
@ -198,7 +203,7 @@ class users(osv.osv):
|
|||
return dataobj.browse(cr, uid, data_id, context).res_id
|
||||
|
||||
def action_next(self,cr,uid,ids,context=None):
|
||||
return{
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'form',
|
||||
'res_model': 'ir.module.module.configuration.wizard',
|
||||
|
@ -213,7 +218,7 @@ class users(osv.osv):
|
|||
'res_model': 'ir.module.module.configuration.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target':'new',
|
||||
}
|
||||
}
|
||||
def action_new(self,cr,uid,ids,context={}):
|
||||
return {
|
||||
'view_type': 'form',
|
||||
|
@ -225,7 +230,7 @@ class users(osv.osv):
|
|||
}
|
||||
users()
|
||||
|
||||
class groups2(osv.osv):
|
||||
class groups2(osv.osv): ##FIXME: Is there a reason to inherit this object ?
|
||||
_inherit = 'res.groups'
|
||||
_columns = {
|
||||
'users': fields.many2many('res.users', 'res_groups_users_rel', 'gid', 'uid', 'Users'),
|
||||
|
@ -271,8 +276,3 @@ class res_config_view(osv.osv_memory):
|
|||
}
|
||||
|
||||
res_config_view()
|
||||
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
6535
bin/i18n/cs_CZ.csv
6535
bin/i18n/cs_CZ.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/de_DE.csv
6535
bin/i18n/de_DE.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/es_AR.csv
6535
bin/i18n/es_AR.csv
File diff suppressed because it is too large
Load Diff
6536
bin/i18n/es_ES.csv
6536
bin/i18n/es_ES.csv
File diff suppressed because it is too large
Load Diff
5806
bin/i18n/fr_FR.csv
5806
bin/i18n/fr_FR.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/hu_HU.csv
6535
bin/i18n/hu_HU.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/it_IT.csv
6535
bin/i18n/it_IT.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/nl_NL.csv
6535
bin/i18n/nl_NL.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/pt_BR.csv
6535
bin/i18n/pt_BR.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/pt_PT.csv
6535
bin/i18n/pt_PT.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/ro_RO.csv
6535
bin/i18n/ro_RO.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/ru_RU.csv
6535
bin/i18n/ru_RU.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/sv_SE.csv
6535
bin/i18n/sv_SE.csv
File diff suppressed because it is too large
Load Diff
8466
bin/i18n/zh_CN.csv
8466
bin/i18n/zh_CN.csv
File diff suppressed because it is too large
Load Diff
6535
bin/i18n/zh_TW.csv
6535
bin/i18n/zh_TW.csv
File diff suppressed because it is too large
Load Diff
|
@ -103,6 +103,7 @@
|
|||
<rng:optional><rng:attribute name="xsl"/></rng:optional>
|
||||
<rng:optional> <rng:attribute name="auto" /> </rng:optional>
|
||||
<rng:optional> <rng:attribute name="header" /> </rng:optional>
|
||||
<rng:optional> <rng:attribute name="attachment" /> </rng:optional>
|
||||
<rng:empty />
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
|
|
@ -70,7 +70,7 @@ class expression(object):
|
|||
return []
|
||||
ids2 = table.search(cr, uid, [(parent, 'in', ids)], context=context)
|
||||
return ids+rg(ids2, table, parent)
|
||||
return [(left, 'in', rg(ids2, table, parent))]
|
||||
return [(left, 'in', rg(ids, table, parent))]
|
||||
|
||||
self.__main_table = table
|
||||
|
||||
|
@ -126,7 +126,7 @@ class expression(object):
|
|||
|
||||
elif field._type == 'one2many':
|
||||
if isinstance(right, basestring):
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator)]
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator,limit=None)]
|
||||
else:
|
||||
ids2 = list(right)
|
||||
if not ids2:
|
||||
|
@ -138,7 +138,7 @@ class expression(object):
|
|||
#FIXME
|
||||
if operator == 'child_of':
|
||||
if isinstance(right, basestring):
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like')]
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like',limit=None)]
|
||||
else:
|
||||
ids2 = list(right)
|
||||
|
||||
|
@ -159,7 +159,7 @@ class expression(object):
|
|||
elif field._type == 'many2one':
|
||||
if operator == 'child_of':
|
||||
if isinstance(right, basestring):
|
||||
ids2 = [x[0] for x in field_obj.search_name(cr, uid, right, [], 'like')]
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like',limit=None)]
|
||||
else:
|
||||
ids2 = list(right)
|
||||
|
||||
|
@ -171,7 +171,7 @@ class expression(object):
|
|||
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
|
||||
else:
|
||||
if isinstance(right, basestring):
|
||||
res_ids = field_obj.name_search(cr, uid, right, [], operator)
|
||||
res_ids = field_obj.name_search(cr, uid, right, [], operator,limit=None)
|
||||
right = map(lambda x: x[0], res_ids)
|
||||
self.__exp[i] = (left, 'in', right)
|
||||
else:
|
||||
|
|
|
@ -102,10 +102,10 @@ class _column(object):
|
|||
def set_memory(self, cr, obj, id, name, value, user=None, context=None):
|
||||
raise Exception(_('Not implemented set_memory method !'))
|
||||
|
||||
def get_memory(self, cr, obj, ids, name, context=None, values=None):
|
||||
def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None):
|
||||
raise Exception(_('Not implemented get_memory method !'))
|
||||
|
||||
def get(self, cr, obj, ids, name, context=None, values=None):
|
||||
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
|
||||
raise Exception(_('undefined get method !'))
|
||||
|
||||
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None):
|
||||
|
@ -203,6 +203,28 @@ class binary(_column):
|
|||
_symbol_f = lambda symb: symb and psycopg.Binary(symb) or None
|
||||
_symbol_set = (_symbol_c, _symbol_f)
|
||||
|
||||
_classic_read = False
|
||||
|
||||
def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None):
|
||||
if not context:
|
||||
context = {}
|
||||
if not values:
|
||||
values = []
|
||||
|
||||
res = {}
|
||||
for i in ids:
|
||||
val = None
|
||||
for v in values:
|
||||
if v['id'] == i:
|
||||
val = v[name]
|
||||
break
|
||||
res.setdefault(i, val)
|
||||
if context.get('get_binary_size', True):
|
||||
res[i] = tools.human_size(val)
|
||||
|
||||
return res
|
||||
|
||||
get = get_memory
|
||||
|
||||
class selection(_column):
|
||||
_type = 'selection'
|
||||
|
@ -590,9 +612,14 @@ class function(_column):
|
|||
values = {}
|
||||
res = {}
|
||||
if self._method:
|
||||
return self._fnct(obj, cr, user, ids, name, self._arg, context)
|
||||
res = self._fnct(obj, cr, user, ids, name, self._arg, context)
|
||||
else:
|
||||
return self._fnct(cr, obj._table, ids, name, self._arg, context)
|
||||
res = self._fnct(cr, obj._table, ids, name, self._arg, context)
|
||||
|
||||
if self._type == 'binary' and context.get('get_binary_size', True):
|
||||
# convert the data returned by the function with the size of that data...
|
||||
res = dict(map(lambda (x, y): (x, tools.human_size(len(y))), res.items()))
|
||||
return res
|
||||
|
||||
def set(self, cr, obj, id, name, value, user=None, context=None):
|
||||
if not context:
|
||||
|
|
|
@ -295,15 +295,14 @@ class orm_template(object):
|
|||
_table = None
|
||||
|
||||
def _field_create(self, cr, context={}):
|
||||
cr.execute("SELECT id FROM ir_model WHERE model='%s'" % self._name)
|
||||
cr.execute("SELECT id FROM ir_model_data WHERE name='%s'" % ('model_'+self._name.replace('.','_'),))
|
||||
if not cr.rowcount:
|
||||
# reference model in order to have a description of its fonctionnality in custom_report
|
||||
cr.execute('SELECT nextval(%s)', ('ir_model_id_seq',))
|
||||
id = cr.fetchone()[0]
|
||||
cr.execute("INSERT INTO ir_model (id,model, name, info) VALUES (%s, %s, %s, %s)", (id, self._name, self._description, self.__doc__))
|
||||
if 'module' in context:
|
||||
cr.execute("INSERT INTO ir_model_data (name,date_init,date_update,module,model,res_id) VALUES (%s, now(), now(), %s, %s, %s)", \
|
||||
('model_'+self._table, context['module'], 'ir.model', id)
|
||||
('model_'+self._name.replace('.','_'), context['module'], 'ir.model', id)
|
||||
)
|
||||
cr.commit()
|
||||
|
||||
|
@ -494,6 +493,8 @@ class orm_template(object):
|
|||
(prefix == field[0:len(prefix)]):
|
||||
if fields_def[field[len(prefix)]]['type'] == 'integer':
|
||||
res = line[i] and int(line[i])
|
||||
elif fields_def[field[len(prefix)]]['type'] == 'boolean':
|
||||
res = line[i] and eval(line[i])
|
||||
elif fields_def[field[len(prefix)]]['type'] == 'float':
|
||||
res = line[i] and float(line[i])
|
||||
elif fields_def[field[len(prefix)]]['type'] == 'selection':
|
||||
|
@ -645,7 +646,7 @@ class orm_template(object):
|
|||
translated_msg = trans._get_source(cr, uid, self._name, 'constraint', lng, source=msg) or msg
|
||||
error_msgs.append(
|
||||
_("Error occur when validation the fields %s: %s") % (','.join(fields), translated_msg)
|
||||
)
|
||||
)
|
||||
if error_msgs:
|
||||
cr.rollback()
|
||||
raise except_orm('ValidateError', '\n'.join(error_msgs))
|
||||
|
@ -768,7 +769,7 @@ class orm_template(object):
|
|||
fields[node.getAttribute('name')] = attrs
|
||||
|
||||
elif node.nodeType==node.ELEMENT_NODE and node.localName in ('form', 'tree'):
|
||||
result = self.pool.get(self._name).view_header_get(cr, user, False, node.localName, context)
|
||||
result = self.view_header_get(cr, user, False, node.localName, context)
|
||||
if result:
|
||||
node.setAttribute('string', result.decode('utf-8'))
|
||||
if node.nodeType == node.ELEMENT_NODE and node.hasAttribute('groups'):
|
||||
|
@ -1074,7 +1075,7 @@ class orm_template(object):
|
|||
def name_get(self, cr, user, ids, context=None):
|
||||
raise _('The name_get method is not implemented on this object !')
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80):
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=None):
|
||||
raise _('The name_search method is not implemented on this object !')
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
@ -1112,22 +1113,26 @@ class orm_memory(orm_template):
|
|||
self.unlink(ids)
|
||||
return True
|
||||
|
||||
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
|
||||
if not fields:
|
||||
fields = self._columns.keys()
|
||||
def read(self, cr, user, ids, fields_to_read=None, context=None, load='_classic_read'):
|
||||
if not context:
|
||||
context = {}
|
||||
if not fields_to_read:
|
||||
fields_to_read = self._columns.keys()
|
||||
result = []
|
||||
if self.datas:
|
||||
for id in ids:
|
||||
r = {'id': id}
|
||||
for f in fields:
|
||||
for f in fields_to_read:
|
||||
if id in self.datas:
|
||||
r[f] = self.datas[id].get(f, False)
|
||||
if r[f] and isinstance(self._columns[f], fields.binary) and context.get('get_binary_size', True):
|
||||
r[f] = len(r[f])
|
||||
result.append(r)
|
||||
if id in self.datas:
|
||||
self.datas[id]['internal.date_access'] = time.time()
|
||||
fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields)
|
||||
fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields_to_read)
|
||||
for f in fields_post:
|
||||
res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=False)
|
||||
res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=result)
|
||||
for record in result:
|
||||
record[f] = res2[record['id']]
|
||||
return result
|
||||
|
@ -1383,8 +1388,10 @@ class orm(orm_template):
|
|||
iids = ids_lst[:40]
|
||||
ids_lst = ids_lst[40:]
|
||||
res = f.get(cr, self, iids, k, 1, {})
|
||||
for r in res.items():
|
||||
cr.execute("UPDATE \"%s\" SET \"%s\"='%s' where id=%d"% (self._table, k, r[1], r[0]))
|
||||
for key,val in res.items():
|
||||
if f._multi:
|
||||
val = val[k]
|
||||
cr.execute("UPDATE \"%s\" SET \"%s\"='%s' where id=%d"% (self._table, k, val, key))
|
||||
|
||||
# and add constraints if needed
|
||||
if isinstance(f, fields.many2one):
|
||||
|
@ -1685,24 +1692,31 @@ class orm(orm_template):
|
|||
return result[0]
|
||||
return result
|
||||
|
||||
def _read_flat(self, cr, user, ids, fields, context=None, load='_classic_read'):
|
||||
def _read_flat(self, cr, user, ids, fields_to_read, context=None, load='_classic_read'):
|
||||
if not context:
|
||||
context = {}
|
||||
if not ids:
|
||||
return []
|
||||
|
||||
if fields == None:
|
||||
fields = self._columns.keys()
|
||||
if fields_to_read == None:
|
||||
fields_to_read = self._columns.keys()
|
||||
|
||||
# construct a clause for the rules :
|
||||
d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name)
|
||||
|
||||
# all inherited fields + all non inherited fields for which the attribute whose name is in load is True
|
||||
fields_pre = filter(lambda x: x in self._columns and getattr(self._columns[x], '_classic_write'), fields) + self._inherits.values()
|
||||
fields_pre = filter(lambda x: x in self._columns and getattr(self._columns[x], '_classic_write'), fields_to_read) + self._inherits.values()
|
||||
|
||||
res = []
|
||||
if len(fields_pre):
|
||||
fields_pre2 = map(lambda x: (x in ('create_date', 'write_date')) and ('date_trunc(\'second\', '+x+') as '+x) or '"'+x+'"', fields_pre)
|
||||
def convert_field(f):
|
||||
if f in ('create_date', 'write_date'):
|
||||
return "date_trunc('second', %s) as %s" % (f, f)
|
||||
if isinstance(self._columns[f], fields.binary) and context.get('get_binary_size', True):
|
||||
return "length(%s) as %s" % (f,f)
|
||||
return '"%s"' % (f,)
|
||||
#fields_pre2 = map(lambda x: (x in ('create_date', 'write_date')) and ('date_trunc(\'second\', '+x+') as '+x) or '"'+x+'"', fields_pre)
|
||||
fields_pre2 = map(convert_field, fields_pre)
|
||||
for i in range(0, len(ids), cr.IN_MAX):
|
||||
sub_ids = ids[i:i+cr.IN_MAX]
|
||||
if d1:
|
||||
|
@ -1731,7 +1745,7 @@ class orm(orm_template):
|
|||
|
||||
for table in self._inherits:
|
||||
col = self._inherits[table]
|
||||
cols = intersect(self._inherit_fields.keys(), fields)
|
||||
cols = intersect(self._inherit_fields.keys(), fields_to_read)
|
||||
if not cols:
|
||||
continue
|
||||
res2 = self.pool.get(table).read(cr, user, [x[col] for x in res], cols, context, load)
|
||||
|
@ -1743,11 +1757,11 @@ class orm(orm_template):
|
|||
|
||||
for record in res:
|
||||
record.update(res3[record[col]])
|
||||
if col not in fields:
|
||||
if col not in fields_to_read:
|
||||
del record[col]
|
||||
|
||||
# all fields which need to be post-processed by a simple function (symbol_get)
|
||||
fields_post = filter(lambda x: x in self._columns and self._columns[x]._symbol_get, fields)
|
||||
fields_post = filter(lambda x: x in self._columns and self._columns[x]._symbol_get, fields_to_read)
|
||||
if fields_post:
|
||||
# maybe it would be faster to iterate on the fields then on res, so that we wouldn't need
|
||||
# to get the _symbol_get in each occurence
|
||||
|
@ -1757,7 +1771,7 @@ class orm(orm_template):
|
|||
ids = map(lambda x: x['id'], res)
|
||||
|
||||
# all non inherited fields for which the attribute whose name is in load is False
|
||||
fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields)
|
||||
fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields_to_read)
|
||||
|
||||
# Compute POST fields
|
||||
todo = {}
|
||||
|
@ -1767,9 +1781,9 @@ class orm(orm_template):
|
|||
for key,val in todo.items():
|
||||
if key:
|
||||
res2 = self._columns[val[0]].get(cr, self, ids, val, user, context=context, values=res)
|
||||
for pos in range(len(val)):
|
||||
for pos in val:
|
||||
for record in res:
|
||||
record[val[pos]] = res2[record['id']][pos]
|
||||
record[pos] = res2[record['id']][pos]
|
||||
else:
|
||||
for f in val:
|
||||
res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=res)
|
||||
|
@ -2237,9 +2251,9 @@ class orm(orm_template):
|
|||
else:
|
||||
cr.execute('select max(parent_right) from '+self._table)
|
||||
pleft = cr.fetchone()[0] or 0
|
||||
cr.execute('update '+self._table+' set parent_left=%d,parent_right=%d', (pleft+1,pleft+2))
|
||||
cr.execute('update '+self._table+' set parent_left=parent_left+2 where parent_left>%d', (pleft,))
|
||||
cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%d', (pleft,))
|
||||
cr.execute('update '+self._table+' set parent_left=%d,parent_right=%d where id=%d', (pleft+1,pleft+2,id_new))
|
||||
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_create(user, self._name, id_new, cr)
|
||||
|
@ -2383,7 +2397,7 @@ class orm(orm_template):
|
|||
return [(r['id'], str(r[self._rec_name])) for r in self.read(cr, user, ids,
|
||||
[self._rec_name], context, load='_classic_write')]
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80):
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=None):
|
||||
if not args:
|
||||
args = []
|
||||
if not context:
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
###############################################################################
|
||||
|
||||
name = 'tinyerp-server'
|
||||
name = 'openerp-server'
|
||||
version = '4.3.0'
|
||||
description = 'Tiny\'s ERP Server'
|
||||
description = 'OpenERP Server'
|
||||
long_desc = '''\
|
||||
Tiny ERP is a complete ERP and CRM. The main features are accounting (analytic
|
||||
OpenERP is a complete ERP and CRM. The main features are accounting (analytic
|
||||
and financial), stock management, sales and purchases management, tasks
|
||||
automation, marketing campaigns, help desk, POS, etc. Technical features include
|
||||
a distributed server, flexible workflows, an object database, a dynamic GUI,
|
||||
|
@ -43,7 +43,7 @@ Development Status :: 5 - Production/Stable
|
|||
License :: OSI Approved :: GNU General Public License Version 2 (GPL-2)
|
||||
Programming Language :: Python
|
||||
"""
|
||||
url = 'http://www.tinyerp.com'
|
||||
url = 'http://www.openerp.com'
|
||||
author = 'Tiny.be'
|
||||
author_email = 'info@tiny.be'
|
||||
license = 'GPL-2'
|
||||
|
|
|
@ -550,7 +550,7 @@ class _rml_flowable(object):
|
|||
rowheights = [utils.unit_get(f.strip()) for f in node.getAttribute('rowHeights').split(',')]
|
||||
if len(rowheights) == 1:
|
||||
rowheights = rowheights[0]
|
||||
table = platypus.Table(data = data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'] ,{'repeatRows':'int','repeatCols':'int'})))
|
||||
table = platypus.LongTable(data = data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'] ,{'repeatRows':'int','repeatCols':'int'})))
|
||||
if node.hasAttribute('style'):
|
||||
table.setStyle(self.styles.table_styles[node.getAttribute('style')])
|
||||
for s in styles:
|
||||
|
|
|
@ -550,11 +550,12 @@ class rml_parse(object):
|
|||
return res
|
||||
|
||||
class report_sxw(report_rml):
|
||||
def __init__(self, name, table, rml, parser=rml_parse, header=True):
|
||||
def __init__(self, name, table, rml, parser=rml_parse, header=True, store=False):
|
||||
report_rml.__init__(self, name, table, rml, '')
|
||||
self.name = name
|
||||
self.parser = parser
|
||||
self.header = header
|
||||
self.store = store
|
||||
|
||||
def getObjects(self, cr, uid, ids, context):
|
||||
table_obj = pooler.get_pool(cr.dbname).get(self.table)
|
||||
|
@ -572,10 +573,12 @@ class report_sxw(report_rml):
|
|||
report_type = 'pdf'
|
||||
report_xml = None
|
||||
title=''
|
||||
attach = False
|
||||
if report_xml_ids:
|
||||
title = ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name
|
||||
report_xml = ir_actions_report_xml_obj.browse(cr, uid, report_xml_ids[0],
|
||||
context=context)
|
||||
title = report_xml.name
|
||||
attach = report_xml.attachment
|
||||
rml = report_xml.report_rml_content
|
||||
report_type = report_xml.report_type
|
||||
else:
|
||||
|
@ -654,15 +657,24 @@ class report_sxw(report_rml):
|
|||
rml_parser.preprocess(objs, data, ids)
|
||||
rml_dom = xml.dom.minidom.parseString(rml)
|
||||
rml2 = rml_parser._parse(rml_dom, objs, data, header=self.header)
|
||||
#if os.name != "nt":
|
||||
# f = file("/tmp/debug.rml", "w")
|
||||
# f.write(rml2)
|
||||
# f.close()
|
||||
if rml_parser.logo:
|
||||
logo = base64.decodestring(rml_parser.logo)
|
||||
|
||||
create_doc = self.generators[report_type]
|
||||
pdf = create_doc(rml2, logo,title)
|
||||
|
||||
if attach:
|
||||
# TODO: save multiple print with symbolic links in attach
|
||||
pool.get('ir.attachment').create(cr, uid, {
|
||||
'name': title or _('print'),
|
||||
'datas': pdf,
|
||||
'datas_fname': attach+time.strftime('%Y-%m-%d')+'.'+report_type,
|
||||
'res_model': self.table,
|
||||
'res_id': ids[0]
|
||||
}, context=context
|
||||
)
|
||||
cr.commit()
|
||||
|
||||
return (pdf, report_type)
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class db(netsvc.Service):
|
|||
self.id = 0
|
||||
self.id_protect = threading.Semaphore()
|
||||
|
||||
def create(self, password, db_name, demo, lang):
|
||||
def create(self, password, db_name, demo, lang, user_password='admin'):
|
||||
security.check_super(password)
|
||||
self.id_protect.acquire()
|
||||
self.id += 1
|
||||
|
@ -76,7 +76,7 @@ class db(netsvc.Service):
|
|||
cr.execute('CREATE DATABASE ' + db_name + ' ENCODING \'unicode\'')
|
||||
cr.close()
|
||||
class DBInitialize(object):
|
||||
def __call__(self, serv, id, db_name, demo, lang):
|
||||
def __call__(self, serv, id, db_name, demo, lang, user_password='admin'):
|
||||
try:
|
||||
serv.actions[id]['progress'] = 0
|
||||
clean = False
|
||||
|
@ -85,17 +85,24 @@ class db(netsvc.Service):
|
|||
cr.commit()
|
||||
cr.close()
|
||||
cr = None
|
||||
pool = pooler.get_pool(db_name, demo,serv.actions[id],
|
||||
pool = pooler.get_pool(db_name, demo, serv.actions[id],
|
||||
update_module=True)
|
||||
if lang and lang != 'en_US':
|
||||
filename = tools.config["root_path"] + "/i18n/" + lang + ".csv"
|
||||
tools.trans_load(db_name, filename, lang)
|
||||
serv.actions[id]['clean'] = True
|
||||
|
||||
cr = sql_db.db_connect(db_name).cursor()
|
||||
cr.execute('select login, password, name ' \
|
||||
'from res_users ' \
|
||||
'where login <> \'root\' order by login')
|
||||
|
||||
if lang:
|
||||
modobj = pool.get('ir.module.module')
|
||||
mids = modobj.search(cr, 1, [('state', '=', 'installed')])
|
||||
modobj.update_translations(cr, 1, mids, lang)
|
||||
|
||||
cr.execute('UPDATE res_users SET password=%s, active=True WHERE login=%s', (
|
||||
user_password, 'admin'))
|
||||
cr.execute('SELECT login, password, name ' \
|
||||
' FROM res_users ' \
|
||||
' ORDER BY login')
|
||||
serv.actions[id]['users'] = cr.dictfetchall()
|
||||
serv.actions[id]['clean'] = True
|
||||
cr.commit()
|
||||
cr.close()
|
||||
except Exception, e:
|
||||
serv.actions[id]['clean'] = False
|
||||
|
@ -115,7 +122,7 @@ class db(netsvc.Service):
|
|||
'CREATE DB: %s' % (db_name))
|
||||
dbi = DBInitialize()
|
||||
create_thread = threading.Thread(target=dbi,
|
||||
args=(self, id, db_name, demo, lang))
|
||||
args=(self, id, db_name, demo, lang, user_password))
|
||||
create_thread.start()
|
||||
self.actions[id]['thread'] = create_thread
|
||||
return id
|
||||
|
@ -265,6 +272,7 @@ class db(netsvc.Service):
|
|||
except:
|
||||
res = []
|
||||
db.truedb.close()
|
||||
res.sort()
|
||||
return res
|
||||
|
||||
def change_admin_password(self, old_password, new_password):
|
||||
|
@ -275,13 +283,6 @@ class db(netsvc.Service):
|
|||
|
||||
def list_lang(self):
|
||||
return tools.scan_languages()
|
||||
import glob
|
||||
file_list = glob.glob(os.path.join(tools.config['root_path'], 'i18n', '*.csv'))
|
||||
def lang_tuple(fname):
|
||||
lang_dict=tools.get_languages()
|
||||
lang = os.path.basename(fname).split(".")[0]
|
||||
return (lang, lang_dict.get(lang, lang))
|
||||
return [lang_tuple(fname) for fname in file_list]
|
||||
|
||||
def server_version(self):
|
||||
""" Return the version of the server
|
||||
|
|
|
@ -226,12 +226,16 @@ class xml_import(object):
|
|||
def _test_xml_id(self, xml_id):
|
||||
id = xml_id
|
||||
if '.' in xml_id:
|
||||
assert len(id.split('.'))==2, """The ID reference '"%s" must contains
|
||||
module, id = xml_id.split('.', 1)
|
||||
assert '.' not in id, """The ID reference "%s" must contains
|
||||
maximum one dot. They are used to refer to other modules ID, in the
|
||||
form: module.record_id""" % (xml_id,)
|
||||
base, id = xml_id.split('.')
|
||||
if module != self.module:
|
||||
modcnt = self.pool.get('ir.module.module').search_count(self.cr, self.uid, ['&', ('name', '=', module), ('state', 'in', ['installed'])])
|
||||
assert modcnt == 1, """The ID "%s" refer to an uninstalled module""" % (xml_id,)
|
||||
|
||||
if len(id) > 64:
|
||||
self.logger.notifyChannel('init', netsvc.LOG_ERROR, 'id: %s is to long (max: 64)'%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")
|
||||
|
@ -252,7 +256,7 @@ form: module.record_id""" % (xml_id,)
|
|||
for dest,f in (('name','string'),('model','model'),('report_name','name')):
|
||||
res[dest] = rec.getAttribute(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')):
|
||||
for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment')):
|
||||
if rec.hasAttribute(field):
|
||||
res[dest] = rec.getAttribute(field).encode('utf8')
|
||||
if rec.hasAttribute('auto'):
|
||||
|
|
|
@ -27,102 +27,111 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
###############################################################################
|
||||
import operator
|
||||
import math
|
||||
|
||||
class graph(object):
|
||||
def __init__(self, nodes, transitions):
|
||||
self.nodes = nodes
|
||||
self.links = transitions
|
||||
def __init__(self, nodes, transitions, no_ancester=None):
|
||||
"""Initailize graph's object
|
||||
|
||||
@param nodes: list of ids of nodes in the graph
|
||||
@param transitions: list of edges in the graph in the form (source_node, destination_node)
|
||||
@param no_ancester: list of nodes with no incoming edges
|
||||
"""
|
||||
|
||||
self.nodes = nodes or []
|
||||
self.edges = transitions or []
|
||||
self.no_ancester = no_ancester or {}
|
||||
trans = {}
|
||||
|
||||
for t in transitions:
|
||||
trans.setdefault(t[0], [])
|
||||
trans[t[0]].append(t[1])
|
||||
self.transitions = trans
|
||||
self.result = {}
|
||||
self.levels = {}
|
||||
|
||||
def get_parent(self,node):
|
||||
count = 0
|
||||
for item in self.transitions:
|
||||
if self.transitions[item].__contains__(node):
|
||||
count +=1
|
||||
return count
|
||||
|
||||
def init_rank(self):
|
||||
self.temp = {}
|
||||
"""Computes rank of the nodes of the graph by finding initial feasible tree
|
||||
"""
|
||||
self.edge_wt = {}
|
||||
for link in self.links:
|
||||
self.temp[link] = self.result[link[1]]['y'] - self.result[link[0]]['y']
|
||||
self.edge_wt[link] = self.result[link[1]]['y'] - self.result[link[0]]['y']
|
||||
|
||||
cnt = 0
|
||||
list_node = []
|
||||
list_edge = []
|
||||
|
||||
while self.tight_tree()<self.result.__len__():
|
||||
cnt+=1
|
||||
tot_node = self.partial_order.__len__()
|
||||
#do until all the nodes in the component are searched
|
||||
while self.tight_tree()<tot_node:
|
||||
list_node = []
|
||||
list_edge = []
|
||||
|
||||
for node in self.nodes:
|
||||
if node not in self.reachable_nodes:
|
||||
list_node.append(node)
|
||||
list_edge = []
|
||||
|
||||
for link in self.temp:
|
||||
if link not in self.tree_edges:
|
||||
list_edge.append(link)
|
||||
for edge in self.edge_wt:
|
||||
if edge not in self.tree_edges:
|
||||
list_edge.append(edge)
|
||||
|
||||
slack = 100
|
||||
|
||||
for edge in list_edge:
|
||||
if (self.reachable_nodes.__contains__(edge[0]) and edge[1] not in self.reachable_nodes) or ( self.reachable_nodes.__contains__(edge[1]) and edge[0] not in self.reachable_nodes):
|
||||
if(slack>self.temp[edge]-1):
|
||||
slack = self.temp[edge]-1
|
||||
if ((self.reachable_nodes.__contains__(edge[0]) and edge[1] not in self.reachable_nodes) or
|
||||
(self.reachable_nodes.__contains__(edge[1]) and edge[0] not in self.reachable_nodes)):
|
||||
if(slack>self.edge_wt[edge]-1):
|
||||
slack = self.edge_wt[edge]-1
|
||||
new_edge = edge
|
||||
|
||||
if new_edge[0] not in self.reachable_nodes:
|
||||
delta = -(self.temp[new_edge]-1)
|
||||
delta = -(self.edge_wt[new_edge]-1)
|
||||
else:
|
||||
delta = self.temp[new_edge]-1
|
||||
delta = self.edge_wt[new_edge]-1
|
||||
|
||||
for node in self.result:
|
||||
if node in self.reachable_nodes:
|
||||
self.result[node]['y'] += delta
|
||||
|
||||
for link in self.temp:
|
||||
self.temp[link] = self.result[link[1]]['y'] - self.result[link[0]]['y']
|
||||
for edge in self.edge_wt:
|
||||
self.edge_wt[edge] = self.result[edge[1]]['y'] - self.result[edge[0]]['y']
|
||||
|
||||
self.init_cutvalues()
|
||||
self.init_cutvalues()
|
||||
|
||||
|
||||
|
||||
|
||||
def tight_tree(self,):
|
||||
def tight_tree(self):
|
||||
self.reachable_nodes = []
|
||||
self.tree_edges = []
|
||||
self.reachable_node(self.start)
|
||||
return self.reachable_nodes.__len__()
|
||||
|
||||
def reachable_node(self,node):
|
||||
|
||||
def reachable_node(self, node):
|
||||
"""Find the nodes of the graph which are only 1 rank apart from each other
|
||||
"""
|
||||
|
||||
if node not in self.reachable_nodes:
|
||||
self.reachable_nodes.append(node)
|
||||
for link in self.temp:
|
||||
if link[0]==node:
|
||||
# print link[0]
|
||||
if self.temp[link]==1:
|
||||
self.tree_edges.append(link)
|
||||
if link[1] not in self.reachable_nodes:
|
||||
self.reachable_nodes.append(link[1])
|
||||
self.reachable_node(link[1])
|
||||
for edge in self.edge_wt:
|
||||
if edge[0]==node:
|
||||
if self.edge_wt[edge]==1:
|
||||
self.tree_edges.append(edge)
|
||||
if edge[1] not in self.reachable_nodes:
|
||||
self.reachable_nodes.append(edge[1])
|
||||
self.reachable_node(edge[1])
|
||||
|
||||
|
||||
def init_cutvalues(self):
|
||||
"""Initailize cut values of edges of the feasible tree.
|
||||
Edges with negative cut-values are removed from the tree to optimize rank assignment
|
||||
"""
|
||||
self.cut_edges = {}
|
||||
self.head_nodes = []
|
||||
i=0;
|
||||
|
||||
for edge in self.tree_edges:
|
||||
self.head_nodes = []
|
||||
rest_edges = []
|
||||
rest_edges += self.tree_edges
|
||||
rest_edges.__delitem__(i)
|
||||
self.head_component(self.start,rest_edges)
|
||||
self.head_component(self.start, rest_edges)
|
||||
i+=1
|
||||
positive = 0
|
||||
negative = 0
|
||||
|
@ -137,129 +146,527 @@ class graph(object):
|
|||
positive+=1
|
||||
|
||||
self.cut_edges[edge] = positive - negative
|
||||
|
||||
|
||||
|
||||
|
||||
def head_component(self, node, rest_edges):
|
||||
"""Find nodes which are reachable from the starting node, after removing an edge
|
||||
"""
|
||||
if node not in self.head_nodes:
|
||||
self.head_nodes.append(node)
|
||||
for link in rest_edges:
|
||||
if link[0]==node:
|
||||
self.head_component(link[1],rest_edges)
|
||||
|
||||
for edge in rest_edges:
|
||||
if edge[0]==node:
|
||||
self.head_component(edge[1],rest_edges)
|
||||
|
||||
|
||||
def process_ranking(self, node, level=0):
|
||||
"""Computes initial feasible ranking after making graph acyclic with depth-first search
|
||||
"""
|
||||
|
||||
if node not in self.result:
|
||||
self.result[node] = {'x': None, 'y':level, 'mark':0}
|
||||
else:
|
||||
if level > self.result[node]['y']:
|
||||
self.result[node]['y'] = level
|
||||
|
||||
if self.result[node]['mark']==0:
|
||||
self.result[node]['mark'] = 1
|
||||
for t in self.transitions.get(node, []):
|
||||
self.process_ranking(t, level+1)
|
||||
for sec_end in self.transitions.get(node, []):
|
||||
self.process_ranking(sec_end, level+1)
|
||||
|
||||
|
||||
def make_acyclic(self, parent, node, level, tree):
|
||||
"""Computes Partial-order of the nodes with depth-first search
|
||||
"""
|
||||
|
||||
if node not in self.partial_order:
|
||||
self.partial_order[node] = {'level':level, 'mark':0}
|
||||
if parent:
|
||||
tree.append((parent, node))
|
||||
|
||||
if self.partial_order[node]['mark']==0:
|
||||
self.partial_order[node]['mark'] = 1
|
||||
for sec_end in self.transitions.get(node, []):
|
||||
self.links.append((node, sec_end))
|
||||
self.make_acyclic(node, sec_end, level+1, tree)
|
||||
|
||||
def preprocess_order(self):
|
||||
levels = {}
|
||||
for r in self.result:
|
||||
l = self.result[r]['y']
|
||||
levels.setdefault(l,[])
|
||||
levels[l].append(r)
|
||||
self.levels = levels
|
||||
return tree
|
||||
|
||||
def process_order(self, level):
|
||||
self.levels[level].sort(lambda x,y: cmp(self.result[x]['x'], self.result[y]['x']))
|
||||
for nodepos in range(len(self.levels[level])):
|
||||
node = self.levels[level][nodepos]
|
||||
if nodepos == 0:
|
||||
left = self.result[node]['x']- 0.5
|
||||
else:
|
||||
left = (self.result[node]['x'] + self.result[self.levels[level][nodepos-1]]['x']) / 2.0
|
||||
|
||||
if nodepos == (len(self.levels[level])-1):
|
||||
right = self.result[node]['x'] + 0.5
|
||||
else:
|
||||
right = (self.result[node]['x'] + self.result[self.levels[level][nodepos+1]]['x']) / 2.0
|
||||
|
||||
|
||||
if self.transitions.get(node, False):
|
||||
if len(self.transitions[node])==1:
|
||||
pos = (left+right)/2.0
|
||||
step = 0
|
||||
else:
|
||||
pos = left
|
||||
step = (-left+right) / (len(self.transitions[node])-1)
|
||||
|
||||
for n2 in self.transitions[node]:
|
||||
self.result[n2]['x'] = pos
|
||||
pos += step
|
||||
|
||||
def exchange(self,e,f):
|
||||
|
||||
def rev_edges(self, tree):
|
||||
"""reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order
|
||||
to make the graph acyclic
|
||||
"""
|
||||
Is_Cyclic = False
|
||||
i=0
|
||||
for link in self.links:
|
||||
src = link[0]
|
||||
des = link[1]
|
||||
edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level']
|
||||
if edge_len < 0:
|
||||
self.links.__delitem__(i)
|
||||
self.links.insert(i, (des, src))
|
||||
self.transitions[src].remove(des)
|
||||
self.transitions.setdefault(des, []).append(src)
|
||||
Is_Cyclic = True
|
||||
elif math.fabs(edge_len) > 1:
|
||||
Is_Cyclic = True
|
||||
i += 1
|
||||
|
||||
return Is_Cyclic
|
||||
|
||||
def exchange(self, e, f):
|
||||
"""Exchange edges to make feasible-tree optimized
|
||||
@param edge: edge with negative cut-value
|
||||
@param edge: new edge with minimum slack-value
|
||||
"""
|
||||
self.tree_edges.__delitem__(self.tree_edges.index(e))
|
||||
self.tree_edges.append(f)
|
||||
self.init_cutvalues()
|
||||
|
||||
|
||||
def enter_edge(self,edge):
|
||||
def enter_edge(self, edge):
|
||||
"""Finds a new_edge with minimum slack value to replace an edge with negative cut-value
|
||||
|
||||
@param edge: edge with negative cut-value
|
||||
"""
|
||||
|
||||
self.head_nodes = []
|
||||
rest_edges = []
|
||||
rest_edges += self.tree_edges
|
||||
rest_edges.__delitem__(rest_edges.index(edge))
|
||||
self.head_component(self.start,rest_edges)
|
||||
self.head_component(self.start, rest_edges)
|
||||
|
||||
if self.head_nodes.__contains__(edge[1]):
|
||||
l = []
|
||||
for node in self.result:
|
||||
if not self.head_nodes.__contains__(node):
|
||||
l.append(node)
|
||||
self.head_nodes = l
|
||||
|
||||
slack = 100
|
||||
new_edge = edge
|
||||
for source_node in self.transitions:
|
||||
if source_node in self.head_nodes:
|
||||
for dest_node in self.transitions[source_node]:
|
||||
if dest_node not in self.head_nodes:
|
||||
if(slack>(self.temp[edge]-1)):
|
||||
slack = self.temp[edge]-1
|
||||
new_edge = (source_node,dest_node)
|
||||
if(slack>(self.edge_wt[edge]-1)):
|
||||
slack = self.edge_wt[edge]-1
|
||||
new_edge = (source_node, dest_node)
|
||||
|
||||
return new_edge
|
||||
|
||||
|
||||
def leave_edge(self):
|
||||
"""Returns the edge with negative cut_value(if exists)
|
||||
"""
|
||||
if self.critical_edges:
|
||||
for edge in self.critical_edges:
|
||||
self.cut_edges[edge] = 0
|
||||
|
||||
for edge in self.cut_edges:
|
||||
if self.cut_edges[edge]<0:
|
||||
return edge
|
||||
return ()
|
||||
|
||||
def process(self, starting_node):
|
||||
pos = (len(starting_node) - 1.0)/2.0
|
||||
self.start = starting_node[0]
|
||||
for s in starting_node:
|
||||
self.process_ranking(s)
|
||||
self.result[s]['x'] = pos
|
||||
pos += 1.0
|
||||
self.init_rank()
|
||||
#normalize
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def finalize_rank(self, node, level):
|
||||
self.result[node]['y'] = level
|
||||
for destination in self.optimal_edges.get(node, []):
|
||||
self.finalize_rank(destination, level+1)
|
||||
|
||||
|
||||
def normalize(self):
|
||||
"""The ranks are normalized by setting the least rank to zero.
|
||||
"""
|
||||
|
||||
least_rank=100
|
||||
|
||||
#normalization
|
||||
for node in self.result:
|
||||
if least_rank>self.result[node]['y']:
|
||||
least_rank = self.result[node]['y']
|
||||
|
||||
if(least_rank!=0):
|
||||
diff = least_rank
|
||||
for node in self.result:
|
||||
self.result[node]['y']-=least_rank
|
||||
self.result[node]['y']-=least_rank
|
||||
|
||||
e = self.leave_edge()
|
||||
#while e:
|
||||
f = self.enter_edge(e)
|
||||
self.exchange(e,f)
|
||||
e = self.leave_edge()
|
||||
|
||||
def make_chain(self):
|
||||
"""Edges between nodes more than one rank apart are replaced by chains of unit
|
||||
length edges between temporary nodes.
|
||||
"""
|
||||
|
||||
for edge in self.edge_wt:
|
||||
if self.edge_wt[edge]>1:
|
||||
self.transitions[edge[0]].remove(edge[1])
|
||||
start = self.result[edge[0]]['y']
|
||||
end = self.result[edge[1]]['y']
|
||||
|
||||
for rank in range(start+1, end):
|
||||
if not self.result.get((rank, 'temp'), False):
|
||||
self.result[(rank, 'temp')] = {'x': None, 'y': rank, 'mark': 0}
|
||||
|
||||
for rank in range(start, end):
|
||||
if start==rank:
|
||||
self.transitions[edge[0]].append((rank+1, 'temp'))
|
||||
elif rank==end-1:
|
||||
self.transitions.setdefault((rank, 'temp'), []).append(edge[1])
|
||||
else:
|
||||
self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp'))
|
||||
|
||||
|
||||
def init_order(self, node, level):
|
||||
"""Initialize orders the nodes in each rank with depth-first search
|
||||
"""
|
||||
if not self.result[node]['x']:
|
||||
self.result[node]['x'] = self.order[level]
|
||||
self.order[level] = self.order[level]+1
|
||||
|
||||
for sec_end in self.transitions.get(node, []):
|
||||
self.init_order(sec_end, self.result[sec_end]['y'])
|
||||
|
||||
|
||||
def order_heuristic(self):
|
||||
for i in range(12):
|
||||
self.wmedian()
|
||||
|
||||
|
||||
def wmedian(self):
|
||||
"""Applies median heuristic to find optimzed order of the nodes with in their ranks
|
||||
"""
|
||||
for level in self.levels:
|
||||
|
||||
node_median = []
|
||||
nodes = self.levels[level]
|
||||
for node in nodes:
|
||||
node_median.append((node, self.median_value(node, level-1)))
|
||||
|
||||
sort_list = sorted(node_median, key=operator.itemgetter(1))
|
||||
|
||||
new_list = [tuple[0] for tuple in sort_list]
|
||||
|
||||
self.levels[level] = new_list
|
||||
order = 0
|
||||
for node in nodes:
|
||||
self.result[node]['x'] = order
|
||||
order +=1
|
||||
|
||||
|
||||
|
||||
|
||||
def median_value(self, node, adj_rank):
|
||||
"""Returns median value of a vertex , defined as the median position of the adjacent vertices
|
||||
|
||||
@param node: node to process
|
||||
@param adj_rank: rank 1 less than the node's rank
|
||||
"""
|
||||
adj_nodes = self.adj_position(node, adj_rank)
|
||||
l = len(adj_nodes)
|
||||
m = l/2
|
||||
|
||||
if l==0:
|
||||
return -1.0
|
||||
elif l%2 == 1:
|
||||
return adj_nodes[m]#median of the middle element
|
||||
elif l==2:
|
||||
return (adj_nodes[0]+adj_nodes[1])/2
|
||||
else:
|
||||
left = adj_nodes[m-1] - adj_nodes[0]
|
||||
right = adj_nodes[l-1] - adj_nodes[m]
|
||||
return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right)
|
||||
|
||||
|
||||
def adj_position(self, node, adj_rank):
|
||||
"""Returns list of the present positions of the nodes adjacent to node in the given adjacent rank.
|
||||
|
||||
@param node: node to process
|
||||
@param adj_rank: rank 1 less than the node's rank
|
||||
"""
|
||||
|
||||
pre_level_nodes = self.levels.get(adj_rank, [])
|
||||
adj_nodes = []
|
||||
|
||||
if pre_level_nodes:
|
||||
for src in pre_level_nodes:
|
||||
if (self.transitions.get(src) and self.transitions[src].__contains__(node)):
|
||||
adj_nodes.append(self.result[src]['x'])
|
||||
|
||||
return adj_nodes
|
||||
|
||||
|
||||
def preprocess_order(self):
|
||||
levels = {}
|
||||
|
||||
for r in self.partial_order:
|
||||
l = self.result[r]['y']
|
||||
levels.setdefault(l,[])
|
||||
levels[l].append(r)
|
||||
|
||||
self.levels = levels
|
||||
|
||||
|
||||
def graph_order(self):
|
||||
"""Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component
|
||||
"""
|
||||
mid_pos = None
|
||||
max_level = max(map(lambda x: len(x), self.levels.values()))
|
||||
|
||||
for level in self.levels:
|
||||
if level:
|
||||
no = len(self.levels[level])
|
||||
factor = (max_level - no) * 0.10
|
||||
list = self.levels[level]
|
||||
list.reverse()
|
||||
|
||||
if no%2==0:
|
||||
first_half = list[no/2:]
|
||||
factor = -factor
|
||||
else:
|
||||
first_half = list[no/2+1:]
|
||||
if max_level==1:#for the case when horizontal graph is there
|
||||
self.result[list[no/2]]['x'] = mid_pos + (self.result[list[no/2]]['y']%2 * 0.5)
|
||||
else:
|
||||
self.result[list[no/2]]['x'] = mid_pos + factor
|
||||
|
||||
last_half = list[:no/2]
|
||||
|
||||
i=1
|
||||
for node in first_half:
|
||||
self.result[node]['x'] = mid_pos - (i + factor)
|
||||
i += 1
|
||||
|
||||
i=1
|
||||
for node in last_half:
|
||||
self.result[node]['x'] = mid_pos + (i + factor)
|
||||
i += 1
|
||||
else:
|
||||
self.max_order += max_level+1
|
||||
mid_pos = self.result[self.start]['x']
|
||||
|
||||
|
||||
def tree_order(self, node, last=0):
|
||||
mid_pos = self.result[node]['x']
|
||||
l = self.transitions.get(node, [])
|
||||
l.reverse()
|
||||
no = len(l)
|
||||
|
||||
if no%2==0:
|
||||
first_half = l[no/2:]
|
||||
factor = 1
|
||||
else:
|
||||
first_half = l[no/2+1:]
|
||||
factor = 0
|
||||
|
||||
last_half = l[:no/2]
|
||||
|
||||
i=1
|
||||
for child in first_half:
|
||||
self.result[child]['x'] = mid_pos - (i - (factor * 0.5))
|
||||
i += 1
|
||||
|
||||
if self.transitions.get(child, False):
|
||||
if last:
|
||||
self.result[child]['x'] = last + len(self.transitions[child])/2 + 1
|
||||
last = self.tree_order(child, last)
|
||||
|
||||
if no%2:
|
||||
mid_node = l[no/2]
|
||||
self.result[mid_node]['x'] = mid_pos
|
||||
|
||||
if self.transitions.get((mid_node), False):
|
||||
if last:
|
||||
self.result[mid_node]['x'] = last + len(self.transitions[mid_node])/2 + 1
|
||||
last = self.tree_order(mid_node)
|
||||
else:
|
||||
if last:
|
||||
self.result[mid_node]['x'] = last + 1
|
||||
self.result[node]['x'] = self.result[mid_node]['x']
|
||||
mid_pos = self.result[node]['x']
|
||||
|
||||
i=1
|
||||
last_child = None
|
||||
for child in last_half:
|
||||
self.result[child]['x'] = mid_pos + (i - (factor * 0.5))
|
||||
last_child = child
|
||||
i += 1
|
||||
if self.transitions.get(child, False):
|
||||
if last:
|
||||
self.result[child]['x'] = last + len(self.transitions[child])/2 + 1
|
||||
last = self.tree_order(child, last)
|
||||
|
||||
if last_child:
|
||||
last = self.result[last_child]['x']
|
||||
|
||||
return last
|
||||
|
||||
|
||||
def process_order(self):
|
||||
"""Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component
|
||||
"""
|
||||
max_level = max(map(lambda x: len(x), self.levels.values()))
|
||||
|
||||
if max_level%2:
|
||||
self.result[self.start]['x'] = (max_level+1)/2 + self.max_order +1
|
||||
else:
|
||||
self.result[self.start]['x'] = (max_level)/2 + self.max_order + 1
|
||||
|
||||
if self.Is_Cyclic:
|
||||
self.graph_order()
|
||||
|
||||
else:
|
||||
self.result[self.start]['x'] = 0
|
||||
self.tree_order(self.start, 0)
|
||||
min_order = math.fabs(min(map(lambda x: x['x'], self.result.values())))
|
||||
min_order += self.max_order + 1
|
||||
|
||||
for level in self.levels:
|
||||
for node in self.levels[level]:
|
||||
self.result[node]['x'] += min_order
|
||||
|
||||
self.max_order = max(map(lambda x: x['x'], self.result.values()))
|
||||
|
||||
def find_starts(self):
|
||||
"""Finds other start nodes of the graph in the case when graph is disconneted
|
||||
"""
|
||||
rem_nodes = []
|
||||
for node in self.nodes:
|
||||
if not self.partial_order.get(node):
|
||||
rem_nodes.append(node)
|
||||
cnt = 0
|
||||
while True:
|
||||
if len(rem_nodes)==1:
|
||||
self.start_nodes.append(rem_nodes[0])
|
||||
break
|
||||
else:
|
||||
count = 0
|
||||
new_start = rem_nodes[0]
|
||||
largest_tree = []
|
||||
|
||||
for node in rem_nodes:
|
||||
self.partial_order = {}
|
||||
tree = self.make_acyclic(None, node, 0, [])
|
||||
if len(tree)+1 > count:
|
||||
count = len(tree) + 1
|
||||
new_start = node
|
||||
largest_tree = tree
|
||||
else:
|
||||
if not largest_tree:
|
||||
new_start = rem_nodes[0]
|
||||
rem_nodes.remove(new_start)
|
||||
|
||||
self.start_nodes.append(new_start)
|
||||
|
||||
|
||||
for edge in largest_tree:
|
||||
if rem_nodes.__contains__(edge[0]):
|
||||
rem_nodes.remove(edge[0])
|
||||
if rem_nodes.__contains__(edge[1]):
|
||||
rem_nodes.remove(edge[1])
|
||||
|
||||
if not rem_nodes:
|
||||
break
|
||||
|
||||
|
||||
def rank(self):
|
||||
"""Finds the optimized rank of the nodes using Network-simplex algorithm
|
||||
|
||||
@param start: starting node of the component
|
||||
"""
|
||||
self.levels = {}
|
||||
self.critical_edges = []
|
||||
self.partial_order = {}
|
||||
self.links = []
|
||||
self.Is_Cyclic = False
|
||||
|
||||
tree = self.make_acyclic(None, self.start, 0, [])
|
||||
self.Is_Cyclic = self.rev_edges(tree)
|
||||
self.process_ranking(self.start)
|
||||
self.init_rank()
|
||||
|
||||
#make cut values of all tree edges to 0 to optimize feasible tree
|
||||
e = self.leave_edge()
|
||||
|
||||
while e :
|
||||
f = self.enter_edge(e)
|
||||
if e==f:
|
||||
self.critical_edges.append(e)
|
||||
else:
|
||||
self.exchange(e,f)
|
||||
e = self.leave_edge()
|
||||
|
||||
#finalize rank using optimum feasible tree
|
||||
# self.optimal_edges = {}
|
||||
# for edge in self.tree_edges:
|
||||
# source = self.optimal_edges.setdefault(edge[0], [])
|
||||
# source.append(edge[1])
|
||||
|
||||
# self.finalize_rank(self.start, 0)
|
||||
|
||||
#normalization
|
||||
self.normalize()
|
||||
for edge in self.edge_wt:
|
||||
self.edge_wt[edge] = self.result[edge[1]]['y'] - self.result[edge[0]]['y']
|
||||
|
||||
def order_in_rank(self):
|
||||
"""Finds optimized order of the nodes within their ranks using median heuristic
|
||||
|
||||
@param start: starting node of the component
|
||||
"""
|
||||
|
||||
self.make_chain()
|
||||
self.preprocess_order()
|
||||
for n in self.levels:
|
||||
self.process_order(n)
|
||||
|
||||
self.order = {}
|
||||
max_rank = max(map(lambda x: x, self.levels.keys()))
|
||||
|
||||
for i in range(max_rank+1):
|
||||
self.order[i] = 0
|
||||
|
||||
self.init_order(self.start, self.result[self.start]['y'])
|
||||
|
||||
for level in self.levels:
|
||||
self.levels[level].sort(lambda x, y: cmp(self.result[x]['x'], self.result[y]['x']))
|
||||
|
||||
self.order_heuristic()
|
||||
self.process_order()
|
||||
|
||||
def process(self, starting_node):
|
||||
"""Process the graph to find ranks and order of the nodes
|
||||
|
||||
@param starting_node: node from where to start the graph search
|
||||
"""
|
||||
|
||||
self.start_nodes = starting_node or []
|
||||
self.partial_order = {}
|
||||
self.links = []
|
||||
|
||||
if self.nodes:
|
||||
if self.start_nodes:
|
||||
#add dummy edges to the nodes which does not have any incoming edges
|
||||
tree = self.make_acyclic(None, self.start_nodes[0], 0, [])
|
||||
|
||||
for node in self.no_ancester:
|
||||
for sec_node in self.transitions.get(node, []):
|
||||
if sec_node in self.partial_order.keys():
|
||||
self.transitions[self.start_nodes[0]].append(node)
|
||||
break
|
||||
|
||||
self.partial_order = {}
|
||||
tree = self.make_acyclic(None, self.start_nodes[0], 0, [])
|
||||
|
||||
|
||||
# if graph is disconnected or no start-node is given
|
||||
#than to find starting_node for each component of the node
|
||||
if len(self.nodes) > len(self.partial_order):
|
||||
self.find_starts()
|
||||
|
||||
self.max_order = 0
|
||||
#for each component of the graph find ranks and order of the nodes
|
||||
for s in self.start_nodes:
|
||||
self.start = s
|
||||
self.rank() # First step:Netwoek simplex algorithm
|
||||
self.order_in_rank() #Second step: ordering nodes within ranks
|
||||
|
||||
|
||||
def __str__(self):
|
||||
result = ''
|
||||
|
@ -269,23 +676,25 @@ class graph(object):
|
|||
result += '\tPosX: '+ str(self.result[node]['x']) + ' - Node:' + node + "\n"
|
||||
return result
|
||||
|
||||
def scale(self, maxx, maxy, plusx2=0, plusy2=0):
|
||||
plusx = - min(map(lambda x: x['x'],self.result.values()))
|
||||
plusy = - min(map(lambda x: x['y'],self.result.values()))
|
||||
|
||||
maxcurrent = 1.0
|
||||
diff = 1.0
|
||||
for l in self.levels:
|
||||
for n in range(1, len(self.levels[l])):
|
||||
n1 = self.levels[l][n]
|
||||
n2 = self.levels[l][n-1]
|
||||
diff = abs(self.result[n2]['x']-self.result[n1]['x'])
|
||||
if diff<maxcurrent:
|
||||
maxcurrent=diff
|
||||
factor = maxx / diff
|
||||
for r in self.result:
|
||||
self.result[r]['x'] = (self.result[r]['x']+plusx) * factor + plusx2
|
||||
self.result[r]['y'] = (self.result[r]['y']+plusy) * maxy + plusy2
|
||||
def scale(self, maxx, maxy, nwidth=0, nheight=0, margin=20):
|
||||
"""Computes actual co-ordiantes of the nodes
|
||||
"""
|
||||
|
||||
#for flat edges ie. source an destination nodes are on the same rank
|
||||
for src in self.transitions:
|
||||
for des in self.transitions[src]:
|
||||
if (self.result[des]['y'] - self.result[src]['y'] == 0):
|
||||
self.result[src]['y'] += 0.08
|
||||
self.result[des]['y'] -= 0.08
|
||||
|
||||
factorX = maxx + nheight
|
||||
factorY = maxy + nwidth
|
||||
|
||||
for node in self.result:
|
||||
self.result[node]['x'] = (self.result[node]['x']) * factorX + margin
|
||||
self.result[node]['y'] = (self.result[node]['y']) * factorY + margin
|
||||
|
||||
|
||||
def result_get(self):
|
||||
return self.result
|
||||
|
|
|
@ -256,6 +256,23 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
|
|||
raise IOError, 'File not found : '+str(name)
|
||||
|
||||
|
||||
def oswalksymlinks(top, topdown=True, onerror=None):
|
||||
"""
|
||||
same as os.walk but follow symlinks
|
||||
attention: all symlinks are walked before all normals directories
|
||||
"""
|
||||
for dirpath, dirnames, filenames in os.walk(top, topdown, onerror):
|
||||
if topdown:
|
||||
yield dirpath, dirnames, filenames
|
||||
|
||||
symlinks = filter(lambda dirname: os.path.islink(os.path.join(dirpath, dirname)), dirnames)
|
||||
for s in symlinks:
|
||||
for x in oswalksymlinks(os.path.join(dirpath, s), topdown, onerror):
|
||||
yield x
|
||||
|
||||
if not topdown:
|
||||
yield dirpath, dirnames, filenames
|
||||
|
||||
#----------------------------------------------------------
|
||||
# iterables
|
||||
#----------------------------------------------------------
|
||||
|
@ -638,7 +655,7 @@ def get_languages():
|
|||
|
||||
def scan_languages():
|
||||
import glob
|
||||
file_list = [os.path.splitext(os.path.basename(f))[0] for f in glob.glob(os.path.join(config['root_path'], 'i18n', '*.csv'))]
|
||||
file_list = [os.path.splitext(os.path.basename(f))[0] for f in glob.glob(os.path.join(config['addons_path'], 'base', 'i18n', '*.po'))]
|
||||
lang_dict = get_languages()
|
||||
return [(lang, lang_dict.get(lang, lang)) for lang in file_list]
|
||||
|
||||
|
@ -672,6 +689,18 @@ def mod10r(number):
|
|||
return result + str((10 - report) % 10)
|
||||
|
||||
|
||||
def human_size(sz):
|
||||
"""
|
||||
Return the size in a human readable format
|
||||
"""
|
||||
if not sz:
|
||||
return False
|
||||
units = ('bytes', 'Kb', 'Mb', 'Gb')
|
||||
s, i = float(sz), 0
|
||||
while s >= 1024 and i < len(units)-1:
|
||||
s = s / 1024
|
||||
i = i + 1
|
||||
return "%0.2f %s" % (s, units[i])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -115,7 +115,7 @@ class TinyPoFile(object):
|
|||
self.tnrs = []
|
||||
while line:
|
||||
line = self.lines.pop(0).strip()
|
||||
return next()
|
||||
return self.next()
|
||||
|
||||
while not line.startswith('msgstr'):
|
||||
if not line:
|
||||
|
@ -166,23 +166,30 @@ class TinyPoFile(object):
|
|||
)
|
||||
|
||||
def write(self, modules, tnrs, source, trad):
|
||||
def quote(str):
|
||||
return '"%s"' % str.replace('"','\\"') \
|
||||
.replace('\n', '\\n"\n"')
|
||||
def quote(s):
|
||||
return '"%s"' % s.replace('"','\\"') \
|
||||
.replace('\n', '\\n"\n"')
|
||||
|
||||
plurial = len(modules) > 1 and 's' or ''
|
||||
self.buffer.write("#. module%s: %s\n" \
|
||||
"#, python-format\n" \
|
||||
% (plurial, ', '.join(modules)))
|
||||
self.buffer.write("#. module%s: %s\n" % (plurial, ', '.join(modules)))
|
||||
|
||||
if "code" in map(lambda e: e[0], tnrs):
|
||||
# only strings in python code are python formated
|
||||
self.buffer.write("#, python-format\n")
|
||||
|
||||
|
||||
for type, name, res_id in tnrs:
|
||||
self.buffer.write("#: %s:%s:%s\n" % (type, name, str(res_id)))
|
||||
for typy, name, res_id in tnrs:
|
||||
self.buffer.write("#: %s:%s:%s\n" % (typy, name, res_id))
|
||||
|
||||
self.buffer.write("msgid %s\n" \
|
||||
"msgstr %s\n\n" \
|
||||
% (quote(source), quote(trad))
|
||||
)
|
||||
|
||||
if not isinstance(trad, unicode):
|
||||
trad = unicode(trad, 'utf8')
|
||||
if not isinstance(source, unicode):
|
||||
source = unicode(source, 'utf8')
|
||||
|
||||
msg = "msgid %s\n" \
|
||||
"msgstr %s\n\n" \
|
||||
% (quote(source), quote(trad))
|
||||
self.buffer.write(msg.encode('utf8'))
|
||||
|
||||
|
||||
# Methods to export the translation file
|
||||
|
@ -226,7 +233,7 @@ def trans_export(lang, modules, buffer, format, dbname=None):
|
|||
_process('po', [mod], modrows, buf, lang, newlang)
|
||||
|
||||
tar = tarfile.open(fileobj=buffer, mode='w|gz')
|
||||
tar.add(tmpdir, '/')
|
||||
tar.add(tmpdir, '')
|
||||
tar.close()
|
||||
|
||||
else:
|
||||
|
@ -324,7 +331,7 @@ def trans_generate(lang, modules, dbname=None):
|
|||
_to_translate = []
|
||||
def push_translation(module, type, name, id, source):
|
||||
tuple = (module, type, name, id, source)
|
||||
if not tuple in _to_translate:
|
||||
if source and tuple not in _to_translate:
|
||||
_to_translate.append(tuple)
|
||||
|
||||
|
||||
|
@ -354,7 +361,7 @@ def trans_generate(lang, modules, dbname=None):
|
|||
|
||||
# export arch
|
||||
arch = result['arch']
|
||||
if not isinstance(arch, UpdateableStr):
|
||||
if arch and not isinstance(arch, UpdateableStr):
|
||||
d = xml.dom.minidom.parseString(arch)
|
||||
for t in trans_parse_view(d.documentElement):
|
||||
push_translation(module, 'wizard_view', name, 0, t)
|
||||
|
@ -368,6 +375,8 @@ def trans_generate(lang, modules, dbname=None):
|
|||
|
||||
elif model=='ir.model.fields':
|
||||
field_name = obj.name
|
||||
if not field_name in pool.get(obj.model)._columns:
|
||||
continue
|
||||
field_def = pool.get(obj.model)._columns[field_name]
|
||||
|
||||
name = obj.model + "," + field_name
|
||||
|
@ -427,23 +436,26 @@ def trans_generate(lang, modules, dbname=None):
|
|||
# parse source code for _() calls
|
||||
def get_module_from_path(path):
|
||||
relative_addons_path = tools.config['addons_path'][len(tools.config['root_path'])+1:]
|
||||
if path.startswith(relative_addons_path):
|
||||
if path.startswith(relative_addons_path) and (os.path.dirname(path) != relative_addons_path):
|
||||
path = path[len(relative_addons_path)+1:]
|
||||
return path.split(os.path.sep)[0]
|
||||
return 'base' # files that are not in a module are considered as being in 'base' module
|
||||
|
||||
modobj = pool.get('ir.module.module')
|
||||
for root, dirs, files in os.walk(tools.config['root_path']):
|
||||
installed_modids = modobj.search(cr, uid, [('state', '=', 'installed')])
|
||||
installed_modules = map(lambda m: m['name'], modobj.browse(cr, uid, installed_modids, ['name']))
|
||||
|
||||
for root, dirs, files in tools.oswalksymlinks(tools.config['root_path']):
|
||||
for fname in fnmatch.filter(files, '*.py'):
|
||||
fabsolutepath = join(root, fname)
|
||||
frelativepath = fabsolutepath[len(tools.config['root_path'])+1:]
|
||||
module = get_module_from_path(frelativepath)
|
||||
is_mod_installed = modobj.search(cr, uid, [('state', '=', 'installed'), ('name', '=', module)]) <> []
|
||||
is_mod_installed = module in installed_modules
|
||||
if (('all' in modules) or (module in modules)) and is_mod_installed:
|
||||
code_string = tools.file_open(fabsolutepath, subdir='').read()
|
||||
iter = re.finditer(
|
||||
'[^a-zA-Z0-9_]_\([\s]*["\'](.+?)["\'][\s]*\)',
|
||||
code_string)
|
||||
code_string, re.M)
|
||||
for i in iter:
|
||||
push_translation(module, 'code', frelativepath, 0, i.group(1).encode('utf8'))
|
||||
|
||||
|
@ -457,22 +469,24 @@ def trans_generate(lang, modules, dbname=None):
|
|||
cr.close()
|
||||
return out
|
||||
|
||||
def trans_load(db_name, filename, lang, strict=False):
|
||||
def trans_load(db_name, filename, lang, strict=False, verbose=True):
|
||||
logger = netsvc.Logger()
|
||||
try:
|
||||
fileobj = open(filename,'r')
|
||||
fileformat = os.path.splitext(filename)[-1][1:].lower()
|
||||
r = trans_load_data(db_name, fileobj, fileformat, lang, strict=False)
|
||||
r = trans_load_data(db_name, fileobj, fileformat, lang, strict=strict, verbose=verbose)
|
||||
fileobj.close()
|
||||
return r
|
||||
except IOError:
|
||||
logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't read file")
|
||||
if verbose:
|
||||
logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't read file")
|
||||
return None
|
||||
|
||||
def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=None):
|
||||
def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=None, verbose=True):
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel("init", netsvc.LOG_INFO,
|
||||
'loading translation file for language %s' % (lang))
|
||||
if verbose:
|
||||
logger.notifyChannel("init", netsvc.LOG_INFO,
|
||||
'loading translation file for language %s' % (lang))
|
||||
pool = pooler.get_pool(db_name)
|
||||
lang_obj = pool.get('res.lang')
|
||||
trans_obj = pool.get('ir.translation')
|
||||
|
@ -486,8 +500,7 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
|
|||
if not lang_name:
|
||||
lang_name=lang
|
||||
languages=tools.get_languages()
|
||||
if lang in languages:
|
||||
lang_name=languages[lang]
|
||||
lang_name = languages.get(lang, lang)
|
||||
ids = lang_obj.create(cr, uid, {
|
||||
'code': lang,
|
||||
'name': lang_name,
|
||||
|
@ -517,7 +530,6 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
|
|||
line = 1
|
||||
for row in reader:
|
||||
line += 1
|
||||
#try:
|
||||
# skip empty rows and rows where the translation field (=last fiefd) is empty
|
||||
if (not row) or (not row[-1]):
|
||||
#print "translate: skip %s" % repr(row)
|
||||
|
@ -583,15 +595,10 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
|
|||
else:
|
||||
trans_obj.create(cr, uid, dic)
|
||||
cr.commit()
|
||||
#except Exception, e:
|
||||
# logger.notifyChannel('init', netsvc.LOG_ERROR,
|
||||
# 'Import error: %s on line %d: %s!' % (str(e), line, row))
|
||||
# cr.rollback()
|
||||
# cr.close()
|
||||
# cr = pooler.get_db(db_name).cursor()
|
||||
cr.close()
|
||||
logger.notifyChannel("init", netsvc.LOG_INFO,
|
||||
"translation file loaded succesfully")
|
||||
if verbose:
|
||||
logger.notifyChannel("init", netsvc.LOG_INFO,
|
||||
"translation file loaded succesfully")
|
||||
except IOError:
|
||||
logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't read file")
|
||||
|
||||
|
|
Loading…
Reference in New Issue