[MERGE] new configuration wizard system

bzr revid: odo@openerp.com-20110706161606-lluokqgsq9ezjbmc
This commit is contained in:
Vo Minh Thu (OpenERP) 2011-07-06 18:16:06 +02:00 committed by Olivier Dony
commit f51a5e1498
22 changed files with 280 additions and 212 deletions

View File

@ -23,6 +23,7 @@ import ir
import module
import res
import publisher_warranty
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -94,7 +94,6 @@
'test/bug_lp541545.xml',
'test/test_osv_expression.yml',
'test/test_ir_rule.yml', # <-- These tests modify/add/delete ir_rules.
'test/test_config_users.yml',
'test/test_ir_values.yml',
],
'installable': True,

View File

@ -180,11 +180,16 @@
</search>
</field>
</record>
<!--
======================
Company
======================
-->
<report id="preview_report" model="res.company" name="preview.report" multi="True"
rml="base/report/preview_report.rml" string="Preview Report"/>
<record id="view_company_form" model="ir.ui.view">
<field name="name">res.company.form</field>
<field name="model">res.company</field>
@ -192,18 +197,34 @@
<field name="arch" type="xml">
<form string="Company">
<group colspan="4" col="6">
<field colspan="4" name="name" select="1"/>
<field name="partner_id" readonly="1" select="1" required="0"/>
<field name="parent_id" select="1" groups="base.group_multi_company"/>
<group colspan="4" col="4">
<field name="name"/>
<field name="partner_id" readonly="1" required="0"/>
<field name="parent_id" groups="base.group_multi_company"/>
</group>
<group colspan="2" col="2">
<field name="logo" nolabel="1" widget="image"/>
</group>
</group>
<notebook colspan="4">
<page string="General Information">
<separator string="Address Information" colspan="4"/>
<field name="street"/>
<field name="street2"/>
<field name="zip"/>
<field name="city"/>
<field name="country_id"/>
<field name="state_id"/>
<field name="phone"/>
<field name="email"/>
<separator string="Header/Footer of Reports" colspan="4"/>
<field name="rml_header1" colspan="4"/>
<field name="rml_footer1" colspan="4"/>
<field name="rml_footer2" colspan="4"/>
<field name="currency_id"/>
<separator colspan="4" string="Your Logo - Use a size of about 450x150 pixels."/>
<field colspan="4" name="logo" widget="image"/>
<group colspan="4" col="8">
<label string="" colspan="7"/>
<button name="%(preview_report)d" string="Preview Report" type="action" icon="gtk-print"/>
</group>
</page>
<page string="Header/Footer" groups="base.group_extended">
<field colspan="4" name="rml_header" nolabel="1"/>
@ -215,6 +236,9 @@
<field colspan="2" name="rml_header3" nolabel="1"/>
</page>
<page string="Configuration">
<separator string="Accounting" colspan="4"/>
<field name="currency_id" colspan="2"/>
<newline/>
</page>
</notebook>
</form>
@ -233,78 +257,6 @@
</field>
</record>
<record id="view_users_configuration_form" model="ir.ui.view">
<field name="name">res.config.users.confirm.form</field>
<field name="model">res.config.users</field>
<field name="type">form</field>
<field name="inherit_id" ref="res_config_view_base"/>
<field name="arch" type="xml">
<data>
<form position="attributes">
<attribute name="string">Create User</attribute>
</form>
<xpath expr='//separator[@string="title"]' position='attributes'>
<attribute name='string'>New User</attribute>
</xpath>
<xpath expr="//label[@string='description']"
position="attributes">
<attribute name="string">Create additional users and assign them groups that will allow them to have access to selected functionalities within the system. Click on 'Done' if you do not wish to add more users at this stage, you can always do this later.</attribute>
</xpath>
<xpath expr='//separator[@string="vsep"]' position='attributes'>
<attribute name='string'></attribute>
</xpath>
<group string="res_config_contents" position="replace">
<field name="name"/>
<field name="email"/>
<field name="login"/>
<field name="password" password="True"/>
<field name="context_lang"/>
<field name="context_tz"/>
<separator string="Group" colspan="4"/>
<label align="0.0" colspan="4" string="Groups are used to define access rights on objects and the visibility of screens and menus"/>
<field colspan="4" nolabel="1" name="groups_id"/>
</group>
<xpath expr='//button[@name="action_next"]'
position='attributes'>
<attribute name="name">action_add</attribute>
<attribute name='string'>Add User</attribute>
<attribute name='icon'>gtk-add</attribute>
</xpath>
<xpath expr='//button[@name="action_skip"]'
position='attributes'>
<!-- if this one is performed first, it transforms
the action_skip into action_next, and the
transformation of action_next to action_add,
since it uses first-match, transforms the same
button. And we end up with [add] [next] instead
of [next] [add]
Would probably be simpler to just replace both
by nothing and create a pair of brand new
buttons... but we'd have to handle the groups
around the buttons... oh well...
-->
<attribute name="name">action_next</attribute>
<attribute name='string'>Done</attribute>
<attribute name='icon'>gtk-go-forward</attribute>
</xpath>
</data>
</field>
</record>
<record id="action_config_user_form" model="ir.actions.act_window">
<field name="name">Create Users</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.config.users</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_users_configuration_form"/>
<field name="target">new</field>
</record>
<record id="view_confirm_simple_view_form" model="ir.ui.view">
<field name="name">Configure Your Interface</field>
<field name="model">res.config.view</field>
@ -345,17 +297,19 @@
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record id="category_administration_config" model="ir.actions.todo.category">
<field name="name">Administration</field>
<field name="sequence">1</field>
</record>
<record id="config_wizard_step_user" model="ir.actions.todo">
<field name="action_id" ref="action_config_user_form"/>
<field name="sequence">10</field>
<field name="restart">never</field>
<field name="state">done</field>
</record>
<record id="config_wizard_simple_view" model="ir.actions.todo">
<field name="action_id" ref="action_config_simple_view_form"/>
<field name="restart">always</field>
<field name="category_id" ref="category_administration_config"/>
<field name="type">special</field>
<field name="sequence">1</field>
<field name="state">skip</field>
</record>
</data>
</openerp>

