[MERGE] forward port of branch saas-3 up to revid 5060 chs@openerp.com-20140206131116-we6rlic5fu09xh8q
bzr revid: chs@openerp.com-20140206131219-9rpwsfe9vc7uf0cr
This commit is contained in:
commit
9289a2608d
|
@ -13,6 +13,7 @@ from openerp.osv import orm
|
|||
from openerp.tools.translate import _
|
||||
from openerp.tools.misc import DEFAULT_SERVER_DATE_FORMAT,\
|
||||
DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.tools import html_sanitize
|
||||
|
||||
REFERENCING_FIELDS = set([None, 'id', '.id'])
|
||||
def only_ref_fields(record):
|
||||
|
@ -188,7 +189,7 @@ class ir_fields_converter(orm.Model):
|
|||
|
||||
def _str_id(self, cr, uid, model, column, value, context=None):
|
||||
return value, []
|
||||
_str_to_reference = _str_to_char = _str_to_text = _str_to_binary = _str_id
|
||||
_str_to_reference = _str_to_char = _str_to_text = _str_to_binary = _str_to_html = _str_id
|
||||
|
||||
def _str_to_date(self, cr, uid, model, column, value, context=None):
|
||||
try:
|
||||
|
|
|
@ -337,7 +337,7 @@ class view(osv.osv):
|
|||
if isinstance(spec, SKIPPED_ELEMENT_TYPES):
|
||||
continue
|
||||
if spec.tag == 'data':
|
||||
specs += [ c for c in specs_tree ]
|
||||
specs += [c for c in spec]
|
||||
continue
|
||||
node = self.locate_node(source, spec)
|
||||
if node is not None:
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
<form string="Partners" version="7.0">
|
||||
<sheet>
|
||||
<field name="image" widget='image' class="oe_left oe_avatar" options='{"preview_image": "image_medium", "size": [90, 90]}'/>
|
||||
<div class="oe_title">
|
||||
<div class="oe_title oe_left">
|
||||
<div class="oe_edit_only">
|
||||
<label for="name"/> (
|
||||
<field name="is_company" on_change="onchange_type(is_company)" class="oe_inline"/> <label for="is_company" string="Is a Company?"/>)
|
||||
|
|
|
@ -8,6 +8,7 @@ class test_base(common.TransactionCase):
|
|||
def setUp(self):
|
||||
super(test_base,self).setUp()
|
||||
self.res_partner = self.registry('res.partner')
|
||||
self.res_users = self.registry('res.users')
|
||||
|
||||
# samples use effective TLDs from the Mozilla public suffix
|
||||
# list at http://publicsuffix.org
|
||||
|
@ -282,6 +283,21 @@ class test_base(common.TransactionCase):
|
|||
p0.refresh()
|
||||
self.assertEquals(p0.vat, sunhelmvat2, 'Commercial fields must be automatically synced')
|
||||
|
||||
def test_60_read_group(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
for user_data in [
|
||||
{'name': 'Alice', 'login': 'alice', 'color': 1, 'function': 'Friend'},
|
||||
{'name': 'Bob', 'login': 'bob', 'color': 2, 'function': 'Friend'},
|
||||
{'name': 'Eve', 'login': 'eve', 'color': 3, 'function': 'Eavesdropper'},
|
||||
]:
|
||||
self.res_users.create(cr, uid, user_data)
|
||||
|
||||
groups_data = self.res_users.read_group(cr, uid, domain=[('login', 'in', ('alice', 'bob', 'eve'))], fields=['name', 'color', 'function'], groupby='function')
|
||||
self.assertEqual(len(groups_data), 2, "Incorrect number of results when grouping on a field")
|
||||
for group_data in groups_data:
|
||||
self.assertIn('color', group_data, "Aggregated data for the column 'color' is not present in read_group return values")
|
||||
self.assertEqual(group_data['color'], 3, "Incorrect sum for aggregated data for the column 'color'")
|
||||
|
||||
class test_partner_recursion(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -208,7 +208,7 @@ class WebRequest(object):
|
|||
args = (request,) + args
|
||||
# Correct exception handling and concurency retry
|
||||
@service_model.check
|
||||
def checked_call(dbname, *a, **kw):
|
||||
def checked_call(___dbname, *a, **kw):
|
||||
return self.func(*a, **kw)
|
||||
|
||||
# FIXME: code and rollback management could be cleaned
|
||||
|
@ -832,6 +832,40 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
|
|||
|
||||
return Model(self, model)
|
||||
|
||||
def save_action(self, action):
|
||||
"""
|
||||
This method store an action object in the session and returns an integer
|
||||
identifying that action. The method get_action() can be used to get
|
||||
back the action.
|
||||
|
||||
:param the_action: The action to save in the session.
|
||||
:type the_action: anything
|
||||
:return: A key identifying the saved action.
|
||||
:rtype: integer
|
||||
"""
|
||||
saved_actions = self.setdefault('saved_actions', {"next": 1, "actions": {}})
|
||||
# we don't allow more than 10 stored actions
|
||||
if len(saved_actions["actions"]) >= 10:
|
||||
del saved_actions["actions"][min(saved_actions["actions"])]
|
||||
key = saved_actions["next"]
|
||||
saved_actions["actions"][key] = action
|
||||
saved_actions["next"] = key + 1
|
||||
self.modified = True
|
||||
return key
|
||||
|
||||
def get_action(self, key):
|
||||
"""
|
||||
Gets back a previously saved action. This method can return None if the action
|
||||
was saved since too much time (this case should be handled in a smart way).
|
||||
|
||||
:param key: The key given by save_action()
|
||||
:type key: integer
|
||||
:return: The saved action or None.
|
||||
:rtype: anything
|
||||
"""
|
||||
saved_actions = self.get('saved_actions', {})
|
||||
return saved_actions.get("actions", {}).get(key)
|
||||
|
||||
def session_gc(session_store):
|
||||
if random.random() < 0.001:
|
||||
# we keep session one week
|
||||
|
@ -973,7 +1007,10 @@ class Root(object):
|
|||
def setup_db(self, httprequest):
|
||||
db = httprequest.session.db
|
||||
# Check if session.db is legit
|
||||
if db and db not in db_filter([db], httprequest=httprequest):
|
||||
if db:
|
||||
if db not in db_filter([db], httprequest=httprequest):
|
||||
_logger.warn("Logged into database '%s', but dbfilter "
|
||||
"rejects it; logging session out.", db)
|
||||
httprequest.session.logout()
|
||||
db = None
|
||||
|
||||
|
|
|
@ -2293,12 +2293,12 @@ class BaseModel(object):
|
|||
f for f in fields
|
||||
if f not in ('id', 'sequence')
|
||||
if fget[f]['type'] in ('integer', 'float')
|
||||
if (f in self._columns and getattr(self._columns[f], '_classic_write'))]
|
||||
if (f in self._all_columns and getattr(self._all_columns[f].column, '_classic_write'))]
|
||||
for f in aggregated_fields:
|
||||
group_operator = fget[f].get('group_operator', 'sum')
|
||||
if flist:
|
||||
flist += ', '
|
||||
qualified_field = '"%s"."%s"' % (self._table, f)
|
||||
qualified_field = self._inherits_join_calc(f, query)
|
||||
flist += "%s(%s) AS %s" % (group_operator, qualified_field, f)
|
||||
|
||||
gb = groupby and (' GROUP BY ' + qualified_groupby_field) or ''
|
||||
|
|
|
@ -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~3', 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]))
|
||||
|
||||
|
|
|
@ -40,9 +40,10 @@ def dispatch(method, params):
|
|||
|
||||
def check(f):
|
||||
@wraps(f)
|
||||
def wrapper(dbname, *args, **kwargs):
|
||||
def wrapper(___dbname, *args, **kwargs):
|
||||
""" Wraps around OSV functions and normalises a few exceptions
|
||||
"""
|
||||
dbname = ___dbname # NOTE: this forbid to use "___dbname" as arguments in http routes
|
||||
|
||||
def tr(src, ttype):
|
||||
# We try to do the same as the _(), but without the frame
|
||||
|
|
|
@ -67,7 +67,8 @@ _SAFE_OPCODES = _EXPR_OPCODES.union(set(opmap[x] for x in [
|
|||
'LOAD_NAME', 'CALL_FUNCTION', 'COMPARE_OP', 'LOAD_ATTR',
|
||||
'STORE_NAME', 'GET_ITER', 'FOR_ITER', 'LIST_APPEND', 'DELETE_NAME',
|
||||
'JUMP_FORWARD', 'JUMP_IF_TRUE', 'JUMP_IF_FALSE', 'JUMP_ABSOLUTE',
|
||||
'MAKE_FUNCTION', 'SLICE+0', 'SLICE+1', 'SLICE+2', 'SLICE+3',
|
||||
'MAKE_FUNCTION', 'SLICE+0', 'SLICE+1', 'SLICE+2', 'SLICE+3', 'BREAK_LOOP',
|
||||
'CONTINUE_LOOP', 'RAISE_VARARGS',
|
||||
# New in Python 2.7 - http://bugs.python.org/issue4715 :
|
||||
'JUMP_IF_FALSE_OR_POP', 'JUMP_IF_TRUE_OR_POP', 'POP_JUMP_IF_FALSE',
|
||||
'POP_JUMP_IF_TRUE', 'SETUP_EXCEPT', 'END_FINALLY'
|
||||
|
|
|
@ -172,7 +172,7 @@ class GettextAlias(object):
|
|||
cr = getattr(s, 'cr', None)
|
||||
if not cr and allow_create:
|
||||
db = self._get_db()
|
||||
if db:
|
||||
if db is not None:
|
||||
cr = db.cursor()
|
||||
is_new_cr = True
|
||||
return cr, is_new_cr
|
||||
|
|
|
@ -101,11 +101,11 @@ def run(args):
|
|||
import openerp
|
||||
|
||||
config = openerp.tools.config
|
||||
config.load()
|
||||
|
||||
config['db_name'] = args.database
|
||||
if args.port:
|
||||
config['xmlrpc_port'] = int(args.port)
|
||||
config['admin_passwd'] = 'admin'
|
||||
config['db_password'] = 'a2aevl8w' # TODO from .openerpserverrc
|
||||
|
||||
if args.addons:
|
||||
args.addons = args.addons.replace(':',',').split(',')
|
||||
|
|
Loading…
Reference in New Issue