[MERGE] forward port of branch saas-3 up to revid 5120 chs@openerp.com-20140424125338-26k5atvtqwmmfv4e

bzr revid: chs@openerp.com-20140424131405-4oannh1102x42m8b
This commit is contained in:
Christophe Simonis 2014-04-24 15:14:05 +02:00
commit c16780df83
7 changed files with 69 additions and 22 deletions

View File

@ -20,15 +20,19 @@
##############################################################################
import collections
import copy
import datetime
import dateutil
from dateutil.relativedelta import relativedelta
import fnmatch
import logging
from lxml import etree
from operator import itemgetter
import os
import time
from operator import itemgetter
import simplejson
import werkzeug
import HTMLParser
from lxml import etree
import openerp
from openerp import tools
@ -861,6 +865,9 @@ class view(osv.osv):
request=request,
json=simplejson,
quote_plus=werkzeug.url_quote_plus,
time=time,
datetime=datetime,
relativedelta=relativedelta,
)
qcontext.update(values)

View File

@ -340,7 +340,7 @@
<separator/>
<field name="category_id" string="Tag" filter_domain="[('category_id','ilike', self)]"/>
<field name="user_id"/>
<field name="parent_id" domain="[('is_company','=',1)]" filter_domain="[('parent_id','child_of',[self])]"/>
<field name="parent_id" domain="[('is_company','=',1)]" operator="child_of"/>
<group expand="0" string="Group By...">
<filter string="Salesperson" icon="terp-personal" domain="[]" context="{'group_by' : 'user_id'}" />
<filter string="Company" context="{'group_by': 'parent_id'}"/>

View File