View File

@ -1885,7 +1885,8 @@
<tree editable="bottom" string="Config Wizard Steps">
<field name="sequence"/>
<field name="action_id"/>
<field name="restart"/>
<field name="category_id"/>
<field name="type"/>
<field name="state" readonly="1"/>
<button name="action_launch" states="open" string="Launch" type="object" icon="gtk-execute" help="Launch Configuration Wizard"/>
<button name="action_open" states="cancel,skip,done"
@ -1903,8 +1904,9 @@
<form string="Config Wizard Steps">
<group colspan="4" col="6">
<field name="action_id"/>
<field name="restart"/>
<field name="type"/>
<field name="sequence"/>
<field name="category_id"/>
</group>
<separator string="Groups" colspan="4"/>
<field name="groups_id" nolabel="1" colspan="4"/>
@ -1925,10 +1927,17 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Actions">
<filter string="To Do" name="todo" icon="terp-camera_test" domain=" ['|',('state','=','open'),'&amp;',('state','=','skip'),('restart','=','onskip')]" help="Todo State Or (Skip State And Onskip Restart)"/>
<separator orientation="vertical"/>
<field name="state"/>
<field name="restart"/>
<group>
<filter string="To Do" name="todo" icon="terp-camera_test" domain=" [('state','=','open')]" help="Wizards to be Launched"/>
<separator orientation="vertical"/>
<field name="action_id"/>
<field name="category_id"/>
<field name="state"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Category" context="{'group_by': 'category_id'}" icon="terp-folder-orange"/>
</group>
</search>
</field>
</record>
@ -1943,7 +1952,7 @@
<menuitem id="next_id_11" name="Configuration Wizards" parent="base.menu_config" sequence="1"/>
<menuitem action="act_ir_actions_todo_form" id="menu_ir_actions_todo_form"
parent="next_id_11" groups="base.group_extended" sequence="20"/>
parent="next_id_11" sequence="20"/>
@ -1958,6 +1967,41 @@
<field name="function">power_on</field>
<field name="args">()</field>
</record>
<record id="ir_actions_todo_category_form" model="ir.ui.view">
<field name="name">ir.actions.todo.category.form</field>
<field name="model">ir.actions.todo.category</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Wizard Category">
<field name="name"/>
<field name="sequence"/>
<field name="wizards_ids" nolabel="1" colspan="4"/>
</form>
</field>
</record>
<record id="ir_actions_todo_category_tree" model="ir.ui.view">
<field name="name">ir.actions.todo.category.tree</field>
<field name="model">ir.actions.todo.category</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Wizard Category">
<field name="name"/>
<field name="sequence"/>
</tree>
</field>
</record>
<record id="category_sales_management_config" model="ir.actions.todo.category">
<field name="name">Sales Management</field>
<field name="sequence">5</field>
</record>
<record id="category_tools_customization_config" model="ir.actions.todo.category">
<field name="name">Tools / Customization</field>
<field name="sequence">5</field>
</record>
</data>
</openerp>

