Skip to content

Commit 7310191

Browse files
committed
[MERGE] forward port of branch saas-2 up to revid 9109 [email protected]
bzr revid: [email protected]
2 parents 64822bd + 6cc096a commit 7310191

35 files changed

+183
-81
lines changed

addons/account/account.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -3187,11 +3187,14 @@ def _prepare_all_journals(self, cr, uid, chart_template_id, acc_template_ref, co
31873187
def _get_analytic_journal(journal_type):
31883188
# Get the analytic journal
31893189
data = False
3190-
if journal_type in ('sale', 'sale_refund'):
3191-
data = obj_data.get_object_reference(cr, uid, 'account', 'analytic_journal_sale')
3192-
elif journal_type in ('purchase', 'purchase_refund'):
3193-
pass
3194-
elif journal_type == 'general':
3190+
try:
3191+
if journal_type in ('sale', 'sale_refund'):
3192+
data = obj_data.get_object_reference(cr, uid, 'account', 'analytic_journal_sale')
3193+
elif journal_type in ('purchase', 'purchase_refund'):
3194+
data = obj_data.get_object_reference(cr, uid, 'account', 'exp')
3195+
elif journal_type == 'general':
3196+
pass
3197+
except ValueError:
31953198
pass
31963199
return data and data[1] or False
31973200

addons/account/wizard/account_reconcile.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from openerp.osv import fields, osv
2525
from openerp.tools.translate import _
26+
from openerp.tools.float_utils import float_round
2627
import openerp.addons.decimal_precision as dp
2728

2829
class account_move_line_reconcile(osv.osv_memory):
@@ -64,7 +65,11 @@ def trans_rec_get(self, cr, uid, ids, context=None):
6465
credit += line.credit
6566
debit += line.debit
6667
account_id = line.account_id.id
67-
return {'trans_nbr': count, 'account_id': account_id, 'credit': credit, 'debit': debit, 'writeoff': debit - credit}
68+
precision = self.pool['decimal.precision'].precision_get(cr, uid, 'Account')
69+
writeoff = float_round(debit-credit, precision_digits=precision)
70+
credit = float_round(credit, precision_digits=precision)
71+
debit = float_round(debit, precision_digits=precision)
72+
return {'trans_nbr': count, 'account_id': account_id, 'credit': credit, 'debit': debit, 'writeoff': writeoff}
6873

6974
def trans_rec_addendum_writeoff(self, cr, uid, ids, context=None):
7075
return self.pool.get('account.move.line.reconcile.writeoff').trans_rec_addendum(cr, uid, ids, context)

addons/account/wizard/account_reconcile_view.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
</group>
1818
<footer>
1919
<button string="Reconcile" name="trans_rec_reconcile_full" type="object" default_focus="1" attrs="{'invisible':[('writeoff','!=',0)]}" class="oe_highlight"/>
20-
<button string="Reconcile With Write-Off" name="trans_rec_addendum_writeoff" type="object" attrs="{'invisible':[('writeoff','==',0)]}" class="oe_highlight"/>
21-
<button string="Partial Reconcile" name="trans_rec_reconcile_partial_reconcile" type="object" attrs="{'invisible':[('writeoff','==',0)]}" class="oe_highlight"/>
20+
<button string="Reconcile With Write-Off" name="trans_rec_addendum_writeoff" type="object" attrs="{'invisible':[('writeoff','=',0)]}" class="oe_highlight"/>
21+
<button string="Partial Reconcile" name="trans_rec_reconcile_partial_reconcile" type="object" attrs="{'invisible':[('writeoff','=',0)]}" class="oe_highlight"/>
2222
or
2323
<button string="Cancel" class="oe_link" special="cancel"/>
2424
</footer>

addons/account_analytic_analysis/account_analytic_analysis_view.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@
219219
<filter name="open" string="In Progress" domain="[('state','in',('open','draft'))]" help="Contracts in progress (open, draft)"/>
220220
<filter name="pending" string="To Renew" domain="[('state','=','pending')]" help="Pending contracts"/>
221221
<filter name="closed" string="Closed" domain="[('state','=','close')]" help="Closed contracts"/>
222-
<filter name="cancelled" string="Cancelled" domain="[('state','=','cancel')]" help="Cancelled contracts"/>
222+
<filter name="cancelled" string="Cancelled" domain="[('state','=','cancelled')]" help="Cancelled contracts"/>
223223
<separator/>
224224
<filter
225225
string="Expired or consumed"

addons/account_asset/account_asset.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ class account_asset_category(osv.osv):
3535
'name': fields.char('Name', size=64, required=True, select=1),
3636
'note': fields.text('Note'),
3737
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
38-
'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True),
39-
'account_depreciation_id': fields.many2one('account.account', 'Depreciation Account', required=True),
40-
'account_expense_depreciation_id': fields.many2one('account.account', 'Depr. Expense Account', required=True),
38+
'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True, domain=[('type','=','other')]),
39+
'account_depreciation_id': fields.many2one('account.account', 'Depreciation Account', required=True, domain=[('type','=','other')]),
40+
'account_expense_depreciation_id': fields.many2one('account.account', 'Depr. Expense Account', required=True, domain=[('type','=','other')]),
4141
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
4242
'company_id': fields.many2one('res.company', 'Company', required=True),
4343
'method': fields.selection([('linear','Linear'),('degressive','Degressive')], 'Computation Method', required=True, help="Choose the method to use to compute the amount of depreciation lines.\n"\

addons/account_followup/report/account_followup_print.rml

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
<para style="terp_default_8">
150150
<font color="white"> </font>
151151
</para>
152-
<para style="terp_default_9_followup_id">[[ format(get_text(o,data['form']['followup_id'])) ]]</para>
152+
<pre style="terp_default_9_followup_id">[[ format(get_text(o,data['form']['followup_id'])) ]]</pre>
153153
<para style="terp_default_9">
154154
<font color="white"> </font>
155155
</para>

addons/auth_ldap/users_ldap.py

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ def authenticate(self, conf, login, password):
9999
filter = filter_format(conf['ldap_filter'], (login,))
100100
try:
101101
results = self.query(conf, filter)
102+
103+
# Get rid of (None, attrs) for searchResultReference replies
104+
results = [i for i in results if i[0]]
102105
if results and len(results) == 1:
103106
dn = results[0][0]
104107
conn = self.connect(conf)

addons/calendar/calendar.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1330,13 +1330,13 @@ def search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, cou
13301330
new_id = get_real_ids(arg[2])
13311331
new_arg = (arg[0], arg[1], new_id)
13321332
new_args.append(new_arg)
1333-
#offset, limit and count must be treated separately as we may need to deal with virtual ids
13341333

1335-
if context.get('virtual_id', True):
1336-
res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=None, context=context, count=False)
1337-
res = self.get_recurrent_ids(cr, uid, res, args, order=order, context=context)
1338-
else:
1339-
res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=order, context=context, count=False)
1334+
if not context.get('virtual_id', True):
1335+
return super(calendar_event, self).search(cr, uid, new_args, offset=offset, limit=limit, order=order, context=context, count=count)
1336+
1337+
# offset, limit, order and count must be treated separately as we may need to deal with virtual ids
1338+
res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=None, context=context, count=False)
1339+
res = self.get_recurrent_ids(cr, uid, res, args, order=order, context=context)
13401340
if count:
13411341
return len(res)
13421342
elif limit:

addons/decimal_precision/decimal_precision.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ def clear_cache(self, cr):
5050
self.precision_get.clear_cache(self)
5151
for obj in self.pool.obj_list():
5252
for colname, col in self.pool.get(obj)._columns.items():
53-
if isinstance(col, (fields.float, fields.function)):
53+
if hasattr(col, 'digits_change'):
5454
col.digits_change(cr)
55-
RegistryManager.signal_registry_change(cr.dbname)
55+
RegistryManager.signal_caches_change(cr.dbname)
5656

5757
def create(self, cr, uid, data, context=None):
5858
res = super(decimal_precision, self).create(cr, uid, data, context=context)

addons/document_ftp/ftpserver/abstracted_fs.py

+1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ def get_crdata(self, line, mode='file'):
262262
if path == '/' and mode in ('list', 'cwd'):
263263
return (None, None, None )
264264

265+
if path == '..': path = self.cwd + '/..'
265266
path = _to_unicode(os.path.normpath(path)) # again, for '/db/../ss'
266267
if path == '.': path = ''
267268

addons/email_template/email_template.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,8 @@ def send_mail(self, cr, uid, template_id, res_id, force_send=False, raise_except
417417

418418
# create a mail_mail based on values, without attachments
419419
values = self.generate_email(cr, uid, template_id, res_id, context=context)
420-
assert values.get('email_from'), 'email_from is missing or empty after template rendering, send_mail() cannot proceed'
421-
420+
if not values.get('email_from'):
421+
raise osv.except_osv(_('Warning!'),_("Sender email is missing or empty after template rendering. Specify one to deliver your message"))
422422
# process partner_to field that is a comma separated list of partner_ids -> recipient_ids
423423
# NOTE: only usable if force_send is True, because otherwise the value is
424424
# not stored on the mail_mail, and therefore lost -> fixed in v8

addons/im/im.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ def get_messages(self, cr, uid, last=None, users_watch=None, uuid=None, context=
185185
def post(self, cr, uid, message, to_session_id, technical=False, uuid=None, context=None):
186186
assert_uuid(uuid)
187187
my_id = self.pool.get('im.user').get_my_id(cr, uid, uuid)
188-
session = self.pool.get('im.session').browse(cr, uid, to_session_id, context)
189-
to_ids = [x.id for x in session.user_ids if x.id != my_id]
188+
session_user_ids = self.pool.get('im.session').get_session_users(cr, uid, to_session_id, context=context).get("user_ids", [])
189+
to_ids = [user_id for user_id in session_user_ids if user_id != my_id]
190190
self.create(cr, openerp.SUPERUSER_ID, {"message": message, 'from_id': my_id,
191191
'to_id': [(6, 0, to_ids)], 'session_id': to_session_id, 'technical': technical}, context=context)
192192
notify_channel(cr, "im_channel", {'type': 'message', 'receivers': [my_id] + to_ids})
@@ -202,7 +202,7 @@ def _calc_name(self, cr, uid, ids, something, something_else, context=None):
202202
return res
203203

204204
_columns = {
205-
'user_ids': fields.many2many('im.user'),
205+
'user_ids': fields.many2many('im.user', 'im_session_im_user_rel', 'im_session_id', 'im_user_id', 'Users'),
206206
"name": fields.function(_calc_name, string="Name", type='char'),
207207
}
208208

@@ -225,6 +225,9 @@ def session_get(self, cr, uid, users_to, uuid=None, context=None):
225225
}, context=context)
226226
return self.read(cr, uid, session_id, context=context)
227227