@ -28,7 +28,7 @@ import openerp
from openerp import SUPERUSER_ID
from openerp import tools
import openerp.exceptions
from openerp.osv import fields,osv
from openerp.osv import fields,osv, expression
from openerp.osv.orm import browse_record
from openerp.tools.translate import _
@ -56,13 +56,33 @@ class res_groups(osv.osv):
def _search_group(self, cr, uid, obj, name, args, context=None):
operand = args[0][2]
operator = args[0][1]
values = operand.split('/')
group_name = values[0]
where = [('name', operator, group_name)]
if len(values) > 1:
application_name = values[0]
group_name = values[1]
where = ['|',('category_id.name', operator, application_name)] + where
lst = True
if isinstance(operand, bool):
domains = [[('name', operator, operand)], [('category_id.name', operator, operand)]]
if operator in expression.NEGATIVE_TERM_OPERATORS == (not operand):
return expression.AND(domains)
else:
return expression.OR(domains)
if isinstance(operand, basestring):
lst = False
operand = [operand]
where = []
for group in operand:
values = filter(bool, group.split('/'))
group_name = values.pop().strip()
category_name = values and '/'.join(values).strip() or group_name
group_domain = [('name', operator, lst and [group_name] or group_name)]
category_domain = [('category_id.name', operator, lst and [category_name] or category_name)]
if operator in expression.NEGATIVE_TERM_OPERATORS and not values:
category_domain = expression.OR([category_domain, [('category_id', '=', False)]])
if (operator in expression.NEGATIVE_TERM_OPERATORS) == (not values):
sub_where = expression.AND([group_domain, category_domain])
else:
sub_where = expression.OR([group_domain, category_domain])
if operator in expression.NEGATIVE_TERM_OPERATORS:
where = expression.AND([where, sub_where])
else:
where = expression.OR([where, sub_where])
return where
_columns = {

View File

@ -302,3 +302,17 @@
float_round(0.01, precision_digits=3, precision_rounding=0.01)
except AssertionError:
pass
-
Test res.groups name search
-
!python {model: res.groups}: |
all_groups = self.search(cr, uid, [])
full_names = [(group.id, group.full_name) for group in self.browse(cr, uid, all_groups)]
group_ids = self.search(cr, uid, [('full_name', 'like', '%Sale%')])
assert set(group_ids) == set([id for (id, full_name) in full_names if 'Sale' in full_name]), "did not match search for 'Sale'"
group_ids = self.search(cr, uid, [('full_name', 'like', '%Technical%')])
assert set(group_ids) == set([id for (id, full_name) in full_names if 'Technical' in full_name]), "did not match search for 'Technical'"
group_ids = self.search(cr, uid, [('full_name', 'like', '%Sales /%')])
assert set(group_ids) == set([id for (id, full_name) in full_names if 'Sales /' in full_name]), "did not match search for 'Sales /'"
group_ids = self.search(cr, uid, [('full_name', 'in', ['Administration / Access Rights','Contact Creation'])])
assert group_ids, "did not match search for 'Administration / Access Rights' and 'Contact Creation'"

View File

@ -24,7 +24,7 @@
#-------------------------------------------------------------
to_19_fr = ( 'zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six',
to_19_fr = ( u'zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six',
'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize',
'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf' )
tens_fr = ( 'vingt', 'trente', 'quarante', 'Cinquante', 'Soixante', 'Soixante-dix', 'Quatre-vingts', 'Quatre-vingt Dix')

View File

@ -808,8 +808,8 @@ form: module.record_id""" % (xml_id,)
f_ref = field.get("ref",'').encode('utf-8')
f_search = field.get("search",'').encode('utf-8')
f_model = field.get("model",'').encode('utf-8')
if not f_model and model._columns.get(f_name,False):
f_model = model._columns[f_name]._obj
if not f_model and model._all_columns.get(f_name,False):
f_model = model._all_columns[f_name].column._obj
f_use = field.get("use",'').encode('utf-8') or 'id'
f_val = False
@ -821,9 +821,9 @@ form: module.record_id""" % (xml_id,)
# browse the objects searched
s = f_obj.browse(cr, self.uid, f_obj.search(cr, self.uid, q))
# column definitions of the "local" object
_cols = self.pool[rec_model]._columns
_cols = self.pool[rec_model]._all_columns
# if the current field is many2many
if (f_name in _cols) and _cols[f_name]._type=='many2many':
if (f_name in _cols) and _cols[f_name].column._type=='many2many':
f_val = [(6, 0, map(lambda x: x[f_use], s))]
elif len(s):
# otherwise (we are probably in a many2one field),
@ -833,17 +833,17 @@ form: module.record_id""" % (xml_id,)
if f_ref=="null":
f_val = False
else:
if f_name in model._columns \
and model._columns[f_name]._type == 'reference':
if f_name in model._all_columns \
and model._all_columns[f_name].column._type == 'reference':
val = self.model_id_get(cr, f_ref)
f_val = val[0] + ',' + str(val[1])
else:
f_val = self.id_get(cr, f_ref)
else:
f_val = _eval_xml(self,field, self.pool, cr, self.uid, self.idref)
if model._columns.has_key(f_name):
if f_name in model._all_columns:
import openerp.osv as osv
if isinstance(model._columns[f_name], osv.fields.integer):
if isinstance(model._all_columns[f_name].column, osv.fields.integer):
f_val = int(f_val)
res[f_name] = f_val

View File

@ -45,7 +45,7 @@ tags_to_kill = ["script", "head", "meta", "title", "link", "style", "frame", "if
tags_to_remove = ['html', 'body', 'font']
# allow new semantic HTML5 tags
allowed_tags = clean.defs.tags | frozenset('article section header footer hgroup nav aside figure main'.split())
allowed_tags = clean.defs.tags | frozenset('article section header footer hgroup nav aside figure main'.split() + [etree.Comment])
safe_attrs = clean.defs.safe_attrs | frozenset(
['style',
'data-oe-model', 'data-oe-id', 'data-oe-field', 'data-oe-type', 'data-oe-expression', 'data-oe-translate', 'data-oe-nodeid',
@ -70,6 +70,8 @@ def html_sanitize(src, silent=True, strict=False):
'forms': True, # remove form tags
'remove_unknown_tags': False,
'allow_tags': allowed_tags,
'comments': False,
'processing_instructions' : False
}
if etree.LXML_VERSION >= (2, 3, 1):
# kill_tags attribute has been added in version 2.3.1
@ -339,6 +341,10 @@ def html_email_clean(html, remove=False, shorten=False, max_length=300, expand_o
overlength_section_count = 0
cur_char_nbr = 0
for node in root.iter():
# comments do not need processing
# note: bug in node.get(value, default) for HtmlComments, default never returned
if node.tag == etree.Comment:
continue
# do not take into account multiple spaces that are displayed as max 1 space in html
node_text = ' '.join((node.text and node.text.strip(' \t\r\n') or '').split())