View File

@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2004-2011 OpenERP S.A. <http://www.openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -800,6 +800,20 @@ class act_window_close(osv.osv):
}
act_window_close()
class ir_actions_todo_category(osv.osv):
"""
Category of Configuration Wizards
"""
_name = 'ir.actions.todo.category'
_description = "Configuration Wizard Category"
_columns = {
'name':fields.char('Name', size=64, translate=True, required=True),
'sequence': fields.integer('Sequence'),
'wizards_ids': fields.one2many('ir.actions.todo', 'category_id', 'Configuration Wizards'),
}
ir_actions_todo_category()
# This model use to register action services.
TODO_STATES = [('open', 'To Do'),
('done', 'Done'),
@ -807,22 +821,30 @@ TODO_STATES = [('open', 'To Do'),
('cancel','Cancelled')]
class ir_actions_todo(osv.osv):
"""
Configuration Wizards
"""
_name = 'ir.actions.todo'
_description = "Configuration Wizards"
_columns={
'action_id': fields.many2one(
'ir.actions.act_window', 'Action', select=True, required=True,
ondelete='cascade'),
'sequence': fields.integer('Sequence'),
'state': fields.selection(TODO_STATES, string='State', required=True),
'name':fields.char('Name', size=64),
'restart': fields.selection([('onskip','On Skip'),('always','Always'),('never','Never')],'Restart',required=True),
'groups_id':fields.many2many('res.groups', 'res_groups_action_rel', 'uid', 'gid', 'Groups'),
'note':fields.text('Text', translate=True),
'name': fields.char('Name', size=64),
'type': fields.selection([('special','Special'),('normal','Normal'),('normal_recurring','Normal Recurring')], 'Type', required=True,
help="""Special: the wizard is run whenever the system is reconfigured.
Normal: the wizard is visible in the configuration panel until it is done.
Normal Recurring: the wizard is visible in the configuration panel regardless of its state."""),
'groups_id': fields.many2many('res.groups', 'res_groups_action_rel', 'uid', 'gid', 'Groups'),
'note': fields.text('Text', translate=True),
'category_id': fields.many2one('ir.actions.todo.category','Category'),
}
_defaults={
'state': 'open',
'sequence': 10,
'restart': 'onskip',
'type': 'special',
}
_order="sequence,name,id"
@ -832,8 +854,16 @@ class ir_actions_todo(osv.osv):
context = {}
wizard_id = ids and ids[0] or False
wizard = self.browse(cr, uid, wizard_id, context=context)
res = self.pool.get('ir.actions.act_window').read(cr, uid, wizard.action_id.id, ['name', 'view_type', 'view_mode', 'res_model', 'context', 'views', 'type'], context=context)
res.update({'target':'new', 'nodestroy': True})
res = self.pool.get('ir.actions.act_window').read(cr, uid, wizard.action_id.id, [], context=context)
res.update({'nodestroy': True})
# Open a specific record when res_id is provided in the context
if res.get('context'):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
ctx = eval(res['context'], {'user': user})
if ctx.get('res_id'):
res.update({'res_id': ctx.pop('res_id')})
res.update({'context': ctx})
return res
def action_open(self, cr, uid, ids, context=None):

View File

@ -40,6 +40,16 @@ from tools.translate import _
from osv import fields, osv, orm
ACTION_DICT = {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'base.module.upgrade',
'target': 'new',
'type': 'ir.actions.act_window',
'nodestroy':True,
}
class module_category(osv.osv):
_name = "ir.module.category"
_description = "Module Category"
@ -285,7 +295,9 @@ class module(osv.osv):
return demo
def button_install(self, cr, uid, ids, context=None):
return self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context)
self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context)
return dict(ACTION_DICT, name=_('Install'))
def button_install_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'uninstalled', 'demo':False})
@ -305,7 +317,7 @@ class module(osv.osv):
if res:
raise orm.except_orm(_('Error'), _('Some installed modules depend on the module you plan to Uninstall :\n %s') % '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res)))
self.write(cr, uid, ids, {'state': 'to remove'})
return True
return dict(ACTION_DICT, name=_('Uninstall'))
def button_uninstall_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'installed'})
@ -342,11 +354,12 @@ class module(osv.osv):
to_install.extend(ids2)
self.button_install(cr, uid, to_install, context=context)
return True
return dict(ACTION_DICT, name=_('Upgrade'))
def button_upgrade_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'installed'})
return True
def button_update_translations(self, cr, uid, ids, context=None):
self.update_translations(cr, uid, ids)
return True

