diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index 8df291a98d1..095d461ff3b 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -430,7 +430,7 @@ class account_bank_statement(osv.osv):
'name': st_number,
'balance_end_real': st.balance_end
}, context=context)
- self.message_append_note(cr, uid, [st.id], body=_('Statement %s is confirmed, journal items are created.') % (st_number,), context=context)
+ self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st_number,), context=context)
return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
def button_cancel(self, cr, uid, ids, context=None):
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 57606ba46fb..e8e935a9505 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -1045,7 +1045,7 @@ class account_invoice(osv.osv):
if obj_inv.type in ('out_invoice', 'out_refund'):
ctx = self.get_log_context(cr, uid, context=ctx)
message = _("Invoice '%s' is validated.") % name
- self.message_append_note(cr, uid, [inv_id], body=message, context=context)
+ self.message_post(cr, uid, [inv_id], body=message, context=context)
return True
def action_cancel(self, cr, uid, ids, *args):
@@ -1275,7 +1275,7 @@ class account_invoice(osv.osv):
# TODO: use currency's formatting function
msg = _("Invoice '%s' is paid partially: %s%s of %s%s (%s%s remaining).") % \
(name, pay_amount, code, invoice.amount_total, code, total, code)
- self.message_append_note(cr, uid, [inv_id], body=msg, context=context)
+ self.message_post(cr, uid, [inv_id], body=msg, context=context)
self.pool.get('account.move.line').reconcile_partial(cr, uid, line_ids, 'manual', context)
# Update the stored value (fields.function), so we write to trigger recompute
@@ -1288,25 +1288,25 @@ class account_invoice(osv.osv):
def _get_document_type(self, type):
type_dict = {
- 'out_invoice': 'Customer invoice',
- 'in_invoice': 'Supplier invoice',
- 'out_refund': 'Customer Refund',
- 'in_refund': 'Supplier Refund',
+ # Translation markers will have no effect at runtime, only used to properly flag export
+ 'out_invoice': _('Customer invoice'),
+ 'in_invoice': _('Supplier invoice'),
+ 'out_refund': _('Customer Refund'),
+ 'in_refund': _('Supplier Refund'),
}
return type_dict.get(type, 'Invoice')
def create_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
- self.message_append_note(cr, uid, [obj.id],body=_("%s created.") % (self._get_document_type(obj.type)), subtype="new", context=context)
+ self.message_post(cr, uid, [obj.id],body=_("%s created.") % (self._get_document_type(obj.type)), subtype="new", context=context)
def confirm_paid_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
- self.message_append_note(cr, uid, [obj.id], body=_("%s paid.") % (self._get_document_type(obj.type)), subtype="paid", context=context)
+ self.message_post(cr, uid, [obj.id], body=_("%s paid.") % (self._get_document_type(obj.type)), subtype="paid", context=context)
def invoice_cancel_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
- self.message_append_note(cr, uid, [obj.id], body=_("%s cancelled.") % (self._get_document_type(obj.type)), subtype="cancel", context=context)
-
+ self.message_post(cr, uid, [obj.id], body=_("%s cancelled.") % (self._get_document_type(obj.type)), subtype="cancel", context=context)
account_invoice()
class account_invoice_line(osv.osv):
diff --git a/addons/account/edi/invoice_action_data.xml b/addons/account/edi/invoice_action_data.xml
index 0eec6d27785..9aa1a4b720f 100644
--- a/addons/account/edi/invoice_action_data.xml
+++ b/addons/account/edi/invoice_action_data.xml
@@ -123,7 +123,7 @@
]]>
-
-
+
- Module Accounting and Finance has been installed.With OpenERP's accounting, you can get an instant access to all your financial data, setup your analytic accounting, forecast your taxes, control your budgets, easily create and send invoices, record bank statements, etc.
The accounting features are fully integrated with others OpenERP applications to automate all your processes: creation of customer invoices, control of supplier invoices, point-of-sale integration, automated follow-ups, etc.
+ Module Accounting and Finance has been installed.
diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py
index ee57368e509..9d656c7607d 100644
--- a/addons/account_voucher/account_voucher.py
+++ b/addons/account_voucher/account_voucher.py
@@ -1293,17 +1293,17 @@ class account_voucher(osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
message = "%s created." % self._document_type[obj.type or False]
- self.message_append_note(cr, uid, [obj.id], body=message, subtype="new", context=context)
+ self.message_post(cr, uid, [obj.id], body=message, subtype="new", context=context)
def post_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
message = "%s '%s' is posted." % (self._document_type[obj.type or False], obj.move_id.name)
- self.message_append_note(cr, uid, [obj.id], body=message, subtype="post", context=context)
+ self.message_post(cr, uid, [obj.id], body=message, subtype="post", context=context)
def reconcile_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
message = "%s reconciled." % self._document_type[obj.type or False]
- self.message_append_note(cr, uid, [obj.id], body=message, subtype="reconcile", context=context)
+ self.message_post(cr, uid, [obj.id], body=message, subtype="reconcile", context=context)
account_voucher()
diff --git a/addons/account_voucher/account_voucher_data.xml b/addons/account_voucher/account_voucher_data.xml
index 76e4d7b1849..a99a8735842 100644
--- a/addons/account_voucher/account_voucher_data.xml
+++ b/addons/account_voucher/account_voucher_data.xml
@@ -2,15 +2,15 @@
-
+
- Module eInvoicing & Payments has been installed.OpenERP's electronic invoicing allows to ease and fasten the creation of invoices and collection of customer payments. Invoices are created in a few clicks and your customers receive them by email. They can pay online and/or import them in their own system.
You can track customer payments easily and automate the reminders. You get an overview of the discussion with your customers on each invoice to ensure a full traceability.
If you want to use advanced accounting features, you should install the "Accounting and Finance" module.
+ Module eInvoicing & Payments has been installed.
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py
index 60d2731fe9d..2e6e5089c88 100644
--- a/addons/analytic/analytic.py
+++ b/addons/analytic/analytic.py
@@ -297,7 +297,7 @@ class account_analytic_account(osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
- self.message_append_note(cr, uid, [obj.id], body=_("Contract for %s has been created.") % (obj.partner_id.name), subtype="new", context=context)
+ self.message_post(cr, uid, [obj.id], body=_("Contract for %s has been created.") % (obj.partner_id.name), subtype="new", context=context)
account_analytic_account()
diff --git a/addons/analytic_contract_project/analytic_contract_project.py b/addons/analytic_contract_project/analytic_contract_project.py
index 1ffab1246c9..91dc4498880 100644
--- a/addons/analytic_contract_project/analytic_contract_project.py
+++ b/addons/analytic_contract_project/analytic_contract_project.py
@@ -79,6 +79,6 @@ class task(osv.osv):
task_id = super(task, self).create(cr, uid, vals, context=context)
task_browse = self.browse(cr, uid, task_id, context=context)
if task_browse.project_id.analytic_account_id:
- self.pool.get('account.analytic.account').message_append_note(cr, uid, [task_browse.project_id.analytic_account_id.id], body=_("Task %s has been created.") % (task_browse.name), context=context)
+ self.pool.get('account.analytic.account').message_post(cr, uid, [task_browse.project_id.analytic_account_id.id], body=_("Task %s has been created.") % (task_browse.name), context=context)
return task_id
task()
diff --git a/addons/auth_reset_password/auth_reset_password.xml b/addons/auth_reset_password/auth_reset_password.xml
index 26ea8878c45..d2256a8911a 100644
--- a/addons/auth_reset_password/auth_reset_password.xml
+++ b/addons/auth_reset_password/auth_reset_password.xml
@@ -9,7 +9,7 @@
]]>Password reset
- ,]+)', text or '')
- emails = to_email(','.join(filter(None, emails)))
- email_froms = to_email(email_from)
+ emails = tools.email_split(','.join(filter(None, emails)))
+ email_froms = tools.email_split(email_from)
if email_froms:
self.email_send(cr, uid, obj, emails, action.act_mail_body, emailfrom=email_froms[0])
return True
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index be3244f8a5b..d560eaacd66 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -1616,36 +1616,6 @@ class calendar_todo(osv.osv):
calendar_todo()
-class ir_attachment(osv.osv):
- _name = 'ir.attachment'
- _inherit = 'ir.attachment'
-
- def search_count(self, cr, user, args, context=None):
- new_args = []
- for domain_item in args:
- if isinstance(domain_item, (list, tuple)) and len(domain_item) == 3 and domain_item[0] == 'res_id':
- new_args.append((domain_item[0], domain_item[1], base_calendar_id2real_id(domain_item[2])))
- else:
- new_args.append(domain_item)
- return super(ir_attachment, self).search_count(cr, user, new_args, context)
-
- def create(self, cr, uid, vals, context=None):
- if context:
- id = context.get('default_res_id', False)
- context.update({'default_res_id' : base_calendar_id2real_id(id)})
- return super(ir_attachment, self).create(cr, uid, vals, context=context)
-
- def search(self, cr, uid, args, offset=0, limit=None, order=None,
- context=None, count=False):
- new_args = []
- for domain_item in args:
- if isinstance(domain_item, (list, tuple)) and len(domain_item) == 3 and domain_item[0] == 'res_id':
- new_args.append((domain_item[0], domain_item[1], base_calendar_id2real_id(domain_item[2])))
- else:
- new_args.append(domain_item)
- return super(ir_attachment, self).search(cr, uid, new_args, offset=offset,
- limit=limit, order=order, context=context, count=False)
-ir_attachment()
class ir_values(osv.osv):
_inherit = 'ir.values'
diff --git a/addons/base_calendar/crm_meeting.py b/addons/base_calendar/crm_meeting.py
index cb96ff2a4d0..e1c66148ae7 100644
--- a/addons/base_calendar/crm_meeting.py
+++ b/addons/base_calendar/crm_meeting.py
@@ -43,7 +43,7 @@ class crm_meeting(base_state, osv.Model):
_name = 'crm.meeting'
_description = "Meeting"
_order = "id desc"
- _inherit = ["calendar.event", 'ir.needaction_mixin', "mail.thread"]
+ _inherit = ["calendar.event", "mail.thread", 'ir.needaction_mixin']
_columns = {
# base_state required fields
'create_date': fields.datetime('Creation Date', readonly=True),
@@ -70,13 +70,17 @@ class crm_meeting(base_state, osv.Model):
# OpenChatter
# ----------------------------------------
+ # shows events of the day for this user
+ def needaction_domain_get(self, cr, uid, domain=[], context={}):
+ return [('date','<=',time.strftime('%Y-%M-%D 23:59:59')), ('date_deadline','>=', time.strftime('%Y-%M-%D 00:00:00')), ('user_id','=',uid)]
+
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
return 'Meeting'
def case_open_send_note(self, cr, uid, ids, context=None):
- return self.message_append_note(cr, uid, ids, body=_("Meeting has been confirmed."), context=context)
+ return self.message_post(cr, uid, ids, body=_("Meeting confirmed."), context=context)
def case_close_send_note(self, cr, uid, ids, context=None):
- return self.message_append_note(cr, uid, ids, body=_("Meeting has been done."), context=context)
+ return self.message_post(cr, uid, ids, body=_("Meeting completed."), context=context)
diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml
index 6009251a460..928f8d94d5c 100644
--- a/addons/base_calendar/crm_meeting_view.xml
+++ b/addons/base_calendar/crm_meeting_view.xml
@@ -170,7 +170,8 @@
@@ -182,17 +183,16 @@
+ />
+ type="object" />
+ type="object" />
@@ -200,16 +200,16 @@
+ string="Uncertain" />
+ string="Accept" />
+ string="Decline" />
@@ -244,13 +244,13 @@
CRM - Meetings Treecrm.meeting
-
+
-
+
@@ -287,9 +287,9 @@
-
+
-
+
diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py
index 775de51394c..26afe548217 100644
--- a/addons/base_status/base_stage.py
+++ b/addons/base_status/base_stage.py
@@ -312,8 +312,8 @@ class base_stage(object):
dest = case.user_id.email or ""
body = case.description or ""
for message in case.message_ids:
- if message.email_from and message.body_text:
- body = message.body_text
+ if message.email_from and message.body:
+ body = message.body
break
if not destination:
@@ -395,31 +395,31 @@ class base_stage(object):
def case_open_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been opened.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_close_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been closed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_cancel_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been canceled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_pending_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s is now pending.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_reset_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been renewed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_escalate_send_note(self, cr, uid, ids, new_section=None, context=None):
@@ -428,5 +428,5 @@ class base_stage(object):
msg = '%s has been escalated to %s.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context), new_section.name)
else:
msg = '%s has been escalated.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], 'System Notification', msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
diff --git a/addons/base_status/base_state.py b/addons/base_status/base_state.py
index 8fa2f92e22a..cebf5537485 100644
--- a/addons/base_status/base_state.py
+++ b/addons/base_status/base_state.py
@@ -179,13 +179,13 @@ class base_state(object):
# Notifications
# ******************************
- def case_get_note_msg_prefix(self, cr, uid, id, context=None):
- return ''
-
+ def case_get_note_msg_prefix(self, cr, uid, id, context=None):
+ return ''
+
def case_open_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been opened.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_escalate_send_note(self, cr, uid, ids, new_section=None, context=None):
@@ -194,29 +194,29 @@ class base_state(object):
msg = '%s has been escalated to %s.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context), new_section.name)
else:
msg = '%s has been escalated.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], 'System Notification', msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_close_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been closed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_cancel_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been canceled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_pending_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s is now pending.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
def case_reset_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = _('%s has been renewed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, context=context)
return True
diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py
index 3e3bdc90d08..36700b5b6c2 100644
--- a/addons/crm/crm_action_rule.py
+++ b/addons/crm/crm_action_rule.py
@@ -105,8 +105,8 @@ class base_action_rule(osv.osv):
write['email_cc'] = obj.act_email_cc
# Put state change by rule in communication history
- if hasattr(obj, 'state') and hasattr(obj, 'message_append') and action.act_state:
- model_obj.message_append(cr, uid, [obj], _(action.act_state))
+ if hasattr(obj, 'state') and hasattr(obj, 'message_post') and action.act_state:
+ model_obj.message_post(cr, uid, [obj], _(action.act_state), context=context)
model_obj.write(cr, uid, [obj.id], write, context)
super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context)
diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml
index e5f067c1075..52d779f4584 100644
--- a/addons/crm/crm_data.xml
+++ b/addons/crm/crm_data.xml
@@ -55,13 +55,13 @@
-
-
+
+
- Module CRM has been installedFrom the top menu Sales, you can: trace leads and opportunities, get accurate forecast on your sales pipeline, plan meetings and phonecalls, get realtime statistics and efficiently organize the communication with your prospects.
To manage quotations and sale orders, install the module "Sales Management".
+ Module CRM has been installed
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index c4423520847..b725a4ad988 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -19,11 +19,9 @@
#
##############################################################################
-import binascii
from base_status.base_stage import base_stage
import crm
from datetime import datetime
-from mail.mail_message import to_email
from osv import fields, osv
import time
import tools
@@ -40,8 +38,7 @@ class crm_lead(base_stage, osv.osv):
_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "priority,date_action,id desc"
- _inherit = ['ir.needaction_mixin', 'mail.thread']
- _mail_compose_message = True
+ _inherit = ['mail.thread','ir.needaction_mixin']
def _get_default_section_id(self, cr, uid, context=None):
""" Gives default section by checking if present in the context """
@@ -175,16 +172,6 @@ class crm_lead(base_stage, osv.osv):
else:
return [('id', '=', '0')]
- def _get_email_subject(self, cr, uid, ids, fields, args, context=None):
- res = {}
- for obj in self.browse(cr, uid, ids, context=context):
- res[obj.id] = ''
- for msg in obj.message_ids:
- if msg.email_from:
- res[obj.id] = msg.subject
- break
- return res
-
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null',
select=True, help="Optional linked partner, usually after conversion of the lead"),
@@ -228,7 +215,6 @@ class crm_lead(base_stage, osv.osv):
When the case is over, the state is set to \'Done\'.\
If the case needs to be reviewed then the state is \
set to \'Pending\'.'),
- 'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64),
# Only used for type opportunity
'probability': fields.float('Success Rate (%)',group_operator="avg"),
@@ -278,9 +264,9 @@ class crm_lead(base_stage, osv.osv):
def create(self, cr, uid, vals, context=None):
obj_id = super(crm_lead, self).create(cr, uid, vals, context)
- record = self.browse(cr, uid, obj_id, context)
- if record.user_id:
- self.message_subscribe(cr, uid, [obj_id], [record.user_id.id], context = context)
+# record = self.browse(cr, uid, obj_id, context)
+# if record.user_id:
+# self.message_subscribe(cr, uid, [obj_id], [record.user_id.id], context = context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
@@ -452,7 +438,7 @@ class crm_lead(base_stage, osv.osv):
oldest_id = opportunity_ids[0]
return self.browse(cr, uid, oldest_id, context=context)
- def _mail_body_text(self, cr, uid, lead, fields, title=False, context=None):
+ def _mail_body(self, cr, uid, lead, fields, title=False, context=None):
body = []
if title:
body.append("%s\n" % (title))
@@ -489,11 +475,11 @@ class crm_lead(base_stage, osv.osv):
for opportunity in opportunities:
subject.append(opportunity.name)
title = "%s : %s" % (merge_message, opportunity.name)
- details.append(self._mail_body_text(cr, uid, opportunity, fields, title=title, context=context))
+ details.append(self._mail_body(cr, uid, opportunity, fields, title=title, context=context))
subject = subject[0] + ", ".join(subject[1:])
details = "\n\n".join(details)
- return self.message_append_note(cr, uid, [opportunity_id], subject=subject, body=details)
+ return self.message_post(cr, uid, [opportunity_id], body=details, subject=subject, context=context)
def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None):
message = self.pool.get('mail.message')
@@ -549,7 +535,7 @@ class crm_lead(base_stage, osv.osv):
oldest = self._merge_find_oldest(cr, uid, ids, context=context)
if ctx_opportunities :
first_opportunity = ctx_opportunities[0]
- tail_opportunities = opportunities_list
+ tail_opportunities = opportunities_list + ctx_opportunities[1:]
else:
first_opportunity = opportunities_list[0]
tail_opportunities = opportunities_list[1:]
@@ -609,19 +595,22 @@ class crm_lead(base_stage, osv.osv):
for lead in self.browse(cr, uid, ids, context=context):
if lead.state in ('done', 'cancel'):
continue
- if user_ids or section_id:
- self.allocate_salesman(cr, uid, [lead.id], user_ids, section_id, context=context)
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
self.write(cr, uid, [lead.id], vals, context=context)
self.convert_opportunity_send_note(cr, uid, lead, context=context)
#TOCHECK: why need to change partner details in all messages of lead ?
- if lead.partner_id:
- msg_ids = [ x.id for x in lead.message_ids]
- mail_message.write(cr, uid, msg_ids, {
- 'partner_id': lead.partner_id.id
- }, context=context)
+ # TDE FIXME: I propose to delete this, makes no sense to update partner of an already-send email ...
+ # if lead.partner_id:
+ # msg_ids = [x.id for x in lead.message_ids]
+ # mail_message.write(cr, uid, msg_ids, {
+ # 'partner_id': lead.partner_id.id
+ # }, context=context)
+
+ if user_ids or section_id:
+ self.allocate_salesman(cr, uid, ids, user_ids, section_id, context=context)
+
return True
def _lead_create_contact(self, cr, uid, lead, name, is_company, parent_id=False, context=None):
@@ -633,7 +622,7 @@ class crm_lead(base_stage, osv.osv):
'parent_id': parent_id,
'phone': lead.phone,
'mobile': lead.mobile,
- 'email': lead.email_from and to_email(lead.email_from)[0],
+ 'email': lead.email_from and tools.email_split(lead.email_from)[0],
'fax': lead.fax,
'title': lead.title and lead.title.id or False,
'function': lead.function,
@@ -653,7 +642,7 @@ class crm_lead(base_stage, osv.osv):
partner_id = False
if lead.partner_name and lead.contact_name:
partner_id = self._lead_create_contact(cr, uid, lead, lead.partner_name, True, context=context)
- self._lead_create_contact(cr, uid, lead, lead.contact_name, False, partner_id, context=context)
+ partner_id = self._lead_create_contact(cr, uid, lead, lead.contact_name, False, partner_id, context=context)
elif lead.partner_name and not lead.contact_name:
partner_id = self._lead_create_contact(cr, uid, lead, lead.partner_name, True, context=context)
elif not lead.partner_name and lead.contact_name:
@@ -681,10 +670,12 @@ class crm_lead(base_stage, osv.osv):
if context is None:
context = {}
partner_ids = {}
+ force_partner_id = partner_id
for lead in self.browse(cr, uid, ids, context=context):
if action == 'create':
if not partner_id:
partner_id = self._create_lead_partner(cr, uid, lead, context)
+ partner_id = force_partner_id or self._create_lead_partner(cr, uid, lead, context=context)
self._lead_set_partner(cr, uid, lead, partner_id, context=context)
partner_ids[lead.id] = partner_id
return partner_ids
@@ -824,14 +815,13 @@ class crm_lead(base_stage, osv.osv):
if custom_values is None: custom_values = {}
custom_values.update({
'name': msg.get('subject') or _("No Subject"),
- 'description': msg.get('body_text'),
+ 'description': msg.get('body'),
'email_from': msg.get('from'),
'email_cc': msg.get('cc'),
'user_id': False,
})
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
custom_values['priority'] = msg.get('priority')
- custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context))
return super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
@@ -844,18 +834,18 @@ class crm_lead(base_stage, osv.osv):
if update_vals is None: update_vals = {}
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
- vals['priority'] = msg.get('priority')
+ update_vals['priority'] = msg.get('priority')
maps = {
'cost':'planned_cost',
'revenue': 'planned_revenue',
'probability':'probability',
}
- for line in msg.get('body_text', '').split('\n'):
+ for line in msg.get('body', '').split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
key = maps.get(res.group(1).lower())
- vals[key] = res.group(2).lower()
+ update_vals[key] = res.group(2).lower()
return super(crm_lead, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
@@ -863,15 +853,10 @@ class crm_lead(base_stage, osv.osv):
# OpenChatter methods and notifications
# ----------------------------------------
- def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
- """ Add 'user_id' to the monitored fields """
- res = super(crm_lead, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
- return res + ['user_id']
-
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1]
- return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change",context=context)
+ return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change",context=context)
def case_get_note_msg_prefix(self, cr, uid, lead, context=None):
if isinstance(lead, (int, long)):
@@ -881,33 +866,33 @@ class crm_lead(base_stage, osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
for id in ids:
message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
- self.message_append_note(cr, uid, [id], body=message, subtype="new", context=context)
+ self.message_post(cr, uid, [id], body=message, subtype="new", context=context)
return True
def case_mark_lost_send_note(self, cr, uid, ids, context=None):
message = _("Opportunity has been lost.")
- return self.message_append_note(cr, uid, ids, body=message,subtype="lost", context=context)
+ return self.message_post(cr, uid, ids, body=message,subtype="lost", context=context)
def case_mark_won_send_note(self, cr, uid, ids, context=None):
message = _("Opportunity has been won.")
- return self.message_append_note(cr, uid, ids, body=message, subtype="won", context=context)
+ return self.message_post(cr, uid, ids, body=message, subtype="won", context=context)
def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None):
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0]
if action == 'log': prefix = 'Logged'
else: prefix = 'Scheduled'
message = _("%s a call for the %s.") % (prefix, phonecall.date)
- return self.message_append_note(cr, uid, ids, body=message, context=context)
+ return self.message_post(cr, uid, ids, body=message, context=context)
def _lead_set_partner_send_note(self, cr, uid, ids, context=None):
for lead in self.browse(cr, uid, ids, context=context):
message = _("%s partner is now set to %s." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name))
- lead.message_append_note(body=message)
+ lead.message_post(body=message)
return True
def convert_opportunity_send_note(self, cr, uid, lead, context=None):
message = _("Lead has been converted to an opportunity.")
- lead.message_append_note(body=message)
+ lead.message_post(body=message)
return True
crm_lead()
diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml
index a274dadfe01..4442b22e77e 100644
--- a/addons/crm/crm_lead_demo.xml
+++ b/addons/crm/crm_lead_demo.xml
@@ -552,86 +552,67 @@ AndrewPlan to buy a Laptopcrm.lead
- html
- <![CDATA[Email0 inquiry]]><div><font size="2">Hello,</font></div><div><font size="2"><br></font></div><div><font size="2">I am interested in your company's product and I plan to buy a new laptop having latest technologies and affordable price.</font></div><div><font size="2">Can you please send me product catalogue?</font></div>
+ <![CDATA[Email0 inquiry]]><div><font size="2">Hello,</font></div><div><font size="2"><br></font></div><div><font size="2">I am interested in your company's product and I plan to buy a new laptop having latest technologies and affordable price.</font></div><div><font size="2">Can you please send me product catalogue?</font></div>email
- received
- Re: Plan to buy a Laptopcrm.lead
-
- plain
- Dear Customer,
+ comment
+ Dear Customer,
Thanks for showing interest in our products.
We have attached the catalogue,
We would like to know your interests, Let us know if we can call you for more details.
Thanks
- email
-
- sent
+
+ Re: Plan to buy a Laptopcrm.lead
- html
- <div>Thanks for the information,</div><div>I will visit the store soon.</div>
+ comment
+ <div>Thanks for the information,</div><div>I will visit the store soon.</div>
- email
-
- received
+ Re: Plan to buy a Laptopcrm.lead
- html
- <font color="#1f1f1f">Can you tell me if the store is open at 9:00 PM?</b></font>
+ comment
+ <font color="#1f1f1f">Can you tell me if the store is open at 9:00 PM?</b></font>
- email
- received
-
+ Re: Plan to buy a Laptopcrm.lead
- plain
- Yes, its open till 10:00 PM, you are welcome!
+ Yes, its open till 10:00 PM, you are welcome!email
- sent
-
+
-
Inquirycrm.lead
- plain
- Hello,
+ Hello,
I am Jason from Le Club SARL,
I am intertested to attend Training organized in your company,
Can you send details,email
- received
-
-
Need Detailscrm.lead
- plain
- Want to know features and benifits to use the new software.
+ Want to know features and benifits to use the new software.comment
-
-
Leadscrm.lead
-
+
@@ -261,8 +261,7 @@
-
-
+
@@ -296,7 +295,7 @@
-
+
@@ -342,7 +341,6 @@
@@ -362,10 +360,8 @@
-
-
-
+
@@ -545,7 +541,7 @@
Opportunities Treecrm.lead
-
+
@@ -555,7 +551,6 @@
-
@@ -563,7 +558,7 @@
-
+
@@ -578,7 +573,7 @@
-
+
diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py
index 13171d95b9b..62fc53364ee 100644
--- a/addons/crm/crm_meeting.py
+++ b/addons/crm/crm_meeting.py
@@ -44,7 +44,7 @@ class crm_meeting(osv.Model):
def create_send_note(self, cr, uid, ids, context=None):
if context is None:
context = {}
- # update context: if come from phonecall, default state values can make the message_append_note crash
+ # update context: if come from phonecall, default state values can make the message_post crash
context.pop('default_state', False)
for meeting in self.browse(cr, uid, ids, context=context):
# in the message, transpose meeting.date to the timezone of the current user
@@ -53,14 +53,14 @@ class crm_meeting(osv.Model):
if meeting.opportunity_id: # meeting can be create from phonecalls or opportunities, therefore checking for the parent
lead = meeting.opportunity_id
message = _("Meeting linked to the opportunity %s has been created and scheduled on %s.") % (lead.name, meeting_date_tz)
- lead.message_append_note(_('System Notification'), message)
+ lead.message_post(body=message)
elif meeting.phonecall_id:
phonecall = meeting.phonecall_id
message = _("Meeting linked to the phonecall %s has been created and scheduled on %s.") % (phonecall.name, meeting_date_tz)
- phonecall.message_append_note(body=message)
+ phonecall.message_post(body=message)
else:
message = _("A meeting has been scheduled on %s.") % (meeting_date_tz)
- meeting.message_append_note(body=message)
+ meeting.message_post(body=message)
return True
class calendar_attendee(osv.osv):
diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py
index da08f97250a..44894fc881d 100644
--- a/addons/crm/crm_phonecall.py
+++ b/addons/crm/crm_phonecall.py
@@ -32,7 +32,7 @@ class crm_phonecall(base_state, osv.osv):
_name = "crm.phonecall"
_description = "Phonecall"
_order = "id desc"
- _inherit = ['ir.needaction_mixin', 'mail.thread']
+ _inherit = ['mail.thread']
_columns = {
# base_state required fields
'date_action_last': fields.datetime('Last Action', readonly=1),
@@ -177,11 +177,11 @@ class crm_phonecall(base_state, osv.osv):
if context is None:
context = {}
partner_ids = {}
+ force_partner_id = partner_id
for call in self.browse(cr, uid, ids, context=context):
if action == 'create':
- if not partner_id:
- partner_id = self._call_create_partner(cr, uid, call, context=context)
- self._call_create_partner_address(cr, uid, call, partner_id, context=context)
+ partner_id = force_partner_id or self._call_create_partner(cr, uid, call, context=context)
+ self._call_create_partner_address(cr, uid, call, partner_id, context=context)
self._call_set_partner(cr, uid, [call.id], partner_id, context=context)
partner_ids[call.id] = partner_id
return partner_ids
@@ -266,7 +266,7 @@ class crm_phonecall(base_state, osv.osv):
def case_reset_send_note(self, cr, uid, ids, context=None):
message = _('Phonecall has been reset and set as open.')
- return self.message_append_note(cr, uid, ids, body=message, context=context)
+ return self.message_post(cr, uid, ids, body=message, context=context)
def case_open_send_note(self, cr, uid, ids, context=None):
lead_obj = self.pool.get('crm.lead')
@@ -280,11 +280,11 @@ class crm_phonecall(base_state, osv.osv):
message = _("Phonecall linked to the opportunity %s has been created and scheduled on %s.") % (lead.name, phonecall_date_str)
else:
message = _("Phonecall has been created and opened.")
- phonecall.message_append_note(body=message)
+ phonecall.message_post(body=message)
return True
def _call_set_partner_send_note(self, cr, uid, ids, context=None):
- return self.message_append_note(cr, uid, ids, body=_("Partner has been created."), context=context)
+ return self.message_post(cr, uid, ids, body=_("Partner has been created."), context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 3b5162288a4..2f885e09b61 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -66,8 +66,7 @@
CRM - Phone Calls Treecrm.phonecall
-
-
+
@@ -76,7 +75,6 @@
- crm.phonecall
-
+
-
diff --git a/addons/crm/wizard/crm_lead_to_partner.py b/addons/crm/wizard/crm_lead_to_partner.py
index 98f114b4088..9b239bab7b9 100644
--- a/addons/crm/wizard/crm_lead_to_partner.py
+++ b/addons/crm/wizard/crm_lead_to_partner.py
@@ -50,20 +50,20 @@ class crm_lead2partner(osv.osv_memory):
def _select_partner(self, cr, uid, context=None):
if context is None:
context = {}
- lead = self.pool.get('crm.lead')
- partner = self.pool.get('res.partner')
- lead_ids = list(context and context.get('active_ids', []) or [])
- if not len(lead_ids):
+ if not context.get('active_model') == 'crm.lead' or not context.get('active_id'):
return False
- this = lead.browse(cr, uid, lead_ids[0], context=context)
- # Find partner address matches the email_from of the lead
- res = lead.message_partner_by_email(cr, uid, this.email_from, context=context)
- partner_id = res.get('partner_id', False)
- # Find partner name that matches the name of the lead
- if not partner_id and this.partner_name:
+ partner = self.pool.get('res.partner')
+ lead = self.pool.get('crm.lead')
+ this = lead.browse(cr, uid, context.get('active_id'), context=context)
+ partner_id = False
+ if this.email_from:
+ partner_ids = partner.search(cr, uid, [('email', '=', this.email_from)], context=context)
+ if partner_ids:
+ partner_id = partner_ids[0]
+ if not this.partner_id and this.partner_name:
partner_ids = partner.search(cr, uid, [('name', '=', this.partner_name)], context=context)
- if partner_ids and len(partner_ids):
- partner_id = partner_ids[0]
+ if partner_ids:
+ partner_id = partner_ids[0]
return partner_id
def default_get(self, cr, uid, fields, context=None):
@@ -107,15 +107,16 @@ class crm_lead2partner(osv.osv_memory):
lead_ids = context and context.get('active_ids') or []
data = self.browse(cr, uid, ids, context=context)[0]
partner_id = data.partner_id and data.partner_id.id or False
- partner_ids = lead.convert_partner(cr, uid, lead_ids, data.action, partner_id, context=context)
- return partner_ids[lead_ids[0]]
+ return lead.convert_partner(cr, uid, lead_ids, data.action, partner_id, context=context)
def make_partner(self, cr, uid, ids, context=None):
"""
This function Makes partner based on action.
"""
- partner_id = self._create_partner(cr, uid, ids, context=context)
- return self.pool.get('res.partner').redirect_partner_form(cr, uid, partner_id, context=context)
+ # Only called from Form view, so only meant to convert one Lead.
+ lead_id = context and context.get('active_id') or False
+ partner_ids_map = self._create_partner(cr, uid, ids, context=context)
+ return self.pool.get('res.partner').redirect_partner_form(cr, uid, partner_ids_map.get(lead_id, False), context=context)
crm_lead2partner()
diff --git a/addons/crm/wizard/crm_phonecall_to_partner.py b/addons/crm/wizard/crm_phonecall_to_partner.py
index 422af02f99d..715b7396c66 100644
--- a/addons/crm/wizard/crm_phonecall_to_partner.py
+++ b/addons/crm/wizard/crm_phonecall_to_partner.py
@@ -57,12 +57,10 @@ class crm_phonecall2partner(osv.osv_memory):
if context is None:
context = {}
phonecall = self.pool.get('crm.phonecall')
-
data = self.browse(cr, uid, ids, context=context)[0]
call_ids = context and context.get('active_ids') or []
partner_id = data.partner_id and data.partner_id.id or False
- partner_ids = phonecall.convert_partner(cr, uid, call_ids, data.action, partner_id, context=context)
- return partner_ids[call_ids[0]]
+ return phonecall.convert_partner(cr, uid, call_ids, data.action, partner_id, context=context)
crm_phonecall2partner()
diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py
index ec6252bcdca..535f6d20367 100644
--- a/addons/crm_claim/crm_claim.py
+++ b/addons/crm_claim/crm_claim.py
@@ -72,7 +72,7 @@ class crm_claim(base_stage, osv.osv):
_description = "Claim"
_order = "priority,date desc"
_inherit = ['mail.thread']
- _mail_compose_message = True
+
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Claim Subject', size=128, required=True),
@@ -194,13 +194,12 @@ class crm_claim(base_stage, osv.osv):
if custom_values is None: custom_values = {}
custom_values.update({
'name': msg.get('subject') or _("No Subject"),
- 'description': msg.get('body_text'),
+ 'description': msg.get('body'),
'email_from': msg.get('from'),
'email_cc': msg.get('cc'),
})
if msg.get('priority'):
custom_values['priority'] = msg.get('priority')
- custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from'), context=context))
return super(crm_claim,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
@@ -220,7 +219,7 @@ class crm_claim(base_stage, osv.osv):
'revenue': 'planned_revenue',
'probability':'probability'
}
- for line in msg['body_text'].split('\n'):
+ for line in msg['body'].split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
@@ -239,16 +238,16 @@ class crm_claim(base_stage, osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
msg = _('Claim has been created.')
- return self.message_append_note(cr, uid, ids, body=msg, context=context)
+ return self.message_post(cr, uid, ids, body=msg, context=context)
def case_refuse_send_note(self, cr, uid, ids, context=None):
msg = _('Claim has been refused.')
- return self.message_append_note(cr, uid, ids, body=msg, context=context)
+ return self.message_post(cr, uid, ids, body=msg, context=context)
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
stage_name = self.pool.get('crm.claim.stage').name_get(cr, uid, [stage_id], context=context)[0][1]
- return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context)
+ return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context)
class res_partner(osv.osv):
diff --git a/addons/crm_claim/test/ui/claim_demo.yml b/addons/crm_claim/test/ui/claim_demo.yml
index ad8fdf3aa44..6b6d380f5be 100644
--- a/addons/crm_claim/test/ui/claim_demo.yml
+++ b/addons/crm_claim/test/ui/claim_demo.yml
@@ -9,7 +9,7 @@
-
!python {model: crm.claim}: |
try:
- self.message_update(cr, uid,[ref('crm_claim_4')], {'subject': 'Claim Update record','body_text': 'first training session completed',})
+ self.message_update(cr, uid,[ref('crm_claim_4')], {'subject': 'Claim Update record','body': 'first training session completed',})
except:
pass
-
\ No newline at end of file
+
diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py
index 4b0cb2e3ffa..612537bdb77 100644
--- a/addons/crm_helpdesk/crm_helpdesk.py
+++ b/addons/crm_helpdesk/crm_helpdesk.py
@@ -38,7 +38,7 @@ class crm_helpdesk(base_state, osv.osv):
_description = "Helpdesk"
_order = "id desc"
_inherit = ['mail.thread']
- _mail_compose_message = True
+
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True),
@@ -105,12 +105,11 @@ class crm_helpdesk(base_state, osv.osv):
if custom_values is None: custom_values = {}
custom_values.update({
'name': msg.get('subject') or _("No Subject"),
- 'description': msg.get('body_text'),
+ 'description': msg.get('body'),
'email_from': msg.get('from'),
'email_cc': msg.get('cc'),
'user_id': False,
})
- custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from'), context=context))
return super(crm_helpdesk,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
@@ -130,7 +129,7 @@ class crm_helpdesk(base_state, osv.osv):
'revenue': 'planned_revenue',
'probability':'probability'
}
- for line in msg['body_text'].split('\n'):
+ for line in msg['body'].split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower()):
@@ -149,7 +148,7 @@ class crm_helpdesk(base_state, osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
msg = _('Case has been created.')
- self.message_append_note(cr, uid, ids, body=msg, context=context)
+ self.message_post(cr, uid, ids, body=msg, context=context)
return True
diff --git a/addons/crm_helpdesk/report/crm_helpdesk_report.py b/addons/crm_helpdesk/report/crm_helpdesk_report.py
index 93a33d62819..6496935c2d2 100644
--- a/addons/crm_helpdesk/report/crm_helpdesk_report.py
+++ b/addons/crm_helpdesk/report/crm_helpdesk_report.py
@@ -97,7 +97,7 @@ class crm_helpdesk_report(osv.osv):
c.planned_cost,
count(*) as nbr,
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
- (SELECT count(id) FROM mail_message WHERE model='crm.helpdesk' AND res_id=c.id AND email_from IS NOT NULL) AS email,
+ (SELECT count(id) FROM mail_message WHERE model='crm.helpdesk' AND res_id=c.id AND type = 'email') AS email,
abs(avg(extract('epoch' from (c.date_deadline - c.date_closed)))/(3600*24)) as delay_expected
from
crm_helpdesk c
diff --git a/addons/crm_helpdesk/test/process/help-desk.yml b/addons/crm_helpdesk/test/process/help-desk.yml
index 320bd61c2af..4fd6a9ee9d7 100644
--- a/addons/crm_helpdesk/test/process/help-desk.yml
+++ b/addons/crm_helpdesk/test/process/help-desk.yml
@@ -23,7 +23,7 @@
!python {model: crm.helpdesk}: |
question_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
try:
- self.message_update(cr, uid, question_ids, {'subject': 'Link of product', 'body_text': 'www.openerp.com'})
+ self.message_update(cr, uid, question_ids, {'subject': 'Link of product', 'body': 'www.openerp.com'})
except:
pass
diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml
index d4ff93d52fd..057d5240847 100644
--- a/addons/crm_partner_assign/crm_lead_view.xml
+++ b/addons/crm_partner_assign/crm_lead_view.xml
@@ -19,8 +19,7 @@
attrs="{'invisible':[('partner_assigned_id','=',False)]}"
name="%(crm_lead_forward_to_partner_act)d"
icon="terp-mail-forward" type="action"
- context="{'default_name': 'partner', 'default_partner_id': partner_assigned_id}"
- />
+ context="{'mail.compose.message.mode': 'forward', 'default_partner_ids': [partner_assigned_id]}"/>
@@ -37,8 +36,6 @@
-
-
crm.lead.geo_assign.tree.inheritcrm.lead
@@ -49,6 +46,7 @@
+
crm.opportunity.partner.filter.assignedcrm.lead
@@ -63,5 +61,6 @@
+
diff --git a/addons/crm_partner_assign/i18n/crm_partner_assign.pot b/addons/crm_partner_assign/i18n/crm_partner_assign.pot
index 3fb9fc0e915..c3ddc66fa3b 100644
--- a/addons/crm_partner_assign/i18n/crm_partner_assign.pot
+++ b/addons/crm_partner_assign/i18n/crm_partner_assign.pot
@@ -72,7 +72,7 @@ msgid "Geo Localize"
msgstr ""
#. module: crm_partner_assign
-#: help:crm.lead.forward.to.partner,body_text:0
+#: help:crm.lead.forward.to.partner,body:0
msgid "Plain-text version of the message"
msgstr ""
@@ -129,7 +129,7 @@ msgid "Highest"
msgstr ""
#. module: crm_partner_assign
-#: field:crm.lead.forward.to.partner,body_text:0
+#: field:crm.lead.forward.to.partner,body:0
msgid "Text contents"
msgstr ""
diff --git a/addons/crm_partner_assign/test/partner_assign.yml b/addons/crm_partner_assign/test/partner_assign.yml
index bc4cd0d6e57..a055fc6cd6d 100644
--- a/addons/crm_partner_assign/test/partner_assign.yml
+++ b/addons/crm_partner_assign/test/partner_assign.yml
@@ -29,8 +29,8 @@
I forward this opportunity to its nearest partner.
-
!python {model: crm.lead.forward.to.partner}: |
- context.update({'active_model': 'crm.lead', 'active_id': ref('crm.crm_case_19'), 'active_ids': [ref('crm.crm_case_19')]})
- forward_id = self.create(cr, uid, {'email_from': 'test@openerp.com', 'send_to': 'partner'}, context=context)
+ context.update({'default_model': 'crm.lead', 'default_res_id': ref('crm.crm_case_19'), 'active_ids': [ref('crm.crm_case_19')]})
+ forward_id = self.create(cr, uid, {}, context=context)
try:
self.action_forward(cr, uid, [forward_id], context=context)
except:
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
index d479f8b1bd5..5b0fe97b015 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -20,186 +20,160 @@
#
##############################################################################
-import time
import re
+import time
+import tools
+
from osv import osv, fields
from tools.translate import _
-from mail.mail_message import to_email
class crm_lead_forward_to_partner(osv.osv_memory):
- """Forwards lead history"""
+ """ Forward info history to partners. """
_name = 'crm.lead.forward.to.partner'
_inherit = "mail.compose.message"
+ def default_get(self, cr, uid, fields, context=None):
+ if context is None:
+ context = {}
+ # set as comment, perform overrided document-like action that calls get_record_data
+ old_mode = context.get('mail.compose.message.mode', 'forward')
+ context['mail.compose.message.mode'] = 'comment'
+ res = super(crm_lead_forward_to_partner, self).default_get(cr, uid, fields, context=context)
+ # back to forward mode
+ context['mail.compose.message.mode'] = old_mode
+ res['composition_mode'] = context['mail.compose.message.mode']
+ return res
+
+ def _get_composition_mode_selection(self, cr, uid, context=None):
+ composition_mode = super(crm_lead_forward_to_partner, self)._get_composition_mode_selection(cr, uid, context=context)
+ composition_mode.append(('forward', 'Forward'))
+ return composition_mode
+
_columns = {
- 'send_to': fields.selection([('user', 'User'), ('partner', 'Partner'), \
- ('email', 'Email Address')], 'Send to', required=True),
- 'user_id': fields.many2one('res.users', "User"),
- 'attachment_ids': fields.many2many('ir.attachment','lead_forward_to_partner_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
- 'partner_id' : fields.many2one('res.partner', 'Partner'),
- 'history': fields.selection([('info', 'Case Information'), ('latest', 'Latest email'), ('whole', 'Whole Story')], 'Send history', required=True),
+ 'partner_ids': fields.many2many('res.partner',
+ 'lead_forward_to_partner_res_partner_rel',
+ 'wizard_id', 'partner_id', 'Additional contacts'),
+ 'attachment_ids': fields.many2many('ir.attachment',
+ 'lead_forward_to_partner_attachment_rel',
+ 'wizard_id', 'attachment_id', 'Attachments'),
+ 'history_mode': fields.selection([('info', 'Case Information'),
+ ('latest', 'Latest email'), ('whole', 'Whole Story')],
+ 'Send history', required=True),
}
_defaults = {
- 'send_to' : 'email',
- 'history': 'latest',
- 'email_from': lambda s, cr, uid, c: s.pool.get('res.users').browse(cr, uid, uid, c).email,
+ 'history_mode': 'latest',
+ 'content_subtype': lambda self,cr, uid, context={}: 'html',
}
- def on_change_email(self, cr, uid, ids, user, context=None):
- if not user:
- return {'value': {'email_to': False}}
- return {'value': {'email_to': self.pool.get('res.users').browse(cr, uid, uid, context=context).email}}
-
- def on_change_history(self, cr, uid, ids, history_type, context=None):
- """Gives message body according to type of history selected
- * info: Forward the case information
- * whole: Send the whole history
- * latest: Send the latest histoy
+ def get_record_data(self, cr, uid, model, res_id, context=None):
+ """ Override of mail.compose.message, to add default values coming
+ form the related lead.
"""
- #TODO: ids and context are not comming
- res = {}
- res_id = context.get('active_id')
- model = context.get('active_model')
- lead = self.pool.get(model).browse(cr, uid, res_id, context)
- body_text = self._get_message_body_text(cr, uid, lead, history_type, context=context)
- if body_text:
- res = {'value': {'body_text' : body_text}}
+ res = super(crm_lead_forward_to_partner, self).get_record_data(cr, uid, model, res_id, context=context)
+ if model not in ('crm.lead') or not res_id:
+ return res
+ lead_obj = self.pool.get(model)
+ lead = lead_obj.browse(cr, uid, res_id, context=context)
+ subject = '%s: %s - %s' % (_('Fwd'), _('Lead forward'), lead.name)
+ body = self._get_message_body(cr, uid, lead, 'info', context=context)
+ res.update({
+ 'subject': subject,
+ 'body': body,
+ })
return res
+
+ def on_change_history_mode(self, cr, uid, ids, history_mode, model, res_id, context=None):
+ """ Update body when changing history_mode """
+ if model and model == 'crm.lead' and res_id:
+ lead = self.pool.get(model).browse(cr, uid, res_id, context=context)
+ body = self._get_message_body(cr, uid, lead, history_mode, context=context)
+ return {'value': {'body': body}}
- def on_change_partner(self, cr, uid, ids, partner_id):
- """This function fills address information based on partner/user selected
- """
- if not partner_id:
- return {'value' : {'email_to' : False}}
- partner_obj = self.pool.get('res.partner')
- data = {}
- partner = partner_obj.browse(cr, uid, [partner_id])
- user_id = partner and partner[0].user_id or False
- data.update({'email_from': partner and partner[0].email or "",
- 'email_cc' : user_id and user_id.user or '',
- 'user_id': user_id and user_id.id or False})
- return {'value' : data}
+ def on_change_partner_ids(self, cr, uid, ids, partner_ids, context=None):
+ """ TDE-TODO: Keep void; maybe we could check that partner_ids have
+ email defined. """
+ return {}
+
+ def create(self, cr, uid, values, context=None):
+ """ TDE-HACK: remove 'type' from context, because when viewing an
+ opportunity form view, a default_type is set and propagated
+ to the wizard, that has a not matching type field. """
+ default_type = context.pop('default_type', None)
+ new_id = super(crm_lead_forward_to_partner, self).create(cr, uid, values, context=context)
+ if default_type:
+ context['default_type'] = default_type
+ return new_id
def action_forward(self, cr, uid, ids, context=None):
"""
- Forward the lead to a partner
+ Forward the lead to a partner
"""
if context is None:
context = {}
res = {'type': 'ir.actions.act_window_close'}
- model = context.get('active_model')
- if model not in ('crm.lead'):
+ wizard = self.browse(cr, uid, ids[0], context=context)
+ if wizard.model not in ('crm.lead'):
return res
- this = self.browse(cr, uid, ids[0], context=context)
- lead = self.pool.get(model)
- lead_id = context and context.get('active_id', False) or False
- lead_ids = lead_id and [lead_id] or []
- mode = context.get('mail.compose.message.mode')
- if mode == 'mass_mail':
+ lead = self.pool.get(wizard.model)
+ lead_ids = wizard.res_id and [wizard.res_id] or []
+
+ if wizard.composition_mode == 'mass_mail':
lead_ids = context and context.get('active_ids', []) or []
- value = self.default_get(cr, uid, ['body_text', 'email_to', 'email_cc', 'subject', 'history'], context=context)
+ value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history_mode'], context=context)
self.write(cr, uid, ids, value, context=context)
- context['mail.compose.message.mode'] = mode
self.send_mail(cr, uid, ids, context=context)
- for case in lead.browse(cr, uid, lead_ids, context=context):
- if (this.send_to == 'partner' and this.partner_id):
- lead.assign_partner(cr, uid, [case.id], this.partner_id.id, context=context)
+ # for case in lead.browse(cr, uid, lead_ids, context=context):
+ # TDE: WHAT TO DO WITH THAT ?
+ # if (this.send_to == 'partner' and this.partner_id):
+ # lead.assign_partner(cr, uid, [case.id], this.partner_id.id, context=context)
- if this.send_to == 'user':
- lead.allocate_salesman(cr, uid, [case.id], [this.user_id.id], context=context)
-
- email_cc = to_email(case.email_cc)
- email_cc = email_cc and email_cc[0] or ''
- new_cc = []
- if email_cc:
- new_cc.append(email_cc)
- for to in this.email_to.split(','):
- email_to = to_email(to)
- email_to = email_to and email_to[0] or ''
- if email_to not in new_cc:
- new_cc.append(to)
- update_vals = {'email_cc' : ', '.join(new_cc) }
- lead.write(cr, uid, [case.id], update_vals, context=context)
+ # if this.send_to == 'user':
+ # lead.allocate_salesman(cr, uid, [case.id], [this.user_id.id], context=context)
return res
- def _get_info_body_text(self, cr, uid, lead, context=None):
+ def _get_info_body(self, cr, uid, lead, context=None):
field_names = []
proxy = self.pool.get(lead._name)
if lead.type == 'opportunity':
field_names += ['partner_id']
field_names += [
- 'partner_name' , 'title', 'function', 'street', 'street2',
+ 'partner_name' , 'title', 'function', 'street', 'street2',
'zip', 'city', 'country_id', 'state_id', 'email_from',
'phone', 'fax', 'mobile', 'categ_id', 'description',
]
- return proxy._mail_body_text(cr, uid, lead, field_names, context=context)
+ return proxy._mail_body(cr, uid, lead, field_names, context=context)
- def _get_message_body_text(self, cr, uid, lead, mode='whole', context=None):
- """This function gets whole communication history and returns as top posting style
+ def _get_message_body(self, cr, uid, lead, history_mode='whole', context=None):
+ """ This function gets whole communication history and returns as top
+ posting style
+ #1: form a body, based on the lead
+ #2: append to the body the communication history, based on the
+ history_mode parameter
+
+ - info: Forward the case information
+ - latest: Send the latest history
+ - whole: Send the whole history
+
+ :param lead: browse_record on crm.lead
+ :param history_mode: 'whole' or 'latest'
"""
mail_message = self.pool.get('mail.message')
- message_ids = []
- body = self._get_info_body_text(cr, uid, lead, context=context)
- if mode in ('whole', 'latest'):
- message_ids = lead.message_ids
- message_ids = map(lambda x: x.id, filter(lambda x: x.email_from, message_ids))
- if mode == 'latest' and len(message_ids):
- message_ids = [message_ids[0]]
- for message in mail_message.browse(cr, uid, message_ids, context=context):
- header = '-------- Original Message --------'
- sender = 'From: %s' %(message.email_from or '')
- to = 'To: %s' % (message.email_to or '')
- sentdate = 'Date: %s' % (message.date or '')
- desc = '\n%s'%(message.body_text)
- original = [header, sender, to, sentdate, desc, '\n']
- original = '\n'.join(original)
- body += original
+ body = self._get_info_body(cr, uid, lead, context=context)
+ if history_mode not in ('whole', 'latest'):
+ return body or ''
+ for message in lead.message_ids:
+ header = '-------- Original Message --------'
+ sentdate = 'Date: %s' % (message.date or '')
+ desc = '\n%s'%(message.body)
+ original = [header, sentdate, desc, '\n']
+ original = '\n'.join(original)
+ body += original
+ if history_mode == 'latest':
+ break
return body or ''
- def get_value(self, cr, uid, model, res_id, context=None):
- if context is None:
- context = {}
- res = super(crm_lead_forward_to_partner, self).get_value(cr, uid, model, res_id, context=context)
- if model not in ("crm.lead"):
- return res
- proxy = self.pool.get(model)
- partner = self.pool.get('res.partner')
- lead = proxy.browse(cr, uid, res_id, context=context)
- mode = context.get('mail.compose.message.mode')
- if mode == "forward":
- body_type = context.get('mail.compose.message.body')
- email_cc = res.get('email_cc', "")
- email = res.get('email_to', "")
- subject = '%s: %s - %s' % (_('Fwd'), 'Lead forward', lead.name)
- body = self._get_message_body_text(cr, uid, lead, body_type, context=context)
- partner_assigned_id = lead.partner_assigned_id and lead.partner_assigned_id.id or False
- user_id = False
- if not partner_assigned_id:
- partner_assigned_id = proxy.search_geo_partner(cr, uid, [lead.id], context=None).get(lead.id, False)
- if partner_assigned_id:
- assigned_partner = partner.browse(cr, uid, partner_assigned_id, context=context)
- user_id = assigned_partner.user_id and assigned_partner.user_id.id or False
- email_cc = assigned_partner.user_id and assigned_partner.user_id.email or ''
- email = assigned_partner.email
-
- res.update({
- 'subject' : subject,
- 'body_text' : body,
- 'email_cc' : email_cc,
- 'email_to' : email,
- 'partner_assigned_id': partner_assigned_id,
- 'user_id': user_id,
- })
- return res
-
- def default_get(self, cr, uid, fields, context=None):
- if context is None:
- context = {}
- context['mail.compose.message.mode'] = 'forward'
- context['mail.compose.message.body'] = 'info'
- return super(crm_lead_forward_to_partner, self).default_get(cr, uid, fields, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
index cecf73954e5..600bd301b3f 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
@@ -7,42 +7,31 @@
crm.lead.forward.to.partner
@@ -57,8 +46,6 @@
new
-
-
-
-
+ />
diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
index b43b7d19b85..9adab6d3976 100644
--- a/addons/email_template/email_template.py
+++ b/addons/email_template/email_template.py
@@ -38,7 +38,7 @@ except ImportError:
class email_template(osv.osv):
"Templates for sending email"
- _inherit = 'mail.message'
+ _inherit = 'mail.mail'
_name = "email.template"
_description = 'Email Templates'
_rec_name = 'name' # override mail.message's behavior
@@ -137,28 +137,27 @@ class email_template(osv.osv):
'model': fields.related('model_id','model', type='char', string='Related Document Model',
size=128, select=True, store=True, readonly=True),
# we need a separate m2m table to avoid ID collisions with the original mail.message entries
- 'attachment_ids': fields.many2many('ir.attachment', 'email_template_attachment_rel', 'email_template_id',
- 'attachment_id', 'Files to attach',
- help="You may attach files to this template, to be added to all "
- "emails created from this template"),
+ #'attachment_ids': fields.many2many('ir.attachment', 'email_template_attachment_rel', 'email_template_id',
+ # 'attachment_id', 'Files to attach',
+ # help="You may attach files to this template, to be added to all "
+ # "emails created from this template"),
# Overridden mail.message.common fields to make tooltips more appropriate:
- 'subject':fields.char('Subject', size=512, translate=True, help="Subject (placeholders may be used here)",),
+ #'subject':fields.char('Subject', size=512, translate=True, help="Subject (placeholders may be used here)",),
'email_from': fields.char('From', size=128, help="Sender address (placeholders may be used here)"),
'email_to': fields.char('To', size=256, help="Comma-separated recipient addresses (placeholders may be used here)"),
'email_cc': fields.char('Cc', size=256, help="Carbon copy recipients (placeholders may be used here)"),
- 'email_bcc': fields.char('Bcc', size=256, help="Blind carbon copy recipients (placeholders may be used here)"),
'reply_to': fields.char('Reply-To', size=250, help="Preferred response address (placeholders may be used here)"),
'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing Mail Server', readonly=False,
help="Optional preferred server for outgoing mails. If not set, the highest "
"priority one will be used."),
- 'body_text': fields.text('Text Contents', translate=True, help="Plaintext version of the message (placeholders may be used here)"),
+ #'body': fields.text('Text Contents', translate=True, help="Plaintext version of the message (placeholders may be used here)"),
'body_html': fields.text('Rich-text Contents', translate=True, help="Rich-text/HTML version of the message (placeholders may be used here)"),
- 'message_id': fields.char('Message-Id', size=256, help="Message-ID SMTP header to use in outgoing messages based on this template. "
- "Please note that this overrides the 'Resource Tracking' option, "
- "so if you simply need to track replies to outgoing emails, enable "
- "that option instead.\n"
- "Placeholders must be used here, as this value always needs to be unique!"),
+ #'message_id': fields.char('Message-Id', size=256, help="Message-ID SMTP header to use in outgoing messages based on this template. "
+ # "Please note that this overrides the 'Resource Tracking' option, "
+ # "so if you simply need to track replies to outgoing emails, enable "
+ # "that option instead.\n"
+ # "Placeholders must be used here, as this value always needs to be unique!"),
# Fake fields used to implement the placeholder assistant
'model_object_field': fields.many2one('ir.model.fields', string="Field",
@@ -301,12 +300,11 @@ class email_template(osv.osv):
context = {}
values = {
'subject': False,
- 'body_text': False,
+ 'body': False,
'body_html': False,
'email_from': False,
'email_to': False,
'email_cc': False,
- 'email_bcc': False,
'reply_to': False,
'auto_delete': False,
'model': False,
@@ -317,7 +315,6 @@ class email_template(osv.osv):
'message_id': False,
'state': 'outgoing',
'content_subtype': 'plain',
- 'partner_ids': [],
}
if not template_id:
return values
@@ -325,26 +322,19 @@ class email_template(osv.osv):
report_xml_pool = self.pool.get('ir.actions.report.xml')
template = self.get_email_template(cr, uid, template_id, res_id, context)
- for field in ['subject', 'body_text', 'body_html', 'email_from',
- 'email_to', 'email_cc', 'email_bcc', 'reply_to',
+ for field in ['subject', 'body', 'body_html', 'email_from',
+ 'email_to', 'email_cc', 'reply_to',
'message_id']:
values[field] = self.render_template(cr, uid, getattr(template, field),
template.model, res_id, context=context) \
or False
- # if email_to: find or create a partner
- if values['email_to']:
- partner_id = self.pool.get('mail.thread').message_partner_by_email(cr, uid, values['email_to'], context=context)['partner_id']
- if not partner_id:
- partner_id = self.pool.get('res.partner').name_create(cr, uid, values['email_to'], context=context)
- values['partner_ids'] = [partner_id]
-
if values['body_html']:
values.update(content_subtype='html')
if template.user_signature:
signature = self.pool.get('res.users').browse(cr, uid, uid, context).signature
- values['body_text'] += '\n\n' + signature
+ values['body'] += '\n\n' + signature
values.update(mail_server_id = template.mail_server_id.id or False,
auto_delete = template.auto_delete,
@@ -391,12 +381,12 @@ class email_template(osv.osv):
:returns: id of the mail.message that was created
"""
if context is None: context = {}
- mail_message = self.pool.get('mail.message')
+ mail_mail = self.pool.get('mail.mail')
ir_attachment = self.pool.get('ir.attachment')
values = self.generate_email(cr, uid, template_id, res_id, context=context)
assert 'email_from' in values, 'email_from is missing or empty after template rendering, send_mail() cannot proceed'
attachments = values.pop('attachments') or {}
- msg_id = mail_message.create(cr, uid, values, context=context)
+ msg_id = mail_mail.create(cr, uid, values, context=context)
# link attachments
attachment_ids = []
for fname, fcontent in attachments.iteritems():
@@ -404,15 +394,15 @@ class email_template(osv.osv):
'name': fname,
'datas_fname': fname,
'datas': fcontent,
- 'res_model': mail_message._name,
+ 'res_model': mail_mail._name,
'res_id': msg_id,
}
context.pop('default_type', None)
attachment_ids.append(ir_attachment.create(cr, uid, attachment_data, context=context))
if attachment_ids:
- mail_message.write(cr, uid, msg_id, {'attachment_ids': [(6, 0, attachment_ids)]}, context=context)
+ mail_mail.write(cr, uid, msg_id, {'attachment_ids': [(6, 0, attachment_ids)]}, context=context)
if force_send:
- mail_message.send(cr, uid, [msg_id], context=context)
+ mail_mail.send(cr, uid, [msg_id], context=context)
return msg_id
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/email_template/email_template_view.xml b/addons/email_template/email_template_view.xml
index a04790d1c1c..a03bd3351ed 100644
--- a/addons/email_template/email_template_view.xml
+++ b/addons/email_template/email_template_view.xml
@@ -19,12 +19,11 @@
-
-
+
diff --git a/addons/email_template/i18n/email_template.pot b/addons/email_template/i18n/email_template.pot
index 0990a940397..519755ac8f0 100644
--- a/addons/email_template/i18n/email_template.pot
+++ b/addons/email_template/i18n/email_template.pot
@@ -289,8 +289,8 @@ msgid "Add Signature"
msgstr ""
#. module: email_template
-#: help:email.template,body_text:0
-#: help:email_template.preview,body_text:0
+#: help:email.template,body:0
+#: help:email_template.preview,body:0
msgid "Plaintext version of the message (placeholders may be used here)"
msgstr ""
@@ -425,8 +425,8 @@ msgid "Cc"
msgstr ""
#. module: email_template
-#: field:email.template,body_text:0
-#: field:email_template.preview,body_text:0
+#: field:email.template,body:0
+#: field:email_template.preview,body:0
msgid "Text Contents"
msgstr ""
diff --git a/addons/email_template/wizard/email_template_preview.py b/addons/email_template/wizard/email_template_preview.py
index 4ef0e9fa156..2c1866a53c4 100644
--- a/addons/email_template/wizard/email_template_preview.py
+++ b/addons/email_template/wizard/email_template_preview.py
@@ -26,7 +26,6 @@ class email_template_preview(osv.osv_memory):
_inherit = "email.template"
_name = "email_template.preview"
_description = "Email Template Preview"
- _rec_name = "subject"
def _get_records(self, cr, uid, context=None):
"""
@@ -79,14 +78,13 @@ class email_template_preview(osv.osv_memory):
model = template.model
vals['email_to'] = self.render_template(cr, uid, template.email_to, model, res_id, context)
vals['email_cc'] = self.render_template(cr, uid, template.email_cc, model, res_id, context)
- vals['email_bcc'] = self.render_template(cr, uid, template.email_bcc, model, res_id, context)
vals['reply_to'] = self.render_template(cr, uid, template.reply_to, model, res_id, context)
vals['subject'] = self.render_template(cr, uid, template.subject, model, res_id, context)
- description = self.render_template(cr, uid, template.body_text, model, res_id, context) or ''
+ description = self.render_template(cr, uid, template.body, model, res_id, context) or ''
if template.user_signature:
signature = self.pool.get('res.users').browse(cr, uid, uid, context).signature
description += '\n' + signature
- vals['body_text'] = description
+ vals['body'] = description
if template.body_html:
vals['body_html'] = self.render_template(cr, uid, template.body_html, model, res_id, context) or ''
vals['report_name'] = self.render_template(cr, uid, template.report_name, model, res_id, context)
diff --git a/addons/email_template/wizard/email_template_preview_view.xml b/addons/email_template/wizard/email_template_preview_view.xml
index 39fb413fcde..708ca2b0406 100644
--- a/addons/email_template/wizard/email_template_preview_view.xml
+++ b/addons/email_template/wizard/email_template_preview_view.xml
@@ -12,14 +12,13 @@
-
-
+
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index 1b007a990c0..a05aa232453 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -135,10 +135,9 @@ class mail_compose_message(osv.osv_memory):
'name': template_name,
'email_from': record.email_from or False,
'subject': record.subject or False,
- 'body_text': record.body_text or False,
+ 'body': record.body or False,
'email_to': record.email_to or False,
'email_cc': record.email_cc or False,
- 'email_bcc': record.email_bcc or False,
'reply_to': record.reply_to or False,
'model_id': model_id or False,
'attachment_ids': [(6, 0, [att.id for att in record.attachment_ids])]
diff --git a/addons/email_template/wizard/mail_compose_message_view.xml b/addons/email_template/wizard/mail_compose_message_view.xml
index 0d4362d350e..dff6f4a3ad4 100644
--- a/addons/email_template/wizard/mail_compose_message_view.xml
+++ b/addons/email_template/wizard/mail_compose_message_view.xml
@@ -31,14 +31,14 @@
-
+
-
+
diff --git a/addons/event/email_template.xml b/addons/event/email_template.xml
index 2666ece9921..49738185547 100644
--- a/addons/event/email_template.xml
+++ b/addons/event/email_template.xml
@@ -7,7 +7,7 @@
${object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'}${object.email}Your registration at ${object.event_id.name}
-
+
hello ${object.name},
The event ${object.event_id.name} that you registered for is confirmed and will be held from ${object.event_id.date_begin} to ${object.event_id.date_end}. For any further information please contact our event department.
@@ -27,7 +27,7 @@
${object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'}${object.email}Your registration at ${object.event_id.name}
-
+
hello ${object.name},
We confirm you that your registration to the event ${object.event_id.name} has been recorded. You will automatically receive an email providing you more practical information (such as the schedule, the plan...) as soon as the event will be confirmed to be held.
diff --git a/addons/event/event.py b/addons/event/event.py
index 7f0c77661e4..763aa423378 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -19,10 +19,8 @@
#
##############################################################################
-import time
from osv import fields, osv
from tools.translate import _
-import decimal_precision as dp
from openerp import SUPERUSER_ID
class event_type(osv.osv):
@@ -49,11 +47,11 @@ class event_event(osv.osv):
_name = 'event.event'
_description = __doc__
_order = 'date_begin'
- _inherit = ['ir.needaction_mixin','mail.thread']
+ _inherit = ['mail.thread','ir.needaction_mixin']
def name_get(self, cr, uid, ids, context=None):
if not ids:
- return []
+ return []
res = []
for record in self.browse(cr, uid, ids, context=context):
date = record.date_begin.split(" ")[0]
@@ -99,7 +97,6 @@ class event_event(osv.osv):
return self.write(cr, uid, ids, {'state': 'done'}, context=context)
def check_registration_limits(self, cr, uid, ids, context=None):
- register_pool = self.pool.get('event.registration')
for self.event in self.browse(cr, uid, ids, context=context):
total_confirmed = self.event.register_current
if total_confirmed < self.event.register_min or total_confirmed > self.event.register_max and self.event.register_max!=0:
@@ -109,7 +106,7 @@ class event_event(osv.osv):
for event in self.browse(cr, uid, ids, context=context):
available_seats = event.register_avail
if available_seats and no_of_registration > available_seats:
- raise osv.except_osv(_('Warning!'),_("Only %d Seats are Available!") % (available_seats))
+ raise osv.except_osv(_('Warning!'),_("Only %d Seats are Available!") % (available_seats))
elif available_seats == 0:
raise osv.except_osv(_('Warning!'),_("No Tickets Available!"))
@@ -139,7 +136,6 @@ class event_event(osv.osv):
@param context: A standard dictionary for contextual values
@return: Dictionary of function fields value.
"""
- register_pool = self.pool.get('event.registration')
res = {}
for event in self.browse(cr, uid, ids, context=context):
res[event.id] = {}
@@ -268,27 +264,27 @@ class event_event(osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
message = _("Event has been created.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def button_cancel_send_note(self, cr, uid, ids, context=None):
message = _("Event has been cancelled.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def button_draft_send_note(self, cr, uid, ids, context=None):
message = _("Event has been set to draft.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def button_done_send_note(self, cr, uid, ids, context=None):
message = _("Event has been done.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def button_confirm_send_note(self, cr, uid, ids, context=None):
message = _("Event has been confirmed.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
event_event()
@@ -334,7 +330,7 @@ class event_registration(osv.osv):
return self.write(cr, uid, ids, {'state': 'draft'}, context=context)
def confirm_registration(self, cr, uid, ids, context=None):
- self.message_append(cr, uid, ids,_('State set to open'),body_text= _('Open'))
+ self.message_post(cr, uid, ids, body=_('State set to open'), context=context)
return self.write(cr, uid, ids, {'state': 'open'}, context=context)
def create(self, cr, uid, vals, context=None):
@@ -364,13 +360,13 @@ class event_registration(osv.osv):
if today >= registration.event_id.date_begin:
values = {'state': 'done', 'date_closed': today}
self.write(cr, uid, ids, values)
- self.message_append(cr, uid, ids, _('State set to Done'), body_text=_('Done'))
+ self.message_post(cr, uid, ids, body=_('State set to Done'), context=context)
else:
raise osv.except_osv(_('Error!'),_("You must wait for the starting day of the event to do this action.") )
return True
def button_reg_cancel(self, cr, uid, ids, context=None, *args):
- self.message_append(cr, uid, ids,_('State set to Cancel'),body_text= _('Cancel'))
+ self.message_post(cr, uid, ids, body=_('State set to Cancel'), context=context)
return self.write(cr, uid, ids, {'state': 'cancel'})
def mail_user(self, cr, uid, ids, context=None):
@@ -440,12 +436,12 @@ class event_registration(osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
message = _("Registration has been created.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def do_draft_send_note(self, cr, uid, ids, context=None):
message = _("Registration has been set as draft.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
event_registration()
diff --git a/addons/event/event_data.xml b/addons/event/event_data.xml
index d8d75950bcc..83af2f35cfb 100644
--- a/addons/event/event_data.xml
+++ b/addons/event/event_data.xml
@@ -14,11 +14,11 @@
-
+
- Module Events Organisation has been installedFrom the top menu Events, you can organize events, manage registrations, automate communication around your event and sell events through your quotations.
+ Module Events Organisation has been installed
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index dce96e4c3cf..b06ae9f0b6f 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -208,7 +208,7 @@
event.event.treeevent.event
-
+
@@ -219,7 +219,7 @@
-
+
@@ -326,7 +326,7 @@
-
+
@@ -421,7 +421,7 @@
event.registration.treeevent.registration
-
+
@@ -431,7 +431,7 @@
-
+
@@ -516,7 +516,7 @@
-
+
diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py
index 681116d064e..1d7a30ee2ee 100644
--- a/addons/event_sale/event_sale.py
+++ b/addons/event_sale/event_sale.py
@@ -88,5 +88,5 @@ class sale_order_line(osv.osv):
}
registration_id = registration_obj.create(cr, uid, dic, context=context)
message = _("The registration %s has been created from the Sale Order %s.") % (registration_id, order_line.order_id.name)
- registration_obj.message_append_note(cr, uid, [registration_id], body=message, context=context)
+ registration_obj.message_post(cr, uid, [registration_id], body=message, context=context)
return super(sale_order_line, self).button_confirm(cr, uid, ids, context=context)
diff --git a/addons/fetchmail/fetchmail.py b/addons/fetchmail/fetchmail.py
index 544a4f81b96..70a05c6bd0e 100644
--- a/addons/fetchmail/fetchmail.py
+++ b/addons/fetchmail/fetchmail.py
@@ -77,7 +77,7 @@ class fetchmail_server(osv.osv):
"emails to the existing conversations (documents)."),
'priority': fields.integer('Server Priority', readonly=True, states={'draft':[('readonly', False)]}, help="Defines the order of processing, "
"lower values mean higher priority"),
- 'message_ids': fields.one2many('mail.message', 'fetchmail_server_id', 'Messages', readonly=True),
+ 'message_ids': fields.one2many('mail.mail', 'fetchmail_server_id', 'Messages', readonly=True),
'configuration' : fields.text('Configuration'),
'script' : fields.char('Script', readonly=True, size=64),
}
@@ -232,8 +232,8 @@ openerp_mailgate.py -u %(uid)d -p PASSWORD -o %(model)s -d %(dbname)s --host=HOS
server.write({'date': time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)})
return True
-class mail_message(osv.osv):
- _inherit = "mail.message"
+class mail_mail(osv.osv):
+ _inherit = "mail.mail"
_columns = {
'fetchmail_server_id': fields.many2one('fetchmail.server', "Inbound Mail Server",
readonly=True,
@@ -247,7 +247,7 @@ class mail_message(osv.osv):
fetchmail_server_id = context.get('fetchmail_server_id')
if fetchmail_server_id:
values['fetchmail_server_id'] = fetchmail_server_id
- res = super(mail_message,self).create(cr, uid, values, context=context)
+ res = super(mail_mail,self).create(cr, uid, values, context=context)
return res
def write(self, cr, uid, ids, values, context=None):
@@ -256,7 +256,7 @@ class mail_message(osv.osv):
fetchmail_server_id = context.get('fetchmail_server_id')
if fetchmail_server_id:
values['fetchmail_server_id'] = server_id
- res = super(mail_message,self).write(cr, uid, ids, values, context=context)
+ res = super(mail_mail,self).write(cr, uid, ids, values, context=context)
return res
diff --git a/addons/fetchmail/fetchmail_view.xml b/addons/fetchmail/fetchmail_view.xml
index cf651b5fd3d..3cdc886ba2b 100644
--- a/addons/fetchmail/fetchmail_view.xml
+++ b/addons/fetchmail/fetchmail_view.xml
@@ -104,27 +104,16 @@
/>
- mail.message.list.fetchmail
- mail.message
-
+ mail.mail.form.fetchmail
+ mail.mail
+
-
+
-
- mail.message.inherit.search
- mail.message
-
-
-
-
-
-
-
-
-
+
- Module Employee Directory has been installedManage your human resources in OpenERP: employees and hierarchy, HR departments and jobs.
More HR features are available from the following modules: Recruitment Process (manage job positions and recruitment), Timesheets Validation (record timesheets and attendance), Leaves Management (keep track of employee leaves), Expenses Management (manage employee expenses), Employee Appraisals (organize employee surveys, where employees evaluate their subordinates or their manager.)
+ Module Employee Directory has been installed
diff --git a/addons/hr_evaluation/__openerp__.py b/addons/hr_evaluation/__openerp__.py
index 2662b637334..4be0f94947c 100644
--- a/addons/hr_evaluation/__openerp__.py
+++ b/addons/hr_evaluation/__openerp__.py
@@ -38,11 +38,10 @@ created and it can be defined which level of employee hierarchy fills what and
final review and evaluation is done by the manager. Every evaluation filled by
the employees can be viewed in the form of pdf file.
""",
- 'demo': ['hr_evaluation_demo.xml'],
- 'data': [
+ "demo": ["hr_evaluation_demo.xml"],
+ "data": [
'security/ir.model.access.csv',
'security/hr_evaluation_security.xml',
-# 'wizard/hr_evaluation_mail_view.xml',
'hr_evaluation_view.xml',
'report/hr_evaluation_report_view.xml',
'board_hr_evaluation_view.xml',
diff --git a/addons/hr_evaluation/hr_evaluation_data.xml b/addons/hr_evaluation/hr_evaluation_data.xml
index cf632a795cc..6f122e44e9b 100644
--- a/addons/hr_evaluation/hr_evaluation_data.xml
+++ b/addons/hr_evaluation/hr_evaluation_data.xml
@@ -14,11 +14,11 @@
100
-
+
- Module Employee Appraisals has been installedCreate evaluations for your subordinates or manager. You can define a plan with several surveys, where you organize evaluation surveys related to the hierarchy levels. Evaluations filled by employees can exported as pdf files.
+ Module Employee Appraisals has been installed
diff --git a/addons/hr_evaluation/wizard/__init__.py b/addons/hr_evaluation/wizard/__init__.py
deleted file mode 100644
index 64406ac6b1e..00000000000
--- a/addons/hr_evaluation/wizard/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# 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 .
-#
-##############################################################################
-
-#import hr_evaluation_mail
-import mail_compose_message
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_evaluation/wizard/hr_evaluation_mail.py b/addons/hr_evaluation/wizard/hr_evaluation_mail.py
deleted file mode 100644
index 35c54a4cca3..00000000000
--- a/addons/hr_evaluation/wizard/hr_evaluation_mail.py
+++ /dev/null
@@ -1,42 +0,0 @@
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# 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 .
-#
-##############################################################################
-
-from osv import fields, osv
-import tools
-
-class hr_evaluation_reminder(osv.osv_memory):
- _name = "hr.evaluation.reminder"
- _description = "Sends Reminders to employees to fill the evaluations"
- _columns = {
- 'evaluation_id': fields.many2one('hr.evaluation.interview', 'Interview', required=True)
- }
-
- def send_mail(self, cr, uid, ids, context=None):
- mail_message = self.pool.get('mail.message')
- hr_evaluation_interview_obj = self.pool.get('hr.evaluation.interview')
- evaluation_data = self.read(cr, uid, ids, context=context)[0]
- current_interview = hr_evaluation_interview_obj.browse(cr, uid, evaluation_data.get('evaluation_id'))
- if current_interview.state == "waiting_answer" and current_interview.user_to_review_id.work_email :
- msg = " Hello %s, \n\n Kindly post your response for '%s' survey interview. \n\n Thanks," %(current_interview.user_to_review_id.name, current_interview.survey_id.title)
- mail_message.schedule_with_attach(cr, uid, tools.config['email_from'], [current_interview.user_to_review_id.work_email],\
- 'Reminder to fill up Survey', msg, context=context)
- return {'type': 'ir.actions.act_window_close'}
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_evaluation/wizard/hr_evaluation_mail_view.xml b/addons/hr_evaluation/wizard/hr_evaluation_mail_view.xml
deleted file mode 100644
index 89ae99bb6c3..00000000000
--- a/addons/hr_evaluation/wizard/hr_evaluation_mail_view.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
- hr.evaluation.send.mail
- hr.evaluation.reminder
-
-
-
-
-
-
- Evaluation Send Mail
- hr.evaluation.reminder
- ir.actions.act_window
- form
- tree,form
-
- {'record_id':active_id}
- new
-
-
-
-
diff --git a/addons/hr_evaluation/wizard/mail_compose_message.py b/addons/hr_evaluation/wizard/mail_compose_message.py
deleted file mode 100644
index 7e4ba326947..00000000000
--- a/addons/hr_evaluation/wizard/mail_compose_message.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2010-Today OpenERP SA ()
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see
-#
-##############################################################################
-
-from osv import osv
-from osv import fields
-import tools
-from tools.translate import _
-
-class mail_compose_message(osv.osv_memory):
- _inherit = 'mail.compose.message'
-
- def get_value(self, cr, uid, model, resource_id, context=None):
- '''
- To get values of the resource_id for the model
- @param model: Object
- @param resource_id: id of a record for which values to be read
-
- @return: Returns a dictionary
- '''
- if context is None:
- context = {}
- result = super(mail_compose_message, self).get_value(cr, uid, model, resource_id, context=context)
- if model == 'hr.evaluation.interview' and resource_id:
- model_pool = self.pool.get(model)
- record_data = model_pool.browse(cr, uid, resource_id, context)
- if record_data.state == "waiting_answer":
- msg = _("Hello %s, \n\n Kindly post your response for '%s' survey interview. \n\n Thanks,") %(record_data.user_to_review_id.name, record_data.survey_id.title)
- result.update({
- 'email_to': record_data.user_to_review_id.work_email or False,
- 'subject': _("Reminder to fill up Survey"),
- 'body_text': msg,
- })
- return result
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_expense/hr_expense_data.xml b/addons/hr_expense/hr_expense_data.xml
index 6e41f3d4e05..d5123df7ee8 100644
--- a/addons/hr_expense/hr_expense_data.xml
+++ b/addons/hr_expense/hr_expense_data.xml
@@ -2,13 +2,13 @@
-
+
- Module Expenses Management has been installedManage your employee's expenses, with validations by employee manager and accountant, creation and payment of invoices.
This module also uses the analytic accounting and is compatible with the invoice on timesheet module so that you will be able to automatically re-invoice your customer's expenses if your work by project.
+ Module Expenses Management has been installed
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index 5840217d7ee..75487983738 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -94,7 +94,7 @@ class hr_holidays(osv.osv):
_name = "hr.holidays"
_description = "Leave"
_order = "type desc, date_from asc"
- _inherit = ['ir.needaction_mixin', 'mail.thread']
+ _inherit = [ 'mail.thread','ir.needaction_mixin']
def _employee_get(self, cr, uid, context=None):
ids = self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
@@ -347,66 +347,57 @@ class hr_holidays(osv.osv):
if leaves_rest < record.number_of_days_temp:
raise osv.except_osv(_('Warning!'), _('There are not enough %s allocated for employee %s; please create an allocation request for this leave type.') % (record.holiday_status_id.name, record.employee_id.name))
return True
-
+
# -----------------------------
# OpenChatter and notifications
# -----------------------------
-
- def get_needaction_user_ids(self, cr, uid, ids, context=None):
- result = super(hr_holidays, self).get_needaction_user_ids(cr, uid, ids, context=context)
- for obj in self.browse(cr, uid, ids, context=context):
- if obj.state == 'confirm' and obj.employee_id.parent_id:
- result[obj.id] = [obj.employee_id.parent_id.user_id.id]
- elif obj.state == 'validate1':
- # get group_hr_manager: everyone will be warned of second validation
- res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_manager') or False
- obj_id = res and res[1] or False
- if obj_id:
- hr_manager_group = self.pool.get('res.groups').read(cr, uid, [obj_id], ['users'], context=context)[0]
- result[obj.id] = hr_manager_group['users']
- return result
- def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
- """ Add 'user_id' and 'manager' to the monitored fields """
- res = super(hr_holidays, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
- # TODO: add manager
- return res + ['user_id']
-
+ def needaction_domain_get(self, cr, uid, ids, context=None):
+ # to be tested, otherwise convert into employee_id in ...
+ emp_obj = self.pool.get('hr.employee')
+ empids = emp_obj.search(cr, uid, [('parent_id.user_id','=',uid)], context=context)
+ dom = [
+ '&', ('state','=','confirm'),('employee_id', 'in', empids)
+ ]
+ # if this user is a hr.manager, he should do second validations
+ if self.pool.get('res.users').has_group(cr, uid, 'base.group_hr_manager'):
+ dom = ['|'] + dom + [ ('state','=','validate1') ]
+ return dom
+
def create_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
- self.message_append_note(cr, uid, ids, _('System notification'),
- _("The %s request has been created and is waiting confirmation.")
- % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
+ self.message_post(cr, uid, ids,
+ _("The %s request has been created and is waiting for confirmation.")
+ % ('leave' if obj.type == 'remove' else 'allocation',), context=context)
return True
def holidays_confirm_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids):
- self.message_append_note(cr, uid, [obj.id], _('System notification'),
- _("The %s request has been confirmed and is waiting for validation by the manager.")
- % ('leave' if obj.type == 'remove' else 'allocation',), type='notification')
+ self.message_post(cr, uid, [obj.id], _("The %s request has been confirmed and is waiting for validation by the manager.")
+ % ('leave' if obj.type == 'remove' else 'allocation',), context=context)
def holidays_validate_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids):
if obj.holiday_status_id.double_validation:
- self.message_append_note(cr, uid, [obj.id], _('System notification'),
+ self.message_post(cr, uid, [obj.id],
_("The %s request has been approved. A second validation is necessary and is now pending.")
- % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
+ % ('leave' if obj.type == 'remove' else 'allocation',), context=context)
else:
- self.message_append_note(cr, uid, [obj.id], _('System notification'),
+ self.message_post(cr, uid, [obj.id],
_("The %s request has been approved. The validation process is now over.")
- % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
+ % ('leave' if obj.type == 'remove' else 'allocation',), context=context)
def holidays_valid2_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids):
- self.message_append_note(cr, uid, [obj.id], _('System notification'),
+ self.message_post(cr, uid, [obj.id],
_("The %s request has been double validated. The validation process is now over.")
- % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
+ % ('leave' if obj.type == 'remove' else 'allocation',), context=context)
def holidays_refuse_notificate(self, cr, uid, ids, approval, context=None):
for obj in self.browse(cr, uid, ids):
- self.message_append_note(cr, uid, [obj.id], _('System notification'),
+ self.message_post(cr, uid, [obj.id],
_("The %s request has been refused. The validation process is now over.")
- % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
+ % ('leave' if obj.type == 'remove' else 'allocation',), context=context)
hr_holidays()
diff --git a/addons/hr_holidays/hr_holidays_data.xml b/addons/hr_holidays/hr_holidays_data.xml
index 9db0f2e987a..5c8e4922259 100644
--- a/addons/hr_holidays/hr_holidays_data.xml
+++ b/addons/hr_holidays/hr_holidays_data.xml
@@ -13,11 +13,11 @@
100
-
+
- Module Leaves Management has been installedManage employee leaves from the top menu "Human Resources". Employees can create leave requests that are validated by their manager and/or HR people. Once validated, they are visible in the employee's calendar. HR people can define leave types and allocate off-days for employees.
+ Module Leaves Management has been installed
diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml
index 711d07bbfe8..89ce641b271 100644
--- a/addons/hr_holidays/hr_holidays_view.xml
+++ b/addons/hr_holidays/hr_holidays_view.xml
@@ -44,7 +44,6 @@
-
@@ -194,8 +193,7 @@
hr.holidays.allocation.treehr.holidays
-
-
+
@@ -243,8 +241,7 @@
hr.holidays20
-
-
+
@@ -266,8 +263,7 @@
hr.holidays.treehr.holidays
-
-
+
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index 6b4839b7b2b..82f2c9c3a21 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -90,8 +90,7 @@ class hr_applicant(base_stage, osv.Model):
_name = "hr.applicant"
_description = "Applicant"
_order = "id desc"
- _inherit = ['ir.needaction_mixin', 'mail.thread']
- _mail_compose_message = True
+ _inherit = ['mail.thread', 'ir.needaction_mixin']
def _get_default_department_id(self, cr, uid, context=None):
""" Gives default department by checking if present in the context """
@@ -161,13 +160,11 @@ class hr_applicant(base_stage, osv.Model):
date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
date_open = datetime.strptime(issue.date_open, "%Y-%m-%d %H:%M:%S")
ans = date_open - date_create
- date_until = issue.date_open
elif field in ['day_close']:
if issue.date_closed:
date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
date_close = datetime.strptime(issue.date_closed, "%Y-%m-%d %H:%M:%S")
- date_until = issue.date_closed
ans = date_close - date_create
if ans:
duration = float(ans.days)
@@ -328,14 +325,13 @@ class hr_applicant(base_stage, osv.Model):
if custom_values is None: custom_values = {}
custom_values.update({
'name': msg.get('subject') or _("No Subject"),
- 'description': msg.get('body_text'),
+ 'description': msg.get('body'),
'email_from': msg.get('from'),
'email_cc': msg.get('cc'),
'user_id': False,
})
if msg.get('priority'):
custom_values['priority'] = msg.get('priority')
- custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context))
return super(hr_applicant,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
@@ -360,7 +356,7 @@ class hr_applicant(base_stage, osv.Model):
'revenue': 'planned_revenue',
'probability': 'probability',
}
- for line in msg.get('body_text', '').split('\n'):
+ for line in msg.get('body', '').split('\n'):
line = line.strip()
res = tools.misc.command_re.match(line)
if res and maps.get(res.group(1).lower(), False):
@@ -457,23 +453,18 @@ class hr_applicant(base_stage, osv.Model):
# OpenChatter methods and notifications
# -------------------------------------------------------
- def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
- """ Add 'user_id' to the monitored fields """
- res = super(hr_applicant, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
- return res + ['user_id']
-
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
if not stage_id: return True
stage_name = self.pool.get('hr.recruitment.stage').name_get(cr, uid, [stage_id], context=context)[0][1]
- return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context)
+ return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context)
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
return 'Applicant'
def case_open_send_note(self, cr, uid, ids, context=None):
message = _("Applicant has been set in progress.")
- return self.message_append_note(cr, uid, ids, body=message, context=context)
+ return self.message_post(cr, uid, ids, body=message, context=context)
def case_close_send_note(self, cr, uid, ids, context=None):
if context is None:
@@ -481,23 +472,23 @@ class hr_applicant(base_stage, osv.Model):
for applicant in self.browse(cr, uid, ids, context=context):
if applicant.emp_id:
message = _("Applicant has been hired and created as an employee.")
- self.message_append_note(cr, uid, [applicant.id], body=message, context=context)
+ self.message_post(cr, uid, [applicant.id], body=message, context=context)
else:
message = _("Applicant has been hired.")
- self.message_append_note(cr, uid, [applicant.id], body=message, context=context)
+ self.message_post(cr, uid, [applicant.id], body=message, context=context)
return True
def case_cancel_send_note(self, cr, uid, ids, context=None):
msg = 'Applicant refused.'
- return self.message_append_note(cr, uid, ids, body=msg, context=context)
+ return self.message_post(cr, uid, ids, body=msg, context=context)
def case_reset_send_note(self, cr, uid, ids, context=None):
message =_("Applicant has been set as new.")
- return self.message_append_note(cr, uid, ids, body=message, context=context)
+ return self.message_post(cr, uid, ids, body=message, context=context)
def create_send_note(self, cr, uid, ids, context=None):
message = _("Applicant has been created.")
- return self.message_append_note(cr, uid, ids, body=message, context=context)
+ return self.message_post(cr, uid, ids, body=message, context=context)
class hr_job(osv.osv):
diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml
index d90f5ab596a..58a0595c857 100644
--- a/addons/hr_recruitment/hr_recruitment_data.xml
+++ b/addons/hr_recruitment/hr_recruitment_data.xml
@@ -2,13 +2,13 @@
-
+
- Module Recruitment Process has been installedManage job positions and the recruitment process in your company. This module is integrated with the module Survey to help you to define interviews for different jobs.
You can automatically create application records from an email gateway, that you can configure in the Human Resources Settings.
+ Module Recruitment Process has been installed
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index d1866f124af..11f2196ba09 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -76,8 +76,8 @@
Applicantshr.applicant
-
-
+
+
@@ -208,7 +208,7 @@
-
+
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index 4cba4a18680..a1562d53a61 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -95,25 +95,25 @@ class account_analytic_account(osv.osv):
def set_close(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'close'}, context=context)
message = _("Contract has been closed.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def set_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
message = _("Contract has been cancelled.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def set_open(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'open'}, context=context)
message = _("Contract has been opened.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
def set_pending(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'pending'}, context=context)
message = _("Contract has been set as pending.")
- self.message_append_note(cr, uid, ids, body=message, context=context)
+ self.message_post(cr, uid, ids, body=message, context=context)
return True
account_analytic_account()
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_data.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_data.xml
index 5458f397e36..046fd7fe3d0 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_data.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_data.xml
@@ -1,13 +1,12 @@
-
-
+
- Module Timesheets Validation has been installedFrom the top menu "Human Resources", encode and validate timesheets and attendances.
+ Module Timesheets Validation has been installed
diff --git a/addons/idea/idea.py b/addons/idea/idea.py
index 3be4dd2e28d..e2e5ec50ddf 100644
--- a/addons/idea/idea.py
+++ b/addons/idea/idea.py
@@ -67,21 +67,21 @@ class idea_idea(osv.osv):
def idea_cancel(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, { 'state': 'cancel' })
- self.message_append_note(cr, uid, ids, body=_('Idea canceled.'), context=context)
+ self.message_post(cr, uid, ids, body=_('Idea canceled.'), context=context)
return True
def idea_open(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, { 'state': 'open'})
- self.message_append_note(cr, uid, ids, body=_('Idea accepted.'), context=context)
+ self.message_post(cr, uid, ids, body=_('Idea accepted.'), context=context)
return True
def idea_close(self, cr, uid, ids, context={}):
- self.message_append_note(cr, uid, ids, body=_('Idea done.'), context=context)
+ self.message_post(cr, uid, ids, body=_('Idea done.'), context=context)
self.write(cr, uid, ids, { 'state': 'close' })
return True
def idea_draft(self, cr, uid, ids, context={}):
- self.message_append_note(cr, uid, ids, body=_('Idea reset to draft.'), context=context)
+ self.message_post(cr, uid, ids, body=_('Idea reset to draft.'), context=context)
self.write(cr, uid, ids, { 'state': 'draft' })
return True
idea_idea()
diff --git a/addons/import_base/import_framework.py b/addons/import_base/import_framework.py
index 74d2185b57e..7e0a055d95b 100644
--- a/addons/import_base/import_framework.py
+++ b/addons/import_base/import_framework.py
@@ -425,7 +425,7 @@ class import_framework(Thread):
email_id = email_obj.create(self.cr, self.uid, {
'email_from' : 'import@module.openerp',
'email_to' : self.email,
- 'body_text' : self.get_email_body(result, error),
+ 'body' : self.get_email_body(result, error),
'subject' : self.get_email_subject(result, error),
'auto_delete' : True})
email_obj.send(self.cr, self.uid, [email_id])
diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py
index 440a7b2b6f6..1646fb7ff2a 100644
--- a/addons/import_sugarcrm/import_sugarcrm.py
+++ b/addons/import_sugarcrm/import_sugarcrm.py
@@ -226,7 +226,7 @@ class sugar_import(import_framework):
'model': 'model',
'partner_id/.id': 'partner_id/.id',
'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
- 'body_text': 'description',
+ 'body': 'description',
'body_html' : 'description_html',
}
diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py
index 3f0b618b795..9c51853f865 100644
--- a/addons/mail/__init__.py
+++ b/addons/mail/__init__.py
@@ -21,11 +21,11 @@
import mail_message_subtype
import mail_alias
-import mail_message
import mail_followers
+import mail_message
+import mail_mail
import mail_thread
import mail_group
-import ir_needaction
import res_partner
import res_users
import report
diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py
index 72ee43ab093..4a90c4c5ac7 100644
--- a/addons/mail/__openerp__.py
+++ b/addons/mail/__openerp__.py
@@ -65,6 +65,7 @@ The main features of the module are:
'mail_message_subtype.xml',
'res_config_view.xml',
'mail_message_view.xml',
+ 'mail_mail_view.xml',
'mail_followers_view.xml',
'mail_thread_view.xml',
'mail_group_view.xml',
diff --git a/addons/mail/data/mail_demo.xml b/addons/mail/data/mail_demo.xml
index e3d7c2ab1e1..ed30d38b8d3 100644
--- a/addons/mail/data/mail_demo.xml
+++ b/addons/mail/data/mail_demo.xml
@@ -3,41 +3,33 @@
- Internal company announcemail.group
- html
- comment
- mail.group
- html
-
+ comment
- mail.group
- html
-
+ comment
- mail.group
- html
- comment
-
diff --git a/addons/mail/data/mail_group_data.xml b/addons/mail/data/mail_group_data.xml
index 400e8ffc061..c9ac97e6836 100644
--- a/addons/mail/data/mail_group_data.xml
+++ b/addons/mail/data/mail_group_data.xml
@@ -13,15 +13,15 @@
-
-
+
+
- Welcome to OpenERP!Your homepage is a summary of messages you received and key information about documents you follow.
The top menu bar contains all applications you installed. You can use this <i>Settings</i> menu to install more applications, activate others features or give access to new users.
To setup your preferences (name, email signature, avatar), click on the top right corner.
+ Welcome to OpenERP!
diff --git a/addons/mail/doc/mail_openchatter_howto.rst b/addons/mail/doc/mail_openchatter_howto.rst
index 789acdd87eb..e4c86add7bc 100644
--- a/addons/mail/doc/mail_openchatter_howto.rst
+++ b/addons/mail/doc/mail_openchatter_howto.rst
@@ -57,7 +57,7 @@ Use the thread viewer widget inside your form view by using the mail_thread widg
Send notifications
+++++++++++++++++++
-When sending a notification is required in your workflow or business logic, use the ``message_append_note`` method. This method is a shortcut to the ``message_append`` method that takes all ``mail.message`` fields as arguments. This latter method calls ``message_create`` that
+When sending a notification is required in your workflow or business logic, use the ``message_post`` method. This method is a shortcut to the ``message_append`` method that takes all ``mail.message`` fields as arguments. This latter method calls ``message_create`` that
- creates the message
- parses the body to find users you want to push the message to (finding and parsing ``@login`` in the message body)
@@ -74,7 +74,7 @@ You should therefore not worry about subscriptions or anything else than sending
return res
def do_something_send_note(self, cr, uid, ids, context=None):
- self.message_append_note(cr, uid, ids, _('My subject'),
+ self.message_post(cr, uid, ids, _('My subject'),
_("has received a notification and is happy for it."), context=context)
Notifications guidelines
@@ -147,7 +147,7 @@ The best way to direct the messages that will be displayed in the OpenChatter wi
# add: search in the current task project messages
'&', '&', ('res_id', '=', my_task.project_id.id), ('model', '=', 'project.project'),
# ... containing the task name
- '|', ('body_text', 'like', '%s' % (my_task.name)), ('body_html', 'like', '%s' % (my_task.name))
+ '|', ('body', 'like', '%s' % (my_task.name)), ('body_html', 'like', '%s' % (my_task.name))
] + domain, limit=limit, offset=offset, context=context)
# if asked: add ancestor ids to have complete threads
if (ascent): msg_ids = self._message_add_ancestor_ids(cr, uid, ids, msg_ids, root_ids, context=context)
diff --git a/addons/mail/doc/mail_state.rst b/addons/mail/doc/mail_state.rst
index 527a31ba835..fc2772bf094 100644
--- a/addons/mail/doc/mail_state.rst
+++ b/addons/mail/doc/mail_state.rst
@@ -1,15 +1,15 @@
.. _mail_state:
-message_state
+message_unread
=============
-``message_state`` is a boolean field that states whether the document
+``message_unread`` is a boolean field that states whether the document
has unread messages. In previous versions, some documents were going
back to ``pending`` state when receiving an email through the mail
gateway. Now the state related to messages differs from the state or
stage of the document itself.
-message_state and need action mechanism
+message_unread and need action mechanism
+++++++++++++++++++++++++++++++++++++++
The ``mail`` module introduces a default behavior for the need_action
@@ -23,6 +23,6 @@ mechanism [REF].
"""
result = super(ir_needaction_mixin, self).get_needaction_user_ids(cr, uid, ids, context=context)
for obj in self.browse(cr, uid, ids, context=context):
- if obj.message_state == False and obj.user_id:
+ if obj.message_unread == False and obj.user_id:
result[obj.id].append(obj.user_id.id)
return result
diff --git a/addons/mail/ir_needaction.py b/addons/mail/ir_needaction.py
deleted file mode 100644
index 8193ac4f385..00000000000
--- a/addons/mail/ir_needaction.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2012-today OpenERP SA ()
-#
-# 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
-#
-##############################################################################
-
-from osv import osv
-
-class ir_needaction_mixin(osv.Model):
- """ Update of ir.needaction_mixin class
- - override the get_needaction_user_ids method to define the default
- mail gateway need_action: when the object is unread, the object
- responsible has an action to perform.
- """
- _name = 'ir.needaction_mixin'
- _inherit = ['ir.needaction_mixin']
-
- def get_needaction_user_ids(self, cr, uid, ids, context=None):
- """ Returns the user_ids that have to perform an action. It the
- document mail state is unread (False), return object.user_id.id
- as need_action uid.
- :return: dict { record_id: [user_ids], }
- """
- result = super(ir_needaction_mixin, self).get_needaction_user_ids(cr, uid, ids, context=context)
- for obj in self.browse(cr, uid, ids, context=context):
- if obj.message_state == False and obj.user_id:
- result[obj.id].append(obj.user_id.id)
- return result
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py
index 3686dd7c4ed..4b2ed776ab2 100644
--- a/addons/mail/mail_followers.py
+++ b/addons/mail/mail_followers.py
@@ -24,26 +24,24 @@ from osv import fields
class mail_followers(osv.Model):
""" mail_followers holds the data related to the follow mechanism inside
- OpenERP. Users can choose to follow documents (records) of any kind that
- inherits from mail.thread. Following documents allow to receive
- notifications for new messages.
- A subscription is characterized by:
- :param: res_model: model of the followed objects
- :param: res_id: ID of resource (may be 0 for every objects)
- :param: user_id: user_id of the follower
+ OpenERP. Partners can choose to follow documents (records) of any kind
+ that inherits from mail.thread. Following documents allow to receive
+ notifications for new messages.
+ A subscription is characterized by:
+ :param: res_model: model of the followed objects
+ :param: res_id: ID of resource (may be 0 for every objects)
"""
_name = 'mail.followers'
- _rec_name = 'id'
+ _rec_name = 'partner_id'
_log_access = False
- _order = 'res_model asc'
- _description = 'Mail Document Followers'
+ _description = 'Document Followers'
_columns = {
'res_model': fields.char('Related Document Model', size=128,
required=True, select=1,
help='Model of the followed resource'),
'res_id': fields.integer('Related Document ID', select=1,
help='Id of the followed resource'),
- 'user_id': fields.many2one('res.users', string='Related User',
+ 'partner_id': fields.many2one('res.partner', string='Related Partner',
ondelete='cascade', required=True, select=1),
'subtype_ids': fields.many2many('mail.message.subtype',
'mail_message_subtyp_rel',
@@ -51,17 +49,65 @@ class mail_followers(osv.Model):
help = "linking some subscription to several subtype for projet/task"),
}
+
class mail_notification(osv.Model):
- """ mail_notification is a relational table modeling messages pushed to users.
- """
+ """ Class holding notifications pushed to partners. Followers and partners
+ added in 'contacts to notify' receive notifications. """
_name = 'mail.notification'
- _rec_name = 'id'
+ _rec_name = 'partner_id'
_log_access = False
- _order = 'message_id desc'
- _description = 'Mail notification'
+ _description = 'Notifications'
+
_columns = {
- 'user_id': fields.many2one('res.users', string='User',
- ondelete='cascade', required=True, select=1),
- 'message_id': fields.many2one('mail.message', string='Message',
+ 'partner_id': fields.many2one('res.partner', string='Contact',
ondelete='cascade', required=True, select=1),
+ 'read': fields.boolean('Read'),
}
+
+ _defaults = {
+ 'read': False,
+ }
+
+ def create(self, cr, uid, vals, context=None):
+ """ Override of create to check that we can not create a notification
+ for a message the user can not read. """
+ if self.pool.get('mail.message').check_access_rights(cr, uid, 'read'):
+ return super(mail_notification, self).create(cr, uid, vals, context=context)
+ return False
+
+ def notify(self, cr, uid, partner_ids, msg_id, context=None):
+ """ Send by email the notification depending on the user preferences """
+ context = context or {}
+ # mail_noemail (do not send email) or no partner_ids: do not send, return
+ if context.get('mail_noemail') or not partner_ids:
+ return True
+
+ mail_mail_obj = self.pool.get('mail.mail')
+ msg_obj = self.pool.get('mail.message')
+ msg = msg_obj.browse(cr, uid, msg_id, context=context)
+
+ towrite = {
+ 'mail_message_id': msg.id,
+ 'email_to': [],
+ 'user_signature': True,
+ 'auto_delete': True,
+ }
+
+ for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
+ # Do not send an email to the writer
+ if partner.user_id.id == uid:
+ continue
+ # Partner does not want to receive any emails
+ if partner.notification_email_send=='none' or not partner.email:
+ continue
+ # Partner want to receive only emails and comments
+ if partner.notification_email_send=='comment' and msg.type not in ('email','comment'):
+ continue
+
+ if partner.email not in towrite['email_to']:
+ towrite['email_to'].append(partner.email)
+ towrite['email_to'] = ', '.join(towrite['email_to'])
+
+ email_notif_id = mail_mail_obj.create(cr, uid, towrite, context=context)
+ mail_mail_obj.send(cr, uid, [email_notif_id], context=context)
+ return True
diff --git a/addons/mail/mail_followers_view.xml b/addons/mail/mail_followers_view.xml
index 6c2a6eee6a2..9fc8a545a20 100644
--- a/addons/mail/mail_followers_view.xml
+++ b/addons/mail/mail_followers_view.xml
@@ -6,13 +6,12 @@
mail.followers.treemail.followers
- tree10
-
+
@@ -27,7 +26,7 @@
-
+
@@ -46,7 +45,7 @@
10
-
+
@@ -60,7 +59,7 @@
- Pushed notif
+ Notificationsmail.notificationformtree,form
diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py
index 6a14fef83aa..1824f59e0b9 100644
--- a/addons/mail/mail_group.py
+++ b/addons/mail/mail_group.py
@@ -34,7 +34,6 @@ class mail_group(osv.Model):
subscription/follow mechanism of OpenSocial. A mail group has nothing
in common with res.users.group.
"""
-
_description = 'Discussion group'
_name = 'mail.group'
_inherit = ['mail.thread']
@@ -45,31 +44,20 @@ class mail_group(osv.Model):
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
-
+
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
-
- def _get_last_month_msg_nbr(self, cr, uid, ids, name, args, context=None):
- result = {}
- for id in ids:
- lower_date = (DT.datetime.now() - DT.timedelta(days=30)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
- result[id] = self.message_search(cr, uid, [id], limit=None, domain=[('date', '>=', lower_date)], count=True, context=context)
- return result
-
+
def _get_default_image(self, cr, uid, context=None):
image_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
-
+
_columns = {
'description': fields.text('Description'),
'menu_id': fields.many2one('ir.ui.menu', string='Related Menu', required=True, ondelete="cascade"),
- 'responsible_id': fields.many2one('res.users', string='Responsible',
- ondelete='set null', required=True, select=1,
- help="Responsible of the group that has all rights on the record."),
- 'public': fields.selection([('public', 'Public'), ('private', 'Private'), ('groups', 'Selected Group Only')],
- string='Privacy', required=True,
- help='This group is visible by non members. '\
- 'Invisible groups can add members through the invite button.'),
+ 'public': fields.selection([('public','Public'),('private','Private'),('groups','Selected Group Only')], 'Privacy', required=True,
+ help='This group is visible by non members. \
+ Invisible groups can add members through the invite button.'),
'group_public_id': fields.many2one('res.groups', string='Authorized Group'),
'group_ids': fields.many2many('res.groups', rel='mail_group_res_group_rel',
id1='mail_group_id', id2='groups_id', string='Auto Subscription',
@@ -79,7 +67,7 @@ class mail_group(osv.Model):
'image': fields.binary("Photo",
help="This field holds the image used as photo for the "\
"user. The image is base64 encoded, and PIL-supported. "\
- "It is limited to a 12024x1024 px image."),
+ "It is limited to a 1024x1024 px image."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized photo", type="binary", multi="_get_image",
store = {
@@ -96,11 +84,9 @@ class mail_group(osv.Model):
help="Small-sized photo of the group. It is automatically "\
"resized as a 50x50px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
- 'last_month_msg_nbr': fields.function(_get_last_month_msg_nbr, type='integer',
- string='Messages count for last month'),
- 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade",
- help="The email address associated with this group. New emails received will automatically "
- "create new topics."),
+ 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
+ help="The email address associated with this group. New emails received will automatically "
+ "create new topics."),
}
def _get_default_employee_group(self, cr, uid, context=None):
@@ -114,29 +100,23 @@ class mail_group(osv.Model):
_defaults = {
'public': 'groups',
'group_public_id': _get_default_employee_group,
- 'responsible_id': (lambda s, cr, uid, ctx: uid),
'image': _get_default_image,
'parent_id': _get_menu_parent,
- 'alias_domain': False, # always hide alias during creation
+ 'alias_domain': False, # always hide alias during creation
}
- def _subscribe_user_with_group_m2m_command(self, cr, uid, ids, group_ids_command, context=None):
- # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
- user_group_ids = [command[1] for command in group_ids_command if command[0] == 4]
- user_group_ids += [id for command in group_ids_command if command[0] == 6 for id in command[2]]
- # retrieve the user member of those groups
- user_ids = []
- res_groups_obj = self.pool.get('res.groups')
- for group in res_groups_obj.browse(cr, uid, user_group_ids, context=context):
- user_ids += [user.id for user in group.users]
- # subscribe the users
- return self.message_subscribe(cr, uid, ids, user_ids, context=context)
+ def _subscribe_users(self, cr, uid, ids, context=None):
+ for mail_group in self.browse(cr, uid, ids, context=context):
+ partner_ids = []
+ for group in mail_group.group_ids:
+ partner_ids += [user.partner_id.id for user in group.users]
+ self.message_subscribe(cr, uid, ids, partner_ids, context=context)
def create(self, cr, uid, vals, context=None):
mail_alias = self.pool.get('mail.alias')
if not vals.get('alias_id'):
vals.pop('alias_name', None) # prevent errors during copy()
- alias_id = mail_alias.create_unique_alias(cr, uid,
+ alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
# have a catchall domain setup.
{'alias_name': "group+"+vals['name']},
@@ -148,12 +128,11 @@ class mail_group(osv.Model):
# Create client action for this group and link the menu to it
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'action_mail_group_feeds')
if ref:
- search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search_wall')
+ search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search')
params = {
'search_view_id': search_ref and search_ref[1] or False,
'domain': [('model','=','mail.group'),('res_id','=',mail_group_id)],
- 'res_model': 'mail.group',
- 'res_id': mail_group_id,
+ 'res_model': 'mail.message',
'thread_level': 2
}
cobj = self.pool.get('ir.actions.client')
@@ -161,10 +140,9 @@ class mail_group(osv.Model):
self.write(cr, uid, [mail_group_id], {'action': 'ir.actions.client,'+str(newref), 'mail_group_id': mail_group_id}, context=context)
mail_alias.write(cr, uid, [vals['alias_id']], {"alias_force_thread_id": mail_group_id}, context)
-
- if vals.get('group_ids'):
- self._subscribe_user_with_group_m2m_command(cr, uid, [mail_group_id], vals.get('group_ids'), context=context)
+ if vals.get('group_ids'):
+ self._subscribe_users(cr, uid, [mail_group_id], context=context)
return mail_group_id
def unlink(self, cr, uid, ids, context=None):
@@ -176,21 +154,8 @@ class mail_group(osv.Model):
return res
def write(self, cr, uid, ids, vals, context=None):
+ result = super(mail_group, self).write(cr, uid, ids, vals, context=context)
if vals.get('group_ids'):
- self._subscribe_user_with_group_m2m_command(cr, uid, ids, vals.get('group_ids'), context=context)
- return super(mail_group, self).write(cr, uid, ids, vals, context=context)
+ self._subscribe_users(cr, uid, ids, vals.get('group_ids'), context=context)
+ return result
- def action_group_join(self, cr, uid, ids, context=None):
- return self.message_subscribe(cr, uid, ids, context=context)
-
- def action_group_leave(self, cr, uid, ids, context=None):
- return self.message_unsubscribe(cr, uid, ids, context=context)
-
- # ----------------------------------------
- # OpenChatter methods and notifications
- # ----------------------------------------
-
- def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
- """ Add 'responsible_id' to the monitored fields """
- res = super(mail_group, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
- return res + ['responsible_id']
diff --git a/addons/mail/mail_group_menu.py b/addons/mail/mail_group_menu.py
index 8625285d640..25b85bb7b22 100644
--- a/addons/mail/mail_group_menu.py
+++ b/addons/mail/mail_group_menu.py
@@ -40,11 +40,12 @@ class ir_ui_menu(osv.osv):
""" Override to take off menu entries (mail.group) the user is not
following. """
ids = super(ir_ui_menu, self).search(cr, uid, args, offset=0, limit=None, order=order, context=context, count=False)
+ partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
follower_obj = self.pool.get('mail.followers')
for menu in self.browse(cr, uid, ids, context=context):
if menu.mail_group_id:
sub_ids = follower_obj.search(cr, uid, [
- ('user_id', '=', uid), ('res_model', '=', 'mail.group'),
+ ('partner_id', '=', partner_id), ('res_model', '=', 'mail.group'),
('res_id', '=', menu.mail_group_id.id)
], context=context)
if not sub_ids:
diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml
index d21d32a3893..a7ae513669e 100644
--- a/addons/mail/mail_group_view.xml
+++ b/addons/mail/mail_group_view.xml
@@ -1,10 +1,11 @@
+
Discussion Groupmail.wall
-
+ mail.message
@@ -14,8 +15,9 @@
-
+
+
@@ -103,7 +98,6 @@
-
@@ -116,7 +110,6 @@
-
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
new file mode 100644
index 00000000000..50b5b4cfe84
--- /dev/null
+++ b/addons/mail/mail_mail.py
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2010-today OpenERP SA ()
+#
+# 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
+#
+##############################################################################
+
+# import ast
+import base64
+import logging
+import tools
+
+from osv import osv
+from osv import fields
+from tools.translate import _
+
+_logger = logging.getLogger(__name__)
+
+class mail_mail(osv.Model):
+ """
+ Model holding RFC2822 email messages to send. This model also provides
+ facilities to queue and send new email messages.
+ """
+
+ _name = 'mail.mail'
+ _description = 'Outgoing Mails'
+ _inherits = {'mail.message': 'mail_message_id'}
+ _columns = {
+ 'mail_message_id': fields.many2one('mail.message', 'Message', required=True, ondelete='cascade'),
+ 'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
+ 'state': fields.selection([
+ ('outgoing', 'Outgoing'),
+ ('sent', 'Sent'),
+ ('received', 'Received'),
+ ('exception', 'Delivery Failed'),
+ ('cancel', 'Cancelled'),
+ ], 'Status', readonly=True),
+ 'auto_delete': fields.boolean('Auto Delete',
+ help="Permanently delete this email after sending it, to save space"),
+ 'user_signature': fields.boolean('Add Signature',
+ help="If checked, the user's signature will be appended to the text version of the message"),
+ 'references': fields.text('References', help='Message references, such as identifiers of previous messages', readonly=1),
+ 'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences.'),
+ 'email_to': fields.text('To', help='Message recipients'),
+ 'email_cc': fields.char('Cc', size=256, help='Carbon copy message recipients'),
+ 'reply_to':fields.char('Reply-To', size=256, help='Preferred response address for the message'),
+ }
+
+ def _get_default_from(self, cr, uid, context=None):
+ cur = self.pool.get('res.users').browse(cr, uid, uid, context=context)
+ if not cur.alias_domain:
+ # TDE temp: impossible to install social module, because mail.group tries to send emails ...
+ # raise osv.except_osv(_('Invalid Action!'), _('Unable to send email, set an alias domain in your server settings.'))
+ pass
+ return cur.alias_name + '@' + cur.alias_domain
+
+ _defaults = {
+ 'state': 'outgoing',
+ 'email_from': lambda self, cr, uid, ctx=None: self._get_default_from(cr, uid, ctx),
+ 'user_signature': False,
+ }
+
+ def mark_outgoing(self, cr, uid, ids, context=None):
+ return self.write(cr, uid, ids, {'state':'outgoing'}, context=context)
+
+ def cancel(self, cr, uid, ids, context=None):
+ return self.write(cr, uid, ids, {'state':'cancel'}, context=context)
+
+ def process_email_queue(self, cr, uid, ids=None, context=None):
+ """Send immediately queued messages, committing after each
+ message is sent - this is not transactional and should
+ not be called during another transaction!
+
+ :param list ids: optional list of emails ids to send. If passed
+ no search is performed, and these ids are used
+ instead.
+ :param dict context: if a 'filters' key is present in context,
+ this value will be used as an additional
+ filter to further restrict the outgoing
+ messages to send (by default all 'outgoing'
+ messages are sent).
+ """
+ if context is None:
+ context = {}
+ if not ids:
+ filters = ['&', ('state', '=', 'outgoing'), ('type', '=', 'email')]
+ if 'filters' in context:
+ filters.extend(context['filters'])
+ ids = self.search(cr, uid, filters, context=context)
+ res = None
+ try:
+ # Force auto-commit - this is meant to be called by
+ # the scheduler, and we can't allow rolling back the status
+ # of previously sent emails!
+ res = self.send(cr, uid, ids, auto_commit=True, context=context)
+ except Exception:
+ _logger.exception("Failed processing mail queue")
+ return res
+
+ def _postprocess_sent_message(self, cr, uid, message, context=None):
+ """Perform any post-processing necessary after sending ``message``
+ successfully, including deleting it completely along with its
+ attachment if the ``auto_delete`` flag of the message was set.
+ Overridden by subclasses for extra post-processing behaviors.
+
+ :param browse_record message: the message that was just sent
+ :return: True
+ """
+ if message.auto_delete:
+ self.pool.get('ir.attachment').unlink(cr, uid,
+ [x.id for x in message.attachment_ids],
+ context=context)
+ message.unlink()
+ return True
+
+ def send(self, cr, uid, ids, auto_commit=False, context=None):
+ """Sends the selected emails immediately, ignoring their current
+ state (mails that have already been sent should not be passed
+ unless they should actually be re-sent).
+ Emails successfully delivered are marked as 'sent', and those
+ that fail to be deliver are marked as 'exception', and the
+ corresponding error message is output in the server logs.
+
+ :param bool auto_commit: whether to force a commit of the message
+ status after sending each message (meant
+ only for processing by the scheduler),
+ should never be True during normal
+ transactions (default: False)
+ :return: True
+ """
+ ir_mail_server = self.pool.get('ir.mail_server')
+ for message in self.browse(cr, uid, ids, context=context):
+ try:
+ body = message.body
+
+ # handle attachments
+ attachments = []
+ for attach in message.attachment_ids:
+ attachments.append((attach.datas_fname, base64.b64decode(attach.datas)))
+
+ # add signature if flag set
+ if message.user_signature:
+ signature = message.author_id and message.author_id.user_ids[0].signature or ''
+ insertion_point = body.find('