[MERGE] [FORWARD] Forward-port of saas-1 branch until revision 4875

Revision ID: qdp-launchpad@openerp.com-20130507120149-p2m4ug20nfny234v

bzr revid: tde@openerp.com-20130522102240-ysni935cvnfvpe40
This commit is contained in:
Thibault Delavallée 2013-05-22 12:22:40 +02:00
commit 218024570d
12 changed files with 82 additions and 64 deletions

View File

@ -299,8 +299,33 @@ class ir_ui_menu(osv.osv):
- the needaction counter of the related action, taking into account
the action domain
"""
if context is None:
context = {}
res = {}
menu_ids = set()
for menu in self.browse(cr, uid, ids, context=context):
menu_ids.add(menu.id)
ctx = None
if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.context:
try:
# use magical UnquoteEvalContext to ignore undefined client-side variables such as `active_id`
eval_ctx = tools.UnquoteEvalContext(**context)
ctx = eval(menu.action.context, locals_dict=eval_ctx, nocopy=True) or None
except Exception:
# if the eval still fails for some reason, we'll simply skip this menu
pass
menu_ref = ctx and ctx.get('needaction_menu_ref')
if menu_ref:
if not isinstance(menu_ref, list):
menu_ref = [menu_ref]
model_data_obj = self.pool.get('ir.model.data')
for menu_data in menu_ref:
model, id = model_data_obj.get_object_reference(cr, uid, menu_data.split('.')[0], menu_data.split('.')[1])
if (model == 'ir.ui.menu'):
menu_ids.add(id)
menu_ids = list(menu_ids)
for menu in self.browse(cr, uid, menu_ids, context=context):
res[menu.id] = {
'needaction_enabled': False,
'needaction_counter': False,

View File

@ -30,7 +30,11 @@ from openerp.tools.translate import _
CURRENCY_DISPLAY_PATTERN = re.compile(r'(\w+)\s*(?:\((.*)\))?')
class res_currency(osv.osv):
def _current_rate(self, cr, uid, ids, name, arg, context=None):
return self._get_current_rate(cr, uid, ids, name, arg, context=context)
def _get_current_rate(self, cr, uid, ids, name, arg, context=None):
if context is None:
context = {}
res = {}

View File

@ -446,7 +446,7 @@ class res_partner(osv.osv, format_address):
commercial_fields = self._commercial_fields(cr, uid, context=context)
sync_vals = self._update_fields_values(cr, uid, partner.commercial_partner_id,
commercial_fields, context=context)
return self.write(cr, uid, partner.id, sync_vals, context=context)
partner.write(sync_vals)
def _commercial_sync_to_children(self, cr, uid, partner, context=None):
""" Handle sync of commercial fields to descendants """
@ -462,7 +462,7 @@ class res_partner(osv.osv, format_address):
""" Sync commercial fields and address fields from company and to children after create/update,
just as if those were all modeled as fields.related to the parent """
# 1. From UPSTREAM: sync from parent
if update_values.get('parent_id') or update_values.get('use_company_address'):
if update_values.get('parent_id') or update_values.get('use_parent_address'):
# 1a. Commercial fields: sync if parent changed
if update_values.get('parent_id'):
self._commercial_sync_from_company(cr, uid, partner, context=context)
@ -472,7 +472,7 @@ class res_partner(osv.osv, format_address):
use_parent_address=partner.use_parent_address,
parent_id=partner.parent_id.id,
context=context).get('value', {})
self.update_address(cr, uid, partner.id, onchange_vals, context=context)
partner.update_address(onchange_vals)
# 2. To DOWNSTREAM: sync children
if partner.child_ids:

View File

@ -157,8 +157,8 @@
<div>
<field name="use_parent_address" class="oe_edit_only oe_inline"
on_change="onchange_address(use_parent_address, parent_id)"
attrs="{'invisible': [('parent_id','=', False)]}"/>
<label for="use_parent_address" class="oe_edit_only" attrs="{'invisible': [('parent_id','=', False)]}"/>
attrs="{'invisible': [('parent_id','=', False),('use_parent_address','=',False)]}"/>
<label for="use_parent_address" class="oe_edit_only" attrs="{'invisible': [('parent_id','=', False),('use_parent_address','=',False)]}"/>
<button name="open_parent" type="object" string="(edit company address)" class="oe_link oe_edit_only"
attrs="{'invisible': ['|',('parent_id','=', False),('use_parent_address','=',False)]}"/>
<field name="street" placeholder="Street..." attrs="{'readonly': [('use_parent_address','=',True)]}"/>

View File

@ -61,6 +61,24 @@ class test_base(common.TransactionCase):
self.assertEqual(p1.phone, p1phone, 'Phone should be preserved after address sync')
self.assertEqual(p1.type, 'contact', 'Type should be preserved after address sync')
self.assertEqual(p1.email, 'denis.bladesmith@ghoststep.com', 'Email should be preserved after sync')
# turn off sync
p1street = 'Different street, 42'
p1.write({'street': p1street,
'use_parent_address': False})
p1.refresh(), ghoststep.refresh()
self.assertEqual(p1.street, p1street, 'Address fields must not be synced after turning sync off')
self.assertNotEqual(ghoststep.street, p1street, 'Parent address must never be touched')
# turn on sync again
p1.write({'use_parent_address': True})
p1.refresh()
self.assertEqual(p1.street, ghoststep.street, 'Address fields must be synced again')
self.assertEqual(p1.phone, p1phone, 'Phone should be preserved after address sync')
self.assertEqual(p1.type, 'contact', 'Type should be preserved after address sync')
self.assertEqual(p1.email, 'denis.bladesmith@ghoststep.com', 'Email should be preserved after sync')
# Modify parent, sync to children
ghoststreet = 'South Street, 25'
ghoststep.write({'street': ghoststreet})
p1.refresh()

View File

@ -98,6 +98,8 @@ def preload_registry(dbname):
openerp.modules.registry.RegistryManager.new(dbname, update_module=update_module)
except Exception:
_logger.exception('Failed to initialize database `%s`.', dbname)
return False
return True
def run_test_file(dbname, test_file):
""" Preload a registry, possibly run a test file, and start the cron."""
@ -261,12 +263,14 @@ def main(args):
else:
openerp.service.start_services()
rc = 0
if config['db_name']:
for dbname in config['db_name'].split(','):
preload_registry(dbname)
if not preload_registry(dbname):
rc += 1
if config["stop_after_init"]:
sys.exit(0)
sys.exit(rc)
_logger.info('OpenERP server is running, waiting for connections...')
quit_on_signals()

View File

@ -96,10 +96,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
"""
for filename in package.data[kind]:
if kind == 'test':
_test_logger.info("module %s: loading %s", module_name, filename)
else:
_logger.info("module %s: loading %s", module_name, filename)
_logger.info("module %s: loading %s", module_name, filename)
_, ext = os.path.splitext(filename)
pathname = os.path.join(module_name, filename)
fp = tools.file_open(pathname)