View File

@ -110,9 +110,9 @@
<separator string="Description" colspan="4"/>
<field colspan="4" name="description" select="2" nolabel="1"/>
<newline/>
<field name="state" readonly="1" select="1"/>
<field name="state"/>
<group col="6" colspan="2">
<button name="button_install" states="uninstalled" string="Schedule for Installation" icon="terp-gtk-jump-to-ltr" type="object"/>
<button name="button_install" states="uninstalled" string="Install" icon="terp-gtk-jump-to-ltr" type="object"/>
<button name="button_install_cancel" states="to install" string="Cancel Install" icon="gtk-cancel" type="object"/>
<button name="button_uninstall" states="installed" string="Uninstall (beta)" icon="terp-dialog-close" type="object"/>
<button name="button_uninstall_cancel" states="to remove" string="Cancel Uninstall" icon="gtk-cancel" type="object"/>
@ -153,9 +153,9 @@
<field name="installed_version"/>
<field name="latest_version"/>
<field name="state"/>
<button name="button_install" states="uninstalled" string="Schedule for Installation" icon="terp-gtk-jump-to-ltr" type="object"/>
<button name="button_install" states="uninstalled" string="Install" icon="terp-gtk-jump-to-ltr" type="object"/>
<button name="button_install_cancel" states="to install" string="Cancel Install" icon="gtk-cancel" type="object"/>
<button name="button_upgrade" states="installed" string="Schedule Upgrade" icon="terp-gtk-go-back-rtl" type="object"/>
<button name="button_upgrade" states="installed" string="Upgrade" icon="terp-gtk-go-back-rtl" type="object"/>
<button name="button_uninstall" states="installed" string="Uninstall (beta)" icon="terp-dialog-close" type="object"/>
<button name="button_uninstall_cancel" states="to remove" string="Cancel Uninstall" icon="gtk-cancel" type="object"/>
<button name="button_upgrade_cancel" states="to upgrade" string="Cancel Upgrade" icon="gtk-cancel" type="object"/>
@ -169,7 +169,7 @@
<field name="view_mode">tree,form</field>
<field name="domain"/>
<field name="search_view_id" ref="view_module_filter"/>
<field name="help">You can install new modules in order to activate new features, menu, reports or data in your OpenERP instance. To install some modules, click on the button "Schedule for Installation" from the form view, then click on "Apply Scheduled Upgrades" to migrate your system.</field>
<field name="help">You can install new modules in order to activate new features, menu, reports or data in your OpenERP instance. To install some modules, click on the button "Install" from the form view and then click on "Start Upgrade".</field>
</record>
<menuitem action="open_module_tree" id="menu_module_tree" parent="base.menu_management"/>