228+
def get_session_users(self, cr, uid, session_id, context=None):
229+
return self.read(cr, openerp.SUPERUSER_ID, session_id, ['user_ids'], context=context)
230+
228231
def add_to_session(self, cr, uid, session_id, user_id, uuid=None, context=None):
229232
my_id = self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
230233
session = self.read(cr, uid, session_id, context=context)
@@ -259,7 +262,7 @@ def _status_search(self, cr, uid, obj, name, domain, context=None):
259262
return ['&', ('im_last_status', '=', True), ('im_last_status_update', '>', (current - delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
260263
else:
261264
return ['|', ('im_last_status', '=', False), ('im_last_status_update', '<=', (current - delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
262-
265+
# TODO: Remove fields arg in trunk. Also in im.js.
263266
def search_users(self, cr, uid, text_search, fields, limit, context=None):
264267
my_id = self.get_my_id(cr, uid, None, context)
265268
group_employee = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'group_user')[1]
@@ -271,7 +274,7 @@ def search_users(self, cr, uid, text_search, fields, limit, context=None):
271274
if len(found) < limit:
272275
found += self.search(cr, uid, [["name", "ilike", text_search], ["id", "<>", my_id], ["uuid", "=", False], ["im_status", "=", False], ["id", "not in", found]],
273276
order="name asc", limit=limit-len(found), context=context)
274-
users = self.read(cr, uid, found, fields, context=context)
277+
users = self.read(cr,openerp.SUPERUSER_ID, found, ["name", "user_id", "uuid", "im_status"], context=context)
275278
users.sort(key=lambda obj: found.index(obj['id']))
276279
return users
277280

@@ -319,6 +322,9 @@ def _get_name(self, cr, uid, ids, name, arg, context=None):
319322
continue
320323
return res
321324

325+
def get_users(self, cr, uid, ids, context=None):
326+
return self.read(cr,openerp.SUPERUSER_ID, ids, ["name", "im_status", "uuid"], context=context)
327+
322328
_columns = {
323329
'name': fields.function(_get_name, type='char', size=200, string="Name", store=True, readonly=True),
324330
'assigned_name': fields.char(string="Assigned Name", size=200, required=False),
@@ -341,3 +347,16 @@ def _get_name(self, cr, uid, ids, name, arg, context=None):
341347
('user_uniq', 'unique (user_id)', 'Only one chat user per OpenERP user.'),
342348
('uuid_uniq', 'unique (uuid)', 'Chat identifier already used.'),
343349
]
350+
351+
class res_users(osv.osv):
352+
_inherit = "res.users"
353+
354+
def _get_im_user(self, cr, uid, ids, field_name, arg, context=None):
355+
result = dict.fromkeys(ids, False)
356+
for index, im_user in enumerate(self.pool['im.user'].search_read(cr, uid, domain=[('user_id', 'in', ids)], fields=['name', 'user_id'], context=context)):
357+
result[ids[index]] = im_user.get('user_id') and (im_user['user_id'][0], im_user['name']) or False
358+
return result
359+
360+
_columns = {
361+
'im_user_id' : fields.function(_get_im_user, type='many2one', string="IM User", relation="im.user"),
362+
}

addons/im/security/im_security.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
<openerp>
33
<data>
44
<record id="message_rule_1" model="ir.rule">
5-
<field name="name">Can only read messages that you sent or messages sent to you</field>
5+
<field name="name">Can only read messages from a session where user is</field>
66
<field name="model_id" ref="model_im_message"/>
77
<field name="groups" eval="[(6,0,[ref('base.group_user')])]"/>
8-
<field name="domain_force">["|", ('to_id.user_id', 'in', [user.id]), ('from_id.user_id', '=', user.id)]</field>
8+
<field name="domain_force">[('session_id.user_ids', 'in', user.im_user_id.id)]</field>
99
<field name="perm_read" eval="1"/>
1010
<field name="perm_write" eval="0"/>
1111
<field name="perm_create" eval="0"/>
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2-
access_im_message,im.message,model_im_message,base.group_user,1,0,1,0
2+
access_im_message,im.message,model_im_message,,1,0,1,0
33
access_im_user,im.user,model_im_user,,1,1,1,0
44
access_im_session,im.session,model_im_session,,1,0,0,0

addons/im/static/src/js/im.js

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
search_changed: function(e) {
9393
var users = new instance.web.Model("im.user");
9494
var self = this;
95+
// TODO: Remove fields arg in trunk. Also in im.js.
9596
return this.user_search_dm.add(users.call("search_users", [this.get("current_search"), ["name", "user_id", "uuid", "im_status"],
9697
USERS_LIMIT], {context:new instance.web.CompoundContext()})).then(function(users) {
9798
var logged_users = _.filter(users, function(u) { return !!u.im_status; });

addons/im/static/src/js/im_common.js

+30-7
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function declare($, _, openerp) {
145145
if (_.size(no_cache) === 0)
146146
def = $.when();
147147
else
148-
def = im_common.connection.model("im.user").call("read", [_.values(no_cache), []]).then(function(users) {
148+
def = im_common.connection.model("im.user").call("get_users", [_.values(no_cache)]).then(function(users) {
149149
self.add_to_user_cache(users);
150150
});
151151
return def.then(function() {
@@ -230,7 +230,8 @@ function declare($, _, openerp) {
230230
return self.chat_with_users(users);
231231
});
232232
},
233-
activate_session: function(session_id, focus) {
233+
activate_session: function(session_id, focus, message) {
234+
var self = this;
234235
var conv = _.find(this.conversations, function(conv) {return conv.session_id == session_id;});
235236
var def = $.when();
236237
if (! conv) {
@@ -244,6 +245,9 @@ function declare($, _, openerp) {
244245
this.calc_positions();
245246
this.trigger("new_conversation", conv);
246247
}, this));
248+
def = def.then(function(){
249+
return self.load_history(conv, message);
250+
});
247251
}
248252
if (focus) {
249253
def = def.then(function() {
@@ -252,13 +256,32 @@ function declare($, _, openerp) {
252256
}
253257
return def.then(function() {return conv});
254258
},
255-
received_messages: function(messages) {
259+
load_history: function(conv, message){
260+
var self = this;
261+
var domain = [["session_id", "=", conv.session_id]];
262+
if (!_.isUndefined(message)){
263+
domain.push(["date", "<", message.date]);
264+
}
265+
return im_common.connection.model("im.message").call("search_read", [domain, [], 0, 10]).then(function(messages){
266+
messages.reverse();
267+
var users = _.unique(_.map(messages, function(message){
268+
return message.from_id[0];
269+
}));
270+
return self.ensure_users(users).then(function(){
271+
return self.received_messages(messages, true);
272+
});
273+
});
274+
},
275+
received_messages: function(messages, seen) {
256276
var self = this;
257277
var defs = [];
258278
var received = false;
279+
if (_.isUndefined(seen)){
280+
seen = false;
281+
}
259282
_.each(messages, function(message) {
260283
if (! message.technical) {
261-
defs.push(self.activate_session(message.session_id[0]).then(function(conv) {
284+
defs.push(self.activate_session(message.session_id[0], false, message).then(function(conv) {
262285
received = self.my_id !== message.from_id[0];
263286
return conv.received_message(message);
264287
}));
@@ -269,7 +292,7 @@ function declare($, _, openerp) {
269292
}
270293
});
271294
return $.when.apply($, defs).then(function(){
272-
if (! self.get("window_focus") && received) {
295+
if (! self.get("window_focus") && received && !seen) {
273296
self.set("waiting_messages", self.get("waiting_messages") + messages.length);
274297
self.ting.play();
275298
self.create_ting();
@@ -368,7 +391,7 @@ function declare($, _, openerp) {
368391
refresh_users: function() {
369392
var self = this;
370393
var user_ids;
371-
return im_common.connection.model("im.session").call("read", [self.session_id]).then(function(session) {
394+
return im_common.connection.model("im.session").call("get_session_users", [self.session_id]).then(function(session) {
372395
user_ids = _.without(session.user_ids, self.c_manager.me.get("id"));
373396
return self.c_manager.ensure_users(user_ids);
374397
}).then(function(users) {
@@ -449,7 +472,7 @@ function declare($, _, openerp) {
449472
date = "" + zpad(date.getHours(), 2) + ":" + zpad(date.getMinutes(), 2);
450473
var to_show = _.map(items, im_common.escape_keep_url);
451474
this.last_bubble = $(openerp.qweb.render("im_common.conversation_bubble", {"items": to_show, "user": user, "time": date}));
452-
$(this.$(".oe_im_chatview_content").children()[0]).append(this.last_bubble);
475+
$(this.$(".oe_im_chatview_conversation")).append(this.last_bubble);
453476
this._go_bottom();
454477
},
455478
_go_bottom: function() {

0 commit comments

Comments
 (0)