View File

@ -3,7 +3,7 @@
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2010-2011 OpenERP s.a. (<http://openerp.com>).
# Copyright (C) 2010-2013 OpenERP s.a. (<http://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
@ -22,31 +22,15 @@
""" Modules migration handling. """
import os, sys, imp
import imp
import logging
import os
from os.path import join as opj
import itertools
import zipimport
import openerp
import openerp.osv as osv
import openerp.tools as tools
import openerp.tools.osutil as osutil
from openerp.tools.safe_eval import safe_eval as eval
from openerp.tools.translate import _
import zipfile
import openerp.release as release
import openerp.tools as tools
import re
import base64
from zipfile import PyZipFile, ZIP_DEFLATED
from cStringIO import StringIO
import logging
import openerp.modules.db
import openerp.modules.graph
_logger = logging.getLogger(__name__)
@ -100,9 +84,10 @@ class MigrationManager(object):
def migrate_module(self, pkg, stage):
assert stage in ('pre', 'post')
stageformat = {'pre': '[>%s]',
'post': '[%s>]',
}
stageformat = {
'pre': '[>%s]',
'post': '[%s>]',
}
if not (hasattr(pkg, 'update') or pkg.state == 'to upgrade'):
return
@ -129,9 +114,10 @@ class MigrationManager(object):
m = self.migrations[pkg.name]
lst = []
mapping = {'module': opj(pkg.name, 'migrations'),
'maintenance': opj('base', 'maintenance', 'migrations', pkg.name),
}
mapping = {
'module': opj(pkg.name, 'migrations'),
'maintenance': opj('base', 'maintenance', 'migrations', pkg.name),
}
for x in mapping.keys():
if version in m[x]:
@ -180,14 +166,14 @@ class MigrationManager(object):
try:
mod = imp.load_source(name, pyfile, fp2)
_logger.info('module %(addon)s: Running migration %(version)s %(name)s' % mergedict({'name': mod.__name__}, strfmt))
mod.migrate(self.cr, pkg.installed_version)
migrate = mod.migrate
except ImportError:
_logger.error('module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % mergedict({'file': pyfile}, strfmt))
_logger.exception('module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % mergedict({'file': pyfile}, strfmt))
raise
except AttributeError:
_logger.error('module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt)
except:
raise
else:
migrate(self.cr, pkg.installed_version)
finally:
if fp:
fp.close()

View File

@ -30,7 +30,7 @@ RELEASE_LEVELS_DISPLAY = {ALPHA: ALPHA,
# properly comparable using normal operarors, for example:
# (6,1,0,'beta',0) < (6,1,0,'candidate',1) < (6,1,0,'candidate',2)
# (6,1,0,'candidate',2) < (6,1,0,'final',0) < (6,1,2,'final',0)
version_info = (8, 0, 0, ALPHA, 1)
version_info = (7, 'saas~1', 0, FINAL, 0)
version = '.'.join(map(str, version_info[:2])) + RELEASE_LEVELS_DISPLAY[version_info[3]] + str(version_info[4] or '')
serie = major_version = '.'.join(map(str, version_info[:2]))

View File

@ -1,26 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# 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/>.
#
##############################################################################
# trml2pdf - An RML to PDF converter
# Copyright (C) 2003, Fabien Pinckaers, UCL, FSA
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@ -35,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
##############################################################################
import copy
import locale

View File

@ -25,7 +25,7 @@
import re
component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
replace = {'pre':'c', 'preview':'c','-':'final-','_':'final-','rc':'c','dev':'@'}.get
replace = {'pre':'c', 'preview':'c','-':'final-','_':'final-','rc':'c','dev':'@','saas':'','~':''}.get
def _parse_version_parts(s):
for part in component_re.split(s):

View File

@ -198,7 +198,7 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal
raise ValueError("safe_eval does not allow direct evaluation of code objects.")
if '__subclasses__' in expr:
raise ValueError('expression not allowed (__subclasses__)')
raise ValueError('expression not allowed (__subclasses__)')
if globals_dict is None:
globals_dict = {}