View File

@ -27,7 +27,7 @@ class base_module_configuration(osv.osv_memory):
_name = "base.module.configuration"
def start(self, cr, uid, ids, context=None):
todo_ids = self.pool.get('ir.actions.todo').search(cr, uid, ['|', '|', ('restart','=','always'), ('state', '=', 'open'), '&', ('state', '=', 'skip'), ('restart', '=', 'onskip')])
todo_ids = self.pool.get('ir.actions.todo').search(cr, uid, ['|', '|', ('type','=','normal_recurring'), ('state', '=', 'open'), '&', ('state', '=', 'skip'), ('type', '=', 'special')])
if not todo_ids:
# When there is no wizard todo it will display message
data_obj = self.pool.get('ir.model.data')

View File

@ -24,7 +24,7 @@
<field name="code">action = obj.start()</field>
</record>
<menuitem name="Reconfigure"
<menuitem name="Add More Features"
action="action_start_configurator"
id="menu_view_base_module_configuration" parent="base.menu_config"
type="server" icon="STOCK_EXECUTE" sequence="100" />

View File

@ -3,7 +3,7 @@
<data noupdate="1">
<record id="ir_ui_view_sc_configuration" model="ir.ui.view_sc">
<field name="name">Reconfigure</field>
<field name="name">Add More Features</field>
<field name="resource">ir.ui.menu</field>
<field name="user_id" ref="base.user_root"/>
<field name="res_id" ref="menu_view_base_module_configuration"/>

View File

@ -36,7 +36,7 @@
id="menu_view_base_module_upgrade"
parent="menu_management"
sequence="3"/>
<act_window id="action_view_base_module_upgrade_window"
key2="client_action_multi" name="Apply Scheduled Upgrades"
res_model="base.module.upgrade" src_model="ir.module.module"

View File

@ -0,0 +1 @@
import preview_report

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2011 OpenERP S.A. <http://www.openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from report import report_sxw
class rmlparser(report_sxw.rml_parse):
def set_context(self, objects, data, ids, report_type = None):
super(rmlparser,self).set_context(objects, data, ids, report_type)
self.setCompany(objects[0])
report_sxw.report_sxw('report.preview.report', 'res.company',
'addons/base/report/preview_report.rml', parser=rmlparser, header='external')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<document filename="preview_report.pdf">
<template pageSize="(595.0,842.0)" title="Preview Report" author="OpenERP S.A.(sales@openerp.com)" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="57.0" y1="57.0" width="481" height="728"/>
</pageTemplate>
</template>
<story>
<para>
</para>
</story>
</document>

View File

@ -3,7 +3,9 @@
<data>
<menuitem icon="terp-partner" id="menu_base_partner" name="Sales" sequence="0"
web_icon="data/sales.png"
web_icon_hover="data/sales-hover.png"/>
web_icon_hover="data/sales-hover.png"
groups="base.group_sale_salesman"/>
<menuitem id="menu_address_book" name="Address Book" parent="menu_base_partner" sequence="2"/>

View File

