[MERGE] from upstream
bzr revid: fva@openerp.com-20130108175216-qsvgflz81jur21vu
This commit is contained in:
@@ -97,7 +97,7 @@
|
||||
<form string="Account Period" version="7.0">
|
||||
<header>
|
||||
<button string="Close Period" name="%(account.action_account_period_close)d" type="action" class="oe_highlight" states="draft"/>
|
||||
<button name="action_draft" states="done" string="Set to Draft" type="object" groups="account.group_account_manager"/>
|
||||
<button name="action_draft" states="done" string="Re-Open Period" type="object" groups="account.group_account_manager"/>
|
||||
<field name="state" widget="statusbar" nolabel="1"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
||||
+56
-21
@@ -25,6 +25,7 @@ import dateutil
|
||||
import email
|
||||
import logging
|
||||
import pytz
|
||||
import re
|
||||
import time
|
||||
import xmlrpclib
|
||||
from email.message import Message
|
||||
@@ -647,14 +648,14 @@ class mail_thread(osv.AbstractModel):
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
data = {}
|
||||
if isinstance(custom_values, dict):
|
||||
data = custom_values.copy()
|
||||
model = context.get('thread_model') or self._name
|
||||
model_pool = self.pool.get(model)
|
||||
fields = model_pool.fields_get(cr, uid, context=context)
|
||||
data = model_pool.default_get(cr, uid, fields, context=context)
|
||||
if 'name' in fields and not data.get('name'):
|
||||
data['name'] = msg_dict.get('subject', '')
|
||||
if custom_values and isinstance(custom_values, dict):
|
||||
data.update(custom_values)
|
||||
res_id = model_pool.create(cr, uid, data, context=context)
|
||||
return res_id
|
||||
|
||||
@@ -819,6 +820,41 @@ class mail_thread(osv.AbstractModel):
|
||||
"now deprecated res.log.")
|
||||
self.message_post(cr, uid, [id], message, context=context)
|
||||
|
||||
def message_create_partners_from_emails(self, cr, uid, emails, context=None):
|
||||
""" Convert a list of emails into a list partner_ids and a list
|
||||
new_partner_ids. The return value is non conventional because
|
||||
it is meant to be used by the mail widget.
|
||||
|
||||
:return dict: partner_ids and new_partner_ids
|
||||
"""
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
mail_message_obj = self.pool.get('mail.message')
|
||||
|
||||
partner_ids = []
|
||||
new_partner_ids = []
|
||||
for email in emails:
|
||||
m = re.search(r"((.+?)\s*<)?([^<>]+@[^<>]+)>?", email, re.IGNORECASE | re.DOTALL)
|
||||
name = m.group(2) or m.group(0)
|
||||
email = m.group(3)
|
||||
ids = partner_obj.search(cr, SUPERUSER_ID, [('email', '=', email)], context=context)
|
||||
if ids:
|
||||
partner_ids.append(ids[0])
|
||||
else:
|
||||
partner_id = partner_obj.create(cr, uid, {
|
||||
'name': name or email,
|
||||
'email': email,
|
||||
}, context=context)
|
||||
new_partner_ids.append(partner_id)
|
||||
|
||||
# link mail with this from mail to the new partner id
|
||||
message_ids = mail_message_obj.search(cr, SUPERUSER_ID, ['|', ('email_from', '=', email), ('email_from', 'ilike', '<%s>' % email), ('author_id', '=', False)], context=context)
|
||||
if message_ids:
|
||||
mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'email_from': None, 'author_id': partner_id}, context=context)
|
||||
return {
|
||||
'partner_ids': partner_ids,
|
||||
'new_partner_ids': new_partner_ids,
|
||||
}
|
||||
|
||||
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification',
|
||||
subtype=None, parent_id=False, attachments=None, context=None, **kwargs):
|
||||
""" Post a new message in an existing thread, returning the new
|
||||
@@ -907,7 +943,7 @@ class mail_thread(osv.AbstractModel):
|
||||
return mail_message.create(cr, uid, values, context=context)
|
||||
|
||||
def message_post_user_api(self, cr, uid, thread_id, body='', parent_id=False,
|
||||
attachment_ids=None, extra_emails=None, content_subtype='plaintext',
|
||||
attachment_ids=None, content_subtype='plaintext',
|
||||
context=None, **kwargs):
|
||||
""" Wrapper on message_post, used for user input :
|
||||
- mail gateway
|
||||
@@ -920,26 +956,12 @@ class mail_thread(osv.AbstractModel):
|
||||
- type and subtype: comment and mail.mt_comment by default
|
||||
- attachment_ids: supposed not attached to any document; attach them
|
||||
to the related document. Should only be set by Chatter.
|
||||
- extra_email: [ 'Fabien <fpi@openerp.com>', 'al@openerp.com' ]
|
||||
"""
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
mail_message_obj = self.pool.get('mail.message')
|
||||
ir_attachment = self.pool.get('ir.attachment')
|
||||
extra_emails = extra_emails or []
|
||||
|
||||
# 1.A.1: pre-process partners and incoming extra_emails
|
||||
# 1.A.1: add recipients of parent message
|
||||
partner_ids = set([])
|
||||
for email in extra_emails:
|
||||
partner_id = partner_obj.find_or_create(cr, uid, email, context=context)
|
||||
# link mail with this from mail to the new partner id
|
||||
partner_msg_ids = mail_message_obj.search(cr, SUPERUSER_ID, [('email_from', '=', email), ('author_id', '=', False)], context=context)
|
||||
if partner_id and partner_msg_ids:
|
||||
mail_message_obj.write(cr, SUPERUSER_ID, partner_msg_ids, {'email_from': None, 'author_id': partner_id}, context=context)
|
||||
partner_ids.add((4, partner_id))
|
||||
if partner_ids:
|
||||
self.message_subscribe(cr, uid, [thread_id], [item[1] for item in partner_ids], context=context)
|
||||
|
||||
# 1.A.2: add recipients of parent message
|
||||
if parent_id:
|
||||
parent_message = mail_message_obj.browse(cr, uid, parent_id, context=context)
|
||||
partner_ids |= set([(4, partner.id) for partner in parent_message.partner_ids])
|
||||
@@ -947,8 +969,21 @@ class mail_thread(osv.AbstractModel):
|
||||
if self._name == 'mail.thread' and parent_message.author_id.id:
|
||||
partner_ids.add((4, parent_message.author_id.id))
|
||||
|
||||
# 1.A.3: add specified recipients
|
||||
partner_ids |= set(kwargs.pop('partner_ids', []))
|
||||
# 1.A.2: add specified recipients
|
||||
param_partner_ids = set()
|
||||
for item in kwargs.pop('partner_ids', []):
|
||||
if isinstance(item, (list)):
|
||||
param_partner_ids.add((item[0], item[1]))
|
||||
elif isinstance(item, (int, long)):
|
||||
param_partner_ids.add((4, item))
|
||||
else:
|
||||
param_partner_ids.add(item)
|
||||
partner_ids |= param_partner_ids
|
||||
|
||||
# 1.A.3: add parameters recipients as follower
|
||||
# TDE FIXME in 7.1: should check whether this comes from email_list or partner_ids
|
||||
if param_partner_ids and self._name != 'mail.thread':
|
||||
self.message_subscribe(cr, uid, [thread_id], [pid[1] for pid in param_partner_ids], context=context)
|
||||
|
||||
# 1.B: handle body, message_type and message_subtype
|
||||
if content_subtype == 'plaintext':
|
||||
|
||||
@@ -253,7 +253,14 @@ openerp.mail = function (session) {
|
||||
} else {
|
||||
this.avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid);
|
||||
}
|
||||
|
||||
if (this.author_id) {
|
||||
var email = this.author_id[1].match(/(.*)<(.*@.*)>/);
|
||||
if (!email) {
|
||||
this.author_id.push(_.str.escapeHTML(this.author_id[1]), '', this.author_id[1]);
|
||||
} else {
|
||||
this.author_id.push(_.str.escapeHTML(email[0]), _.str.trim(email[1]), email[2]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -370,6 +377,7 @@ openerp.mail = function (session) {
|
||||
this.show_compact_message = false;
|
||||
this.show_delete_attachment = true;
|
||||
this.emails_from = [];
|
||||
this.partners_from = [];
|
||||
},
|
||||
|
||||
start: function () {
|
||||
@@ -494,43 +502,43 @@ openerp.mail = function (session) {
|
||||
this.$(".oe_msg_attachment_list").on('click', '.oe_delete', this.on_attachment_delete);
|
||||
|
||||
this.$(".oe_emails_from").on('change', 'input', this.on_checked_email_from);
|
||||
this.$(".oe_partners_from").on('change', 'input', this.on_checked_partner_from);
|
||||
},
|
||||
|
||||
on_compose_fullmail: function (default_composition_mode) {
|
||||
|
||||
var self = this;
|
||||
if(!this.do_check_attachment_upload()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (default_composition_mode == 'reply') {
|
||||
// create list of new partners
|
||||
this.check_recipient_partners().done(function (partner_ids) {
|
||||
var context = {
|
||||
'default_composition_mode': default_composition_mode,
|
||||
'default_parent_id': this.id,
|
||||
'default_body': mail.ChatterUtils.get_text2html(this.$el ? (this.$el.find('textarea:not(.oe_compact)').val() || '') : ''),
|
||||
'default_attachment_ids': this.attachment_ids,
|
||||
'default_parent_id': self.id,
|
||||
'default_body': mail.ChatterUtils.get_text2html(self.$el ? (self.$el.find('textarea:not(.oe_compact)').val() || '') : ''),
|
||||
'default_attachment_ids': self.attachment_ids,
|
||||
'default_partner_ids': partner_ids,
|
||||
};
|
||||
} else {
|
||||
var context = {
|
||||
'default_model': this.context.default_model,
|
||||
'default_res_id': this.context.default_res_id,
|
||||
'default_composition_mode': default_composition_mode,
|
||||
'default_parent_id': this.id,
|
||||
'default_body': mail.ChatterUtils.get_text2html(this.$el ? (this.$el.find('textarea:not(.oe_compact)').val() || '') : ''),
|
||||
'default_attachment_ids': this.attachment_ids,
|
||||
};
|
||||
}
|
||||
var action = {
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'mail.compose.message',
|
||||
view_mode: 'form',
|
||||
view_type: 'form',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: context,
|
||||
};
|
||||
if (default_composition_mode != 'reply' && self.context.default_model && self.context.default_res_id) {
|
||||
context.default_model = self.context.default_model;
|
||||
context.default_res_id = self.context.default_res_id;
|
||||
}
|
||||
|
||||
var action = {
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'mail.compose.message',
|
||||
view_mode: 'form',
|
||||
view_type: 'form',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: context,
|
||||
};
|
||||
|
||||
self.do_action(action);
|
||||
self.on_cancel();
|
||||
});
|
||||
|
||||
this.do_action(action);
|
||||
this.on_cancel();
|
||||
},
|
||||
|
||||
reinit: function() {
|
||||
@@ -562,63 +570,65 @@ openerp.mail = function (session) {
|
||||
}
|
||||
},
|
||||
|
||||
check_recipient_partners: function (emails) {
|
||||
check_recipient_partners: function () {
|
||||
var self = this;
|
||||
var deferreds = [];
|
||||
for (var i = 0; i < emails.length; i++) {
|
||||
deferreds.push($.Deferred());
|
||||
}
|
||||
var ds_partner = new session.web.DataSetSearch(this, 'res.partner');
|
||||
_.each(emails, function (email) {
|
||||
ds_partner.call('search', [[['email', 'ilike', email]]]).then(function (partner_ids) {
|
||||
var deferred = deferreds[_.indexOf(emails, email)];
|
||||
if (!partner_ids.length) {
|
||||
var pop = new session.web.form.FormOpenPopup(this);
|
||||
pop.show_element(
|
||||
'res.partner',
|
||||
0,
|
||||
{
|
||||
'default_email': email,
|
||||
'force_email': true,
|
||||
'ref': "compound_context",
|
||||
},
|
||||
{
|
||||
title: _t("Please complete partner's informations"),
|
||||
}
|
||||
);
|
||||
pop.on('write_completed, closed', self, function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
else {
|
||||
var partners_from = [];
|
||||
var emails = [];
|
||||
_.each(this.emails_from, function (email_from) {
|
||||
if (email_from[1] && !_.find(emails, function (email) {return email == email_from[0][4];})) {
|
||||
emails.push(email_from[0][1]);
|
||||
}
|
||||
});
|
||||
var deferred_check = $.Deferred();
|
||||
self.parent_thread.ds_thread._model.call('message_create_partners_from_emails', [emails]).then(function (partners) {
|
||||
partners_from = _.clone(partners.partner_ids);
|
||||
var deferreds = [];
|
||||
_.each(partners.new_partner_ids, function (id) {
|
||||
var deferred = $.Deferred()
|
||||
deferreds.push(deferred);
|
||||
var pop = new session.web.form.FormOpenPopup(this);
|
||||
pop.show_element(
|
||||
'res.partner',
|
||||
id,
|
||||
{
|
||||
'force_email': true,
|
||||
'ref': "compound_context",
|
||||
},
|
||||
{
|
||||
title: _t("Please complete partner's informations"),
|
||||
}
|
||||
);
|
||||
pop.on('closed', self, function () {
|
||||
deferred.resolve();
|
||||
}
|
||||
return deferred;
|
||||
});
|
||||
partners_from.push(id);
|
||||
});
|
||||
$.when.apply( $, deferreds ).then(function () {
|
||||
deferred_check.resolve(partners_from);
|
||||
});
|
||||
});
|
||||
return $.when.apply( $, deferreds ).done();
|
||||
return deferred_check;
|
||||
},
|
||||
|
||||
on_message_post: function (event) {
|
||||
var self = this;
|
||||
if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) {
|
||||
// create list of new partners
|
||||
var extra_email = _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]});
|
||||
this.check_recipient_partners(extra_email).done(function () {
|
||||
self.do_send_message_post();
|
||||
this.check_recipient_partners().done(function (partner_ids) {
|
||||
self.do_send_message_post(partner_ids);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/*do post a message and fetch the message*/
|
||||
do_send_message_post: function () {
|
||||
do_send_message_post: function (partner_ids) {
|
||||
var self = this;
|
||||
this.parent_thread.ds_thread._model.call('message_post_user_api', [this.context.default_res_id], {
|
||||
'body': this.$('textarea').val(),
|
||||
'subject': false,
|
||||
'parent_id': this.context.default_parent_id,
|
||||
'attachment_ids': _.map(this.attachment_ids, function (file) {return file.id;}),
|
||||
'extra_emails': _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}),
|
||||
'partner_ids': partner_ids,
|
||||
'context': this.parent_thread.context,
|
||||
}).done(function (message_id) {
|
||||
var thread = self.parent_thread;
|
||||
@@ -678,26 +688,24 @@ openerp.mail = function (session) {
|
||||
_.each(this.options.root_thread.messages, function (msg) {messages.push(msg); messages.concat(msg.get_childs());});
|
||||
}
|
||||
|
||||
var emails_from = _.map(_.filter(messages,
|
||||
function (thread) {return thread.author_id && !thread.author_id[0];}),
|
||||
function (thread) {return thread.author_id[1];});
|
||||
|
||||
return _.each(emails_from, function (email_from) {
|
||||
if (!_.find(self.emails_from, function (from) {return from[0] == email_from;})) {
|
||||
self.emails_from.push([email_from, true]);
|
||||
_.each(messages, function (thread) {
|
||||
if (thread.author_id && !thread.author_id[0] &&
|
||||
!_.find(self.emails_from, function (from) {return from[0][4] == thread.author_id[4];})) {
|
||||
self.emails_from.push([thread.author_id, true]);
|
||||
}
|
||||
});
|
||||
return self.emails_from;
|
||||
},
|
||||
|
||||
on_checked_email_from: function (event) {
|
||||
var $input = $(event.target);
|
||||
var email = $input.attr("data");
|
||||
_.each(this.emails_from, function (email_from) {
|
||||
if (email_from[0] == email) {
|
||||
if (email_from[0][4] == email) {
|
||||
email_from[1] = $input.is(":checked");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -1690,7 +1698,6 @@ openerp.mail = function (session) {
|
||||
this.defaults[key.replace(/^search_default_/, '')] = this.context[key];
|
||||
}
|
||||
}
|
||||
|
||||
this.action.params = _.extend({
|
||||
'display_indented_thread': 1,
|
||||
'show_reply_button': true,
|
||||
|
||||
@@ -221,11 +221,14 @@ openerp_mail_followers = function(session, mail) {
|
||||
var nb_subtype = 0;
|
||||
_(records).each(function (record) {nb_subtype++;});
|
||||
if (nb_subtype > 1) {
|
||||
this.$('hr').show();
|
||||
_(records).each(function (record, record_name) {
|
||||
record.name = record_name;
|
||||
record.followed = record.followed || undefined;
|
||||
$(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') );
|
||||
});
|
||||
} else {
|
||||
this.$('hr').hide();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -132,8 +132,8 @@
|
||||
<div class="oe_emails_from">
|
||||
<t t-foreach='widget.emails_from' t-as='email_from'>
|
||||
<label title="Add them into recipients and followers">
|
||||
<input type="checkbox" t-att-checked="email_from[1] ? 'checked' : undefind" t-att-data="email_from[0]"/>
|
||||
<t t-raw="email_from[0]"/>
|
||||
<input type="checkbox" t-att-checked="email_from[1] ? 'checked' : undefind" t-att-data="email_from[0][4]"/>
|
||||
<t t-raw="email_from[0][2]"/>
|
||||
</label>
|
||||
</t>
|
||||
</div>
|
||||
@@ -243,8 +243,8 @@
|
||||
<t t-if="widget.attachment_ids.length > 0">
|
||||
<div class="oe_msg_attachment_list"></div>
|
||||
</t>
|
||||
<a t-if="widget.author_id and widget.options.show_link and widget.author_id[0]" t-attf-href="#model=res.partner&id=#{widget.author_id[0]}"><t t-raw="widget.author_id[1]"/></a>
|
||||
<span t-if="widget.author_id and (!widget.options.show_link or !widget.author_id[0])"><t t-raw="widget.author_id[1]"/></span>
|
||||
<a t-if="widget.author_id and widget.options.show_link and widget.author_id[0]" t-attf-href="#model=res.partner&id=#{widget.author_id[0]}"><t t-raw="widget.author_id[2]"/></a>
|
||||
<span t-if="widget.author_id and (!widget.options.show_link or !widget.author_id[0])"><t t-raw="widget.author_id[2]"/></span>
|
||||
<span class='oe_subtle'>•</span>
|
||||
<span t-att-title="widget.date"><t t-raw="widget.timerelative"/></span>
|
||||
<span t-if="!widget.options.readonly" class='oe_subtle'>•</span>
|
||||
|
||||
@@ -168,6 +168,7 @@ class mail_compose_message(osv.TransientModel):
|
||||
reply_subject = "%s %s" % (re_prefix, reply_subject)
|
||||
# get partner_ids from original message
|
||||
partner_ids = [partner.id for partner in message_data.partner_ids] if message_data.partner_ids else []
|
||||
partner_ids += context.get('default_partner_ids', [])
|
||||
|
||||
# update the result
|
||||
result = {
|
||||
|
||||
Reference in New Issue
Block a user