@ -68,11 +68,40 @@ class multi_company_default(osv.osv):
multi_company_default()
class res_company(osv.osv):
_name = "res.company"
_description = 'Companies'
_order = 'name'
def _get_address_data(self, cr, uid, ids, field_names, arg, context=None):
""" Read the 'address' functional fields. """
result = {}
part_obj = self.pool.get('res.partner')
address_obj = self.pool.get('res.partner.address')
for company in self.browse(cr, uid, ids, context=context):
result[company.id] = {}.fromkeys(field_names, False)
if company.partner_id:
address_data = part_obj.address_get(cr, uid, [company.partner_id.id], adr_pref=['default'])
if address_data['default']:
address = address_obj.read(cr, uid, address_data['default'], field_names, context=context)
for field in field_names:
result[company.id][field] = address[field] or False
return result
def _set_address_data(self, cr, uid, company_id, name, value, arg, context=None):
""" Write the 'address' functional fields. """
company = self.browse(cr, uid, company_id, context=context)
if company.partner_id:
part_obj = self.pool.get('res.partner')
address_obj = self.pool.get('res.partner.address')
address_data = part_obj.address_get(cr, uid, [company.partner_id.id], adr_pref=['default'])
address = address_data['default']
if address:
address_obj.write(cr, uid, [address], {name: value or False})
else:
address_obj.create(cr, uid, {name: value or False, 'partner_id': company.partner_id.id}, context=context)
return True
_columns = {
'name': fields.char('Company Name', size=64, required=True),
'parent_id': fields.many2one('res.company', 'Parent Company', select=True),
@ -81,14 +110,22 @@ class res_company(osv.osv):
'rml_header1': fields.char('Report Header', size=200),
'rml_footer1': fields.char('Report Footer 1', size=200),
'rml_footer2': fields.char('Report Footer 2', size=200),
'rml_header' : fields.text('RML Header', required=True),
'rml_header2' : fields.text('RML Internal Header', required=True),
'rml_header3' : fields.text('RML Internal Header', required=True),
'logo' : fields.binary('Logo'),
'rml_header': fields.text('RML Header', required=True),
'rml_header2': fields.text('RML Internal Header', required=True),
'rml_header3': fields.text('RML Internal Header', required=True),
'logo': fields.binary('Logo'),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'),
'user_ids': fields.many2many('res.users', 'res_company_users_rel', 'cid', 'user_id', 'Accepted Users'),
'account_no':fields.char('Account No.', size=64),
'street': fields.function(_get_address_data, fnct_inv=_set_address_data, size=128, type='char', string="Street", multi='address'),
'street2': fields.function(_get_address_data, fnct_inv=_set_address_data, size=128, type='char', string="Street2", multi='address'),
'zip': fields.function(_get_address_data, fnct_inv=_set_address_data, size=24, type='char', string="Zip", multi='address'),
'city': fields.function(_get_address_data, fnct_inv=_set_address_data, size=24, type='char', string="City", multi='address'),
'state_id': fields.function(_get_address_data, fnct_inv=_set_address_data, type='many2one', domain="[('country_id', '=', country_id)]", relation='res.country.state', string="State", multi='address'),
'country_id': fields.function(_get_address_data, fnct_inv=_set_address_data, type='many2one', relation='res.country', string="Country", multi='address'),
'email': fields.function(_get_address_data, fnct_inv=_set_address_data, size=64, type='char', string="Email", multi='address'),
'phone': fields.function(_get_address_data, fnct_inv=_set_address_data, size=64, type='char', string="Phone", multi='address'),
}
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
@ -263,6 +300,7 @@ class res_company(osv.osv):
(osv.osv._check_recursion, 'Error! You can not create recursive companies.', ['parent_id'])
]
res_company()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -44,10 +44,9 @@ class res_config_configurable(osv.osv_memory):
'''Return a description the current progress of configuration:
a tuple of (non_open_todos:int, total_todos: int)
'''
return (self.pool.get('ir.actions.todo')\
.search_count(cr, uid, [('state','<>','open')], context),
self.pool.get('ir.actions.todo')\
.search_count(cr, uid, [], context))
todo_pool = self.pool.get('ir.actions.todo')
return (todo_pool.search_count(cr, uid, [('state','<>','open')], context),
todo_pool.search_count(cr, uid, [], context))
def _progress(self, cr, uid, context=None):
closed, total = self.get_current_progress(cr, uid, context=context)
@ -66,6 +65,7 @@ class res_config_configurable(osv.osv_memory):
def _next_action(self, cr, uid, context=None):
todos = self.pool.get('ir.actions.todo')
self.__logger.info('getting next %s', todos)
# Don't forget to change the domain in search view, if this condition is changed
active_todos = todos.search(cr, uid, [('state','=','open')],
limit=1)
if active_todos:
@ -76,7 +76,13 @@ class res_config_configurable(osv.osv_memory):
cr.execute("select 1 from res_groups_users_rel where uid=%s and gid IN %s",(uid, tuple(todo_groups),))
dont_skip_todo = bool(cr.fetchone())
if dont_skip_todo:
return todos.browse(cr, uid, active_todos[0], context=None)
res = todos.browse(cr, uid, active_todos[0], context=None)
# A wizard opening directly a form instead of calling
# next_action will remain in the todo state so we set it to
# done ourselves.
if res.action_id.target == 'current':
res.write({'state': 'done'})
return res
else:
todos.write(cr, uid, active_todos[0], {'state':'skip'}, context=None)
return self._next_action(cr, uid)
@ -100,27 +106,20 @@ class res_config_configurable(osv.osv_memory):
next = self._next_action(cr, uid)
self.__logger.info('next action is %s', next)
if next:
action = next.action_id
return {
'view_mode': action.view_mode,
'view_type': action.view_type,
'view_id': (action.view_id.id, 'Next Setup Action') if action.view_id else False,
'res_model': action.res_model,
'type': action.type,
'target': action.target,
}
res = next.action_launch(context=context)
res.update({'nodestroy': False})
return res
self.__logger.info('all configuration actions have been executed')
current_user_menu = self.pool.get('res.users')\
.browse(cr, uid, uid).menu_id
current_user_menu = self.pool.get('res.users').browse(cr, uid, uid).menu_id
# return the action associated with the menu
return self.pool.get(current_user_menu.type)\
.read(cr, uid, current_user_menu.id)
return self.pool.get(current_user_menu.type).read(cr, uid, current_user_menu.id)
def start(self, cr, uid, ids, context=None):
ids2 = self.pool.get('ir.actions.todo').search(cr, uid, [], context=context)
for todo in self.pool.get('ir.actions.todo').browse(cr, uid, ids2, context=context):
if (todo.restart=='always') or (todo.restart=='onskip' and (todo.state in ('skip','cancel'))):
todo_pool = self.pool.get('ir.actions.todo')
ids2 = todo_pool.search(cr, uid, [], context=context)
for todo in todo_pool.browse(cr, uid, ids2, context=context):
if (todo.type=='normal_recurring'):
todo.write({'state':'open'})
return self.next(cr, uid, ids, context)

View File

@ -21,6 +21,7 @@
import time
import netsvc
from osv import fields, osv
import tools
from tools.misc import currency
from tools.translate import _
@ -77,6 +78,14 @@ class res_currency(osv.osv):
r['date'] = currency_date
return res
def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
if isinstance(ids, (int, long)):
ids = [ids]
reads = self.read(cr, uid, ids, ['name','symbol'], context=context, load='_classic_write')
return [(x['id'], tools.ustr(x['name']) + (x['symbol'] and (' (' + tools.ustr(x['symbol']) + ')') or '')) for x in reads]
def round(self, cr, uid, currency, amount):
if currency.rounding == 0:
return 0.0

View File

@ -240,14 +240,13 @@ class users(osv.osv):
'company_ids':fields.many2many('res.company','res_company_users_rel','user_id','cid','Companies'),
'context_lang': fields.selection(_lang_get, 'Language', required=True,
help="Sets the language for the user's user interface, when UI "
"translations are available"),
help="The default language used in the graphical user interface, when translations are available. To add a new language, you can use the 'Load an Official Translation' wizard available from the 'Administration' menu."),
'context_tz': fields.selection(_tz_get, 'Timezone', size=64,
help="The user's timezone, used to perform timezone conversions "
"between the server and the client."),
'view': fields.function(_get_interface_type, method=True, type='selection', fnct_inv=_set_interface_type,
selection=[('simple','Simplified'),('extended','Extended')],
string='Interface', help="Choose between the simplified interface and the extended one"),
string='Interface', help="OpenERP offers a simplified and an extended user interface. If you use OpenERP for the first time we strongly advise you to select the simplified interface, which has less features but is easier to use. You can switch to the other interface from the User/Preferences menu at any time."),
'user_email': fields.function(_email_get, method=True, fnct_inv=_email_set, string='Email', type="char", size=240),
'menu_tips': fields.boolean('Menu Tips', help="Check out this box if you want to always display tips on each menu action"),
'date': fields.datetime('Last Connection', readonly=True),
@ -511,62 +510,6 @@ class users(osv.osv):
users()
class config_users(osv.osv_memory):
_name = 'res.config.users'
_inherit = ['res.users', 'res.config']
def _generate_signature(self, cr, name, email, context=None):
return _('--\n%(name)s %(email)s\n') % {
'name': name or '',
'email': email and ' <'+email+'>' or '',
}
def create_user(self, cr, uid, new_id, context=None):
""" create a new res.user instance from the data stored
in the current res.config.users.
If an email address was filled in for the user, sends a mail
composed of the return values of ``get_welcome_mail_subject``
and ``get_welcome_mail_body`` (which should be unicode values),
with the user's data %-formatted into the mail body
"""
base_data = self.read(cr, uid, new_id, context=context)
partner_id = self.pool.get('res.partner').main_partner(cr, uid)
address = self.pool.get('res.partner.address').create(
cr, uid, {'name': base_data['name'],
'email': base_data['email'],
'partner_id': partner_id,},
context)
# Change the read many2one values from (id,name) to id, and
# the one2many from ids to (6,0,ids).
base_data.update({'menu_id' : base_data.get('menu_id') and base_data['menu_id'][0],
'company_id' : base_data.get('company_id') and base_data['company_id'][0],
'action_id' : base_data.get('action_id') and base_data['action_id'][0],
'signature' : self._generate_signature(cr, base_data['name'], base_data['email'], context=context),
'address_id' : address,
'groups_id' : [(6,0, base_data.get('groups_id',[]))],
})
new_user = self.pool.get('res.users').create(
cr, uid, base_data, context)
self.send_welcome_email(cr, uid, new_user, context=context)
def execute(self, cr, uid, ids, context=None):
'Do nothing on execution, just launch the next action/todo'
pass
def action_add(self, cr, uid, ids, context=None):
'Create a user, and re-display the view'
self.create_user(cr, uid, ids[0], context=context)
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'res.config.users',
'view_id':self.pool.get('ir.ui.view')\
.search(cr,uid,[('name','=','res.config.users.confirm.form')]),
'type': 'ir.actions.act_window',
'target':'new',
}
config_users()
class groups2(osv.osv): ##FIXME: Is there a reason to inherit this object ?
_inherit = 'res.groups'
_columns = {

View File

@ -29,12 +29,13 @@
<field name="name">Useability / No One</field>
</record>
<record id="group_sale_manager" model="res.groups">
<record id="group_sale_manager" context="{'noadmin':True}" model="res.groups">
<field name="name">Sales / Manager</field>
</record>
<record id="group_sale_salesman" model="res.groups">
<record id="group_sale_salesman" context="{'noadmin':True}" model="res.groups">
<field name="name">Sales / User</field>
</record>
<!-- Set accesses to menu -->
<record model="ir.ui.menu" id="base.menu_administration">
<field name="groups_id" eval="[(6,0, [ref('group_system'), ref('group_erp_manager')])]"/>

View File

@ -125,3 +125,4 @@
"access_res_widget_user","res.widget.user","model_res_widget",,1,0,0,0
"access_res_log_all","res.log","model_res_log",,1,1,1,1
"access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0
"access_ir_actions_todo_category","ir_actions_todo_category","model_ir_actions_todo_category","group_system",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
125 access_res_widget_user res.widget.user model_res_widget 1 0 0 0
126 access_res_log_all res.log model_res_log 1 1 1 1
127 access_ir_config_parameter ir_config_parameter model_ir_config_parameter 1 0 0 0
128 access_ir_actions_todo_category ir_actions_todo_category model_ir_actions_todo_category group_system 1 1 1 1

View File

@ -1,11 +0,0 @@
-
I Create "test" user using configuration wizard.
-
!python {model: res.config.users}: |
defaults = {
'name' : 'test1',
'login' : 'test1',
'password' : 'test',
}
wizard_id = self.create(cr, uid, defaults)
self.action_add(cr, uid, [wizard_id], context)