-You may change your password following this link:
+
You may change your password following this link,
+or by copy-pasting the following URL in your browser: ${object._auth_reset_password_link()}
-${object._auth_reset_password_link()}
-
-If you don't have asked for password reset, you can safely ignore this email.
-
-]]>
+
Note: If you did not ask for a password reset, you can safely ignore this email.
]]>
diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index 8c115baed23..7e9bbacab13 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -302,33 +302,27 @@ the rule to mark CC(mail to any other person defined in actions)."),
return self.format_body(body % data)
def email_send(self, cr, uid, obj, emails, body, emailfrom=None, context=None):
- """ send email
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param email: pass the emails
- @param emailfrom: Pass name the email From else False
- @param context: A standard dictionary for contextual values """
-
if not emailfrom:
- emailfrom = tools.config.get('email_from', False)
-
- if context is None:
- context = {}
-
- mail_message = self.pool.get('mail.message')
+ emailfrom = tools.config.get('email_from')
body = self.format_mail(obj, body)
- if not emailfrom:
- if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email:
- emailfrom = obj.user_id.email
-
- name = '[%d] %s' % (obj.id, tools.ustr(obj.name))
+ if not emailfrom and hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email:
+ emailfrom = obj.user_id.email
emailfrom = tools.ustr(emailfrom)
reply_to = emailfrom
if not emailfrom:
raise osv.except_osv(_('Error!'),
- _("No email ID found for your company address."))
- return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, res_id=obj.id)
+ _("Missing default email address or missing email on responsible user"))
+ return self.pool.get('mail.mail').create(cr, uid,
+ { 'email_from': emailfrom,
+ 'email_to': emails.join(','),
+ 'reply_to': reply_to,
+ 'state': 'outgoing',
+ 'subject': '[%d] %s' % (obj.id, tools.ustr(obj.name)),
+ 'body_html': '
%s
' % body,
+ 'res_id': obj.id,
+ 'model': obj._table_name,
+ 'auto_delete': True
+ }, context=context)
def do_check(self, cr, uid, action, obj, context=None):
diff --git a/addons/base_action_rule/i18n/nb.po b/addons/base_action_rule/i18n/nb.po
new file mode 100644
index 00000000000..7aae94c417f
--- /dev/null
+++ b/addons/base_action_rule/i18n/nb.po
@@ -0,0 +1,536 @@
+# Norwegian Bokmal translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:36+0000\n"
+"PO-Revision-Date: 2012-09-03 16:43+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Norwegian Bokmal \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-09-04 04:52+0000\n"
+"X-Generator: Launchpad (build 15890)\n"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_mail_to_user:0
+msgid ""
+"Check this if you want the rule to send an email to the responsible person."
+msgstr ""
+"Sjekk dette hvis du vil at regelen skal sende en e-post til ansvarlig person."
+
+#. module: base_action_rule
+#: field:base.action.rule,act_remind_partner:0
+msgid "Remind Partner"
+msgstr "Påminn partner"
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_partner_categ_id:0
+msgid "Partner Category"
+msgstr "Partner Kategori"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_mail_to_watchers:0
+msgid "Mail to Watchers (CC)"
+msgstr "Post til overvåkere (CC)"
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_state_to:0
+msgid "Button Pressed"
+msgstr "Knapp trykket"
+
+#. module: base_action_rule
+#: field:base.action.rule,model_id:0
+msgid "Object"
+msgstr "Objekt"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_mail_to_email:0
+msgid "Mail to these Emails"
+msgstr "Send mail til disse e-postene"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_state:0
+msgid "Set State to"
+msgstr "Still stat til"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_email_from:0
+msgid "Email From"
+msgstr "E-post fra"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Email Body"
+msgstr "E-post kropp"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_range_type:0
+msgid "Days"
+msgstr "Dager"
+
+#. module: base_action_rule
+#: field:base.action.rule,last_run:0
+msgid "Last Run"
+msgstr "Siste kjøring"
+
+#. module: base_action_rule
+#: code:addons/base_action_rule/base_action_rule.py:328
+#, python-format
+msgid "Error!"
+msgstr "Feil!"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_reply_to:0
+msgid "Reply-To"
+msgstr "Svar til"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_email_cc:0
+msgid ""
+"These people will receive a copy of the future communication between partner "
+"and users by email"
+msgstr ""
+"Disse menneskene vil motta en kopi av den fremtidige kommunikasjon mellom "
+"partner og brukere av e-post"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_range_type:0
+msgid "Minutes"
+msgstr "Minutter"
+
+#. module: base_action_rule
+#: field:base.action.rule,name:0
+msgid "Rule Name"
+msgstr "Regelnavn"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_remind_partner:0
+msgid ""
+"Check this if you want the rule to send a reminder by email to the partner."
+msgstr ""
+"Sjekk dette hvis du vil at regelen skal sende en påminnelse via e-post til "
+"partneren."
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Conditions on Model Partner"
+msgstr "Forholdene på Modell Partner"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_type:0
+msgid "Deadline"
+msgstr "Frist"
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_partner_id:0
+msgid "Partner"
+msgstr "Partner"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_subject)s = Object subject"
+msgstr "%(object_subject)s = Object subject"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Email Reminders"
+msgstr "E-post påminnelser"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Special Keywords to be Used in the Body"
+msgstr ""
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_state_from:0
+msgid "State"
+msgstr "Stat"
+
+#. module: base_action_rule
+#: model:ir.actions.act_window,help:base_action_rule.base_action_rule_act
+msgid ""
+"Use automated actions to automatically trigger actions for various screens. "
+"Example: a lead created by a specific user may be automatically set to a "
+"specific sales team, or an opportunity which still has status pending after "
+"14 days might trigger an automatic reminder email."
+msgstr ""
+"Bruke automatiserte tiltak for å automatisk utløse tiltak for ulike "
+"skjermer. Eksempel: en leder er opprettet av en bestemt bruker kan bli satt "
+"automatisk til en bestemt salgsteam, eller en mulighet som fortsatt har "
+"status påvente etter 14 dager kan utløse en automatisk påminnelse e-post."
+
+#. module: base_action_rule
+#: help:base.action.rule,act_mail_to_email:0
+msgid "Email-id of the persons whom mail is to be sent"
+msgstr "E-post ID av personer som post skal sendes"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Action Rule"
+msgstr "Handling regel"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Fields to Change"
+msgstr "Felter å endre"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_type:0
+msgid "Creation Date"
+msgstr "Opprettelsesdato"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_type:0
+msgid "Last Action Date"
+msgstr "Siste handlingsdato"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_range_type:0
+msgid "Hours"
+msgstr "Timer"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_id)s = Object ID"
+msgstr "%(object_ID)s = Object ID"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Delay After Trigger Date"
+msgstr "Forsinkelse Etter utløser Dato"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_remind_attach:0
+msgid "Remind with Attachment"
+msgstr "Minn med vedlegg"
+
+#. module: base_action_rule
+#: constraint:ir.cron:0
+msgid "Invalid arguments"
+msgstr "Ugyldige argumenter"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_user_id:0
+msgid "Set Responsible to"
+msgstr "Satt Ansvarlig for å"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_type:0
+msgid "None"
+msgstr "Ingen"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_email_to:0
+msgid ""
+"Use a python expression to specify the right field on which one than we will "
+"use for the 'To' field of the header"
+msgstr ""
+"Bruk en python uttrykk for å angi høyre feltet på hvilken enn vi vil bruke "
+"for Til-feltet på header."
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_user_phone)s = Responsible phone"
+msgstr "% (object_bruker_telefonen) s = Ansvarlig telefon"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid ""
+"The rule uses the AND operator. The model must match all non-empty fields so "
+"that the rule executes the action described in the 'Actions' tab."
+msgstr ""
+"Regelen bruker AND-operatoren. Modellen må matche alle-ikke tomme felt, slik "
+"at regelen utfører handlingen som er beskrevet i \"Handlinger\"-fanen."
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_date_range_type:0
+msgid "Delay type"
+msgstr "forsinkelse typen"
+
+#. module: base_action_rule
+#: help:base.action.rule,regex_name:0
+msgid ""
+"Regular expression for matching name of the resource\n"
+"e.g.: 'urgent.*' will search for records having name starting with the "
+"string 'urgent'\n"
+"Note: This is case sensitive search."
+msgstr ""
+"Regulært uttrykk for matchende navnet på ressursen\n"
+"f.eks: \". haster * 'vil søke etter poster som har navn som starter med "
+"strengen\" haster \"\n"
+"Merk: Dette er små bokstaver søk."
+
+#. module: base_action_rule
+#: field:base.action.rule,act_method:0
+msgid "Call Object Method"
+msgstr "Kall objektmetode"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_email_to:0
+msgid "Email To"
+msgstr "E-post til."
+
+#. module: base_action_rule
+#: help:base.action.rule,act_mail_to_watchers:0
+msgid ""
+"Check this if you want the rule to mark CC(mail to any other person defined "
+"in actions)."
+msgstr ""
+"Sjekk dette hvis du vil at regelen skal merkes CC (mail til en annen person "
+"som er definert i handlinger)."
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(partner)s = Partner name"
+msgstr "%(partner)s = Navn på partner"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Note"
+msgstr "Notat"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_email_from:0
+msgid ""
+"Use a python expression to specify the right field on which one than we will "
+"use for the 'From' field of the header"
+msgstr ""
+"Bruk en python uttrykk for å angi høyre feltet på hvilken enn vi vil bruke "
+"for Fra-feltet på overskriften"
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_date_range:0
+msgid "Delay after trigger date"
+msgstr "Forsinkelse etter triggerdato"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Conditions"
+msgstr "Betingelser"
+
+#. module: base_action_rule
+#: help:base.action.rule,trg_date_range:0
+msgid ""
+"Delay After Trigger Date,specifies you can put a negative number. If you "
+"need a delay before the trigger date, like sending a reminder 15 minutes "
+"before a meeting."
+msgstr ""
+"Forsinkelse Etter utløser Dato, spesifiserer du kan sette et negativt tall. "
+"Hvis du trenger en forsinkelse før avtrekkeren dato, som å sende en "
+"påminnelse 15 minutter før et møte."
+
+#. module: base_action_rule
+#: field:base.action.rule,active:0
+msgid "Active"
+msgstr "Aktiv"
+
+#. module: base_action_rule
+#: code:addons/base_action_rule/base_action_rule.py:329
+#, python-format
+msgid "No Email ID Found for your Company address!"
+msgstr ""
+
+#. module: base_action_rule
+#: field:base.action.rule,act_remind_user:0
+msgid "Remind Responsible"
+msgstr "Minn Ansvarlig"
+
+#. module: base_action_rule
+#: help:base.action.rule,sequence:0
+msgid "Gives the sequence order when displaying a list of rules."
+msgstr "Gir sekvens ordre når du viser en liste over regler."
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_range_type:0
+msgid "Months"
+msgstr "Måneder"
+
+#. module: base_action_rule
+#: field:base.action.rule,filter_id:0
+msgid "Filter"
+msgstr "Filtrer"
+
+#. module: base_action_rule
+#: selection:base.action.rule,trg_date_type:0
+msgid "Date"
+msgstr "Dato"
+
+#. module: base_action_rule
+#: help:base.action.rule,server_action_id:0
+msgid ""
+"Describes the action name.\n"
+"eg:on which object which action to be taken on basis of which condition"
+msgstr ""
+"Beskriver handlingens navn.\n"
+"f.eks: på hvilket objekt som tiltak som skal iverksettes på grunnlag av "
+"hvilken tilstand"
+
+#. module: base_action_rule
+#: model:ir.model,name:base_action_rule.model_ir_cron
+msgid "ir.cron"
+msgstr "ir.actions.actions"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_description)s = Object description"
+msgstr "% (object_beskrivelse) s = Object beskrivelse"
+
+#. module: base_action_rule
+#: constraint:base.action.rule:0
+msgid "Error: The mail is not well formated"
+msgstr "Feil: E-posten er ikke godt nok formatert"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Email Actions"
+msgstr "E-post handlinger"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Email Information"
+msgstr "E-post Informasjon"
+
+#. module: base_action_rule
+#: model:ir.model,name:base_action_rule.model_base_action_rule
+msgid "Action Rules"
+msgstr "Handlingsregler"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_mail_body:0
+msgid "Content of mail"
+msgstr "Innholdet av post"
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_user_id:0
+msgid "Responsible"
+msgstr "Ansvarlig"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(partner_email)s = Partner Email"
+msgstr "% (partner_e-post) s = Partner E-post"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_date)s = Creation date"
+msgstr "%(object_dato)s = opprettelsesdato"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_user_email)s = Responsible Email"
+msgstr "% (object_brukerens_e-post) s = Ansvarlig e-post"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_mail_body:0
+msgid "Mail body"
+msgstr "Mail kropp"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_remind_user:0
+msgid ""
+"Check this if you want the rule to send a reminder by email to the user."
+msgstr ""
+"Kryss av her hvis du vil at regelen skal sende en påminnelse til brukeren "
+"via e-post."
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Server Action to be Triggered"
+msgstr "Server Tiltak som skal Utløses"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_mail_to_user:0
+msgid "Mail to Responsible"
+msgstr "send mail til ansvarlig"
+
+#. module: base_action_rule
+#: field:base.action.rule,act_email_cc:0
+msgid "Add Watchers (Cc)"
+msgstr "Legg til overvåkere (Cc)"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Conditions on Model Fields"
+msgstr "Forholdene på Modell Felter"
+
+#. module: base_action_rule
+#: model:ir.actions.act_window,name:base_action_rule.base_action_rule_act
+#: model:ir.ui.menu,name:base_action_rule.menu_base_action_rule_form
+msgid "Automated Actions"
+msgstr "Automatiserte handinger"
+
+#. module: base_action_rule
+#: field:base.action.rule,server_action_id:0
+msgid "Server Action"
+msgstr "Tjenerhandling"
+
+#. module: base_action_rule
+#: field:base.action.rule,regex_name:0
+msgid "Regex on Resource Name"
+msgstr "Regex på Ressursnavn"
+
+#. module: base_action_rule
+#: help:base.action.rule,act_remind_attach:0
+msgid ""
+"Check this if you want that all documents attached to the object be attached "
+"to the reminder email sent."
+msgstr ""
+"Kryss av her om du vil at alle dokumenter knyttet til objektet festes til "
+"påminnelse e-post sendt."
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Conditions on Timing"
+msgstr "Vilkår for timing"
+
+#. module: base_action_rule
+#: field:base.action.rule,sequence:0
+msgid "Sequence"
+msgstr "Sekvens"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Actions"
+msgstr "Handlinger"
+
+#. module: base_action_rule
+#: help:base.action.rule,active:0
+msgid ""
+"If the active field is set to False, it will allow you to hide the rule "
+"without removing it."
+msgstr ""
+"Hvis det aktive feltet er satt til False, vil det tillate deg å skjule "
+"regelen uten å fjerne den."
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "%(object_user)s = Responsible name"
+msgstr "% (object_bruker) s = Ansvarlig navn"
+
+#. module: base_action_rule
+#: field:base.action.rule,create_date:0
+msgid "Create Date"
+msgstr "Opprettet dato"
+
+#. module: base_action_rule
+#: view:base.action.rule:0
+msgid "Conditions on States"
+msgstr "Vilkår for tilstander"
+
+#. module: base_action_rule
+#: field:base.action.rule,trg_date_type:0
+msgid "Trigger Date"
+msgstr "Uttløser dato"
+
+#~ msgid "Special Keywords to Be Used in The Body"
+#~ msgstr "Spesielle nøkkelord for bruk i meldingsinnhold"
+
+#, python-format
+#~ msgid "No E-Mail ID Found for your Company address!"
+#~ msgstr "Ingen E-post ID funnet for din firmaadresse!"
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index d560eaacd66..a6d5f6859af 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -471,18 +471,10 @@ property or property parameter."),
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
"""
Send mail for event invitation to event attendees.
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of attendee’s IDs.
@param email_from: Email address for user sending the mail
- @param context: A standard dictionary for contextual values
@return: True
"""
- if context is None:
- context = {}
-
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
- mail_message = self.pool.get('mail.message')
for att in self.browse(cr, uid, ids, context=context):
sign = att.sent_by_uid and att.sent_by_uid.signature or ''
sign = ' '.join(sign and sign.split('\n') or [])
@@ -508,17 +500,18 @@ property or property parameter."),
}
body = html_invitation % body_vals
if mail_to and email_from:
- attach = self.get_ics_file(cr, uid, res_obj, context=context)
- mail_message.schedule_with_attach(cr, uid,
- email_from,
- mail_to,
- sub,
- body,
- attachments=attach and {'invitation.ics': attach} or None,
- content_subtype='html',
- reply_to=email_from,
- context=context
- )
+ ics_file = self.get_ics_file(cr, uid, res_obj, context=context)
+ vals = {'email_from': email_from,
+ 'email_to': mail_to,
+ 'state': 'outgoing',
+ 'subject': sub,
+ 'body_html': body,
+ 'auto_delete': True}
+ if ics_file:
+ vals['attachment_ids'] = [(0,0,{'name': 'invitation.ics',
+ 'datas_fname': 'invitation.ics',
+ 'datas': str(ics_file).encode('base64')})]
+ self.pool.get('mail.mail').create(cr, uid, vals, context=context)
return True
def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv):
@@ -812,7 +805,6 @@ class calendar_alarm(osv.osv):
"""
if context is None:
context = {}
- mail_message = self.pool.get('mail.message')
current_datetime = datetime.now()
alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context)
@@ -849,36 +841,10 @@ class calendar_alarm(osv.osv):
else:
re_dates = [alarm.trigger_date]
- for r_date in re_dates:
- ref = alarm.model_id.model + ',' + str(alarm.res_id)
-
- # search for alreay sent requests
- #if request_obj.search(cr, uid, [('trigger_date', '=', r_date), ('ref_doc1', '=', ref)], context=context):
- #continue
-
- # Deactivated because of the removing of res.request
- # TODO: when cleaning calendar module, re-add this in a new mechanism
- #if alarm.action == 'display':
- #value = {
- #'name': alarm.name,
- #'act_from': alarm.user_id.id,
- #'act_to': alarm.user_id.id,
- #'body': alarm.description,
- #'trigger_date': r_date,
- #'ref_doc1': ref
- #}
- #request_id = request_obj.create(cr, uid, value)
- #request_ids = [request_id]
- #for attendee in res_obj.attendee_ids:
- #if attendee.user_id:
- #value['act_to'] = attendee.user_id.id
- #request_id = request_obj.create(cr, uid, value)
- #request_ids.append(request_id)
- #request_obj.request_send(cr, uid, request_ids)
-
+ if re_dates:
if alarm.action == 'email':
- sub = '[Openobject Reminder] %s' % (alarm.name)
- body = """
+ sub = '[OpenERP Reminder] %s' % (alarm.name)
+ body = """
""" % (alarm.name, alarm.trigger_date, alarm.description, \
alarm.user_id.name, alarm.user_id.signature)
mail_to = [alarm.user_id.email]
for att in alarm.attendee_ids:
mail_to.append(att.user_id.email)
if mail_to:
- mail_message.schedule_with_attach(cr, uid,
- tools.config.get('email_from', False),
- mail_to,
- sub,
- body,
- context=context
- )
+ vals = {
+ 'state': 'outgoing',
+ 'subject': sub,
+ 'body_html': body,
+ 'email_to': mail_to,
+ 'email_from': tools.config.get('email_from', mail_to),
+ }
+ self.pool.get('mail.mail').create(cr, uid, vals, context=context)
if next_trigger_date:
update_vals.update({'trigger_date': next_trigger_date})
else:
diff --git a/addons/base_module_record/i18n/nb.po b/addons/base_module_record/i18n/nb.po
new file mode 100644
index 00000000000..8465596f21b
--- /dev/null
+++ b/addons/base_module_record/i18n/nb.po
@@ -0,0 +1,271 @@
+# Norwegian Bokmal translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:36+0000\n"
+"PO-Revision-Date: 2012-09-04 13:40+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Norwegian Bokmal \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
+"X-Generator: Launchpad (build 15901)\n"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,category:0
+msgid "Category"
+msgstr "Kategori"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_objects,save:0
+msgid "Information"
+msgstr "Informasjon"
+
+#. module: base_module_record
+#: model:ir.model,name:base_module_record.model_ir_module_record
+msgid "ir.module.record"
+msgstr "ir.modul.opptak"
+
+#. module: base_module_record
+#: wizard_button:base_module_record.module_record_data,info,end:0
+#: wizard_button:base_module_record.module_record_data,save_yaml,end:0
+msgid "End"
+msgstr "Slutt"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_data,init:0
+#: wizard_view:base_module_record.module_record_objects,init:0
+msgid "Choose objects to record"
+msgstr "Velg objekter til opptak"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,author:0
+msgid "Author"
+msgstr "Forfatter"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,directory_name:0
+msgid "Directory Name"
+msgstr "Navn på katalog"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_data,init,filter_cond:0
+#: wizard_field:base_module_record.module_record_objects,init,filter_cond:0
+msgid "Records only"
+msgstr "Bare opptak"
+
+#. module: base_module_record
+#: selection:base_module_record.module_record_objects,info,data_kind:0
+msgid "Demo Data"
+msgstr "Demo data"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,save,module_filename:0
+msgid "Filename"
+msgstr "Filnavn"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,version:0
+msgid "Version"
+msgstr "Versjon"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_data,info:0
+#: wizard_view:base_module_record.module_record_data,init:0
+#: wizard_view:base_module_record.module_record_data,save_yaml:0
+#: wizard_view:base_module_record.module_record_objects,init:0
+msgid "Objects Recording"
+msgstr "objekter Innspilling"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_objects,save:0
+msgid ""
+"If you think your module could interest other people, we'd like you to "
+"publish it on http://www.openerp.com, in the 'Modules' section. You can do "
+"it through the website or using features of the 'base_module_publish' module."
+msgstr ""
+"Hvis du tror din modul kan interessere andre mennesker, vil vi gjerne at du "
+"publisere den på http://www.openerp.com, i 'Moduler-delen. Du kan gjøre det "
+"gjennom nettstedet eller bruke funksjonene i «base_module_publish»-modulen."
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_data,init,check_date:0
+#: wizard_field:base_module_record.module_record_objects,init,check_date:0
+msgid "Record from Date"
+msgstr "Dato fra opptak"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_data,end:0
+#: wizard_view:base_module_record.module_record_objects,end:0
+#: wizard_view:base_module_record.module_record_objects,info:0
+#: wizard_view:base_module_record.module_record_objects,save:0
+#: wizard_view:base_module_record.module_record_objects,save_yaml:0
+msgid "Module Recording"
+msgstr "Modul innspilling"
+
+#. module: base_module_record
+#: model:ir.actions.wizard,name:base_module_record.wizard_base_module_record_objects
+#: model:ir.ui.menu,name:base_module_record.menu_wizard_base_module_record_objects
+msgid "Export Customizations As a Module"
+msgstr "Eksporter Tilpasninger som en modul"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_objects,save:0
+msgid "Thanks in advance for your contribution."
+msgstr "Takk på forhånd for ditt bidrag."
+
+#. module: base_module_record
+#: help:base_module_record.module_record_data,init,objects:0
+#: help:base_module_record.module_record_objects,init,objects:0
+msgid "List of objects to be recorded"
+msgstr "Liste over objekter som skal spilles inn"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,description:0
+msgid "Full Description"
+msgstr "Full beskrivelse"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,name:0
+msgid "Module Name"
+msgstr "Modulnavn"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_data,init,objects:0
+#: wizard_field:base_module_record.module_record_objects,init,objects:0
+msgid "Objects"
+msgstr "Objekter"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,save,module_file:0
+#: wizard_field:base_module_record.module_record_objects,save_yaml,yaml_file:0
+msgid "Module .zip File"
+msgstr "Modul .zip fil"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_objects,save:0
+msgid "Module successfully created!"
+msgstr ""
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_objects,save_yaml:0
+msgid "YAML file successfully created !"
+msgstr "YAML fil opprettet!"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_data,info:0
+#: wizard_view:base_module_record.module_record_data,save_yaml:0
+msgid "Result, paste this to your module's xml"
+msgstr "Resultatet, lim denne til modulen xml"
+
+#. module: base_module_record
+#: selection:base_module_record.module_record_data,init,filter_cond:0
+#: selection:base_module_record.module_record_objects,init,filter_cond:0
+msgid "Created"
+msgstr "Opprettet"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_data,end:0
+#: wizard_view:base_module_record.module_record_objects,end:0
+msgid "Thanks For using Module Recorder"
+msgstr "Takk for at du brukte Modul opptaker."
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,website:0
+msgid "Documentation URL"
+msgstr "Dokumentasjon URL"
+
+#. module: base_module_record
+#: selection:base_module_record.module_record_data,init,filter_cond:0
+#: selection:base_module_record.module_record_objects,init,filter_cond:0
+msgid "Modified"
+msgstr "Modifisert"
+
+#. module: base_module_record
+#: wizard_button:base_module_record.module_record_data,init,record:0
+#: wizard_button:base_module_record.module_record_objects,init,record:0
+msgid "Record"
+msgstr "Opptak"
+
+#. module: base_module_record
+#: wizard_button:base_module_record.module_record_objects,info,save:0
+msgid "Continue"
+msgstr "Fortsett"
+
+#. module: base_module_record
+#: model:ir.actions.wizard,name:base_module_record.wizard_base_module_record_data
+#: model:ir.ui.menu,name:base_module_record.menu_wizard_base_module_record_data
+msgid "Export Customizations As Data File"
+msgstr "Eksport Tilpasninger Som datafil"
+
+#. module: base_module_record
+#: code:addons/base_module_record/wizard/base_module_save.py:129
+#, python-format
+msgid "Error"
+msgstr "Feil"
+
+#. module: base_module_record
+#: selection:base_module_record.module_record_objects,info,data_kind:0
+msgid "Normal Data"
+msgstr "Normal data"
+
+#. module: base_module_record
+#: wizard_button:base_module_record.module_record_data,end,end:0
+#: wizard_button:base_module_record.module_record_objects,end,end:0
+msgid "OK"
+msgstr "Ok"
+
+#. module: base_module_record
+#: model:ir.ui.menu,name:base_module_record.menu_wizard_base_mod_rec
+msgid "Module Creation"
+msgstr "modul Skapelsen"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_objects,info,data_kind:0
+msgid "Type of Data"
+msgstr "Type data"
+
+#. module: base_module_record
+#: wizard_view:base_module_record.module_record_objects,info:0
+msgid "Module Information"
+msgstr "Modul informasjon"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_data,init,info_yaml:0
+#: wizard_field:base_module_record.module_record_objects,init,info_yaml:0
+msgid "YAML"
+msgstr "YAML"
+
+#. module: base_module_record
+#: wizard_field:base_module_record.module_record_data,info,res_text:0
+#: wizard_field:base_module_record.module_record_data,save_yaml,res_text:0
+msgid "Result"
+msgstr "Resultat"
+
+#. module: base_module_record
+#: wizard_button:base_module_record.module_record_data,init,end:0
+#: wizard_button:base_module_record.module_record_objects,info,end:0
+#: wizard_button:base_module_record.module_record_objects,init,end:0
+msgid "Cancel"
+msgstr "Kanseller"
+
+#. module: base_module_record
+#: wizard_button:base_module_record.module_record_objects,save,end:0
+#: wizard_button:base_module_record.module_record_objects,save_yaml,end:0
+msgid "Close"
+msgstr "Lukke"
+
+#. module: base_module_record
+#: selection:base_module_record.module_record_data,init,filter_cond:0
+#: selection:base_module_record.module_record_objects,init,filter_cond:0
+msgid "Created & Modified"
+msgstr "Laget & Modifisert"
+
+#~ msgid "Module successfully created !"
+#~ msgstr "Modulen opprettet!"
diff --git a/addons/base_report_designer/i18n/nb.po b/addons/base_report_designer/i18n/nb.po
new file mode 100644
index 00000000000..9bf2b572a5f
--- /dev/null
+++ b/addons/base_report_designer/i18n/nb.po
@@ -0,0 +1,204 @@
+# Norwegian Bokmal translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:36+0000\n"
+"PO-Revision-Date: 2012-09-04 13:59+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Norwegian Bokmal \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
+"X-Generator: Launchpad (build 15901)\n"
+
+#. module: base_report_designer
+#: model:ir.model,name:base_report_designer.model_base_report_sxw
+msgid "base.report.sxw"
+msgstr "basen.rapport.sxw"
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+msgid "OpenERP Report Designer Configuration"
+msgstr "OpenERP Rapport Designer Konfigurasjon"
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+msgid ""
+"This plug-in allows you to create/modify OpenERP Reports into OpenOffice "
+"Writer."
+msgstr ""
+"Denne plug-in tillater deg å lage / endre OpenERP rapporter i OpenOffice "
+"Writer."
+
+#. module: base_report_designer
+#: view:base.report.file.sxw:0
+msgid "Upload the modified report"
+msgstr "Laste opp den endrede rapporten"
+
+#. module: base_report_designer
+#: view:base.report.file.sxw:0
+msgid "The .SXW report"
+msgstr ".SXW rapport"
+
+#. module: base_report_designer
+#: model:ir.model,name:base_report_designer.model_base_report_designer_installer
+msgid "base_report_designer.installer"
+msgstr "basen.rapport.designer.installatør"
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+msgid "_Close"
+msgstr "_Lukk"
+
+#. module: base_report_designer
+#: view:base.report.rml.save:0
+msgid "The RML Report"
+msgstr ""
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+msgid "Configure"
+msgstr "Konfigurer"
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+msgid "title"
+msgstr "tittel"
+
+#. module: base_report_designer
+#: field:base.report.file.sxw,report_id:0
+#: field:base.report.sxw,report_id:0
+msgid "Report"
+msgstr "Rapport"
+
+#. module: base_report_designer
+#: model:ir.model,name:base_report_designer.model_base_report_rml_save
+msgid "base.report.rml.save"
+msgstr "Basen.rapport.rml.lagre"
+
+#. module: base_report_designer
+#: model:ir.ui.menu,name:base_report_designer.menu_action_report_designer_wizard
+msgid "Report Designer"
+msgstr "Rapportdesigner"
+
+#. module: base_report_designer
+#: field:base_report_designer.installer,name:0
+msgid "File name"
+msgstr "Filnavn"
+
+#. module: base_report_designer
+#: view:base.report.file.sxw:0
+#: view:base.report.sxw:0
+msgid "Get a report"
+msgstr "Få en rapport"
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+#: model:ir.actions.act_window,name:base_report_designer.action_report_designer_wizard
+msgid "OpenERP Report Designer"
+msgstr "OpenERP Rapport designer"
+
+#. module: base_report_designer
+#: view:base.report.sxw:0
+msgid "Continue"
+msgstr "Fortsett"
+
+#. module: base_report_designer
+#: field:base.report.rml.save,file_rml:0
+msgid "Save As"
+msgstr "Lagre som"
+
+#. module: base_report_designer
+#: help:base_report_designer.installer,plugin_file:0
+msgid ""
+"OpenObject Report Designer plug-in file. Save as this file and install this "
+"plug-in in OpenOffice."
+msgstr ""
+"OpenObject Report Designer plug-in-filen. Lagre som denne filen og "
+"installere denne plugin-modulen i OpenOffice."
+
+#. module: base_report_designer
+#: view:base.report.rml.save:0
+msgid "Save RML FIle"
+msgstr "Lagre RML fil"
+
+#. module: base_report_designer
+#: field:base.report.file.sxw,file_sxw:0
+#: field:base.report.file.sxw,file_sxw_upload:0
+msgid "Your .SXW file"
+msgstr "Din .SXW fil"
+
+#. module: base_report_designer
+#: view:base_report_designer.installer:0
+msgid "Installation and Configuration Steps"
+msgstr "Installasjon og Konfigurasjon trinn"
+
+#. module: base_report_designer
+#: field:base_report_designer.installer,description:0
+msgid "Description"
+msgstr "Beskrivelse:"
+
+#. module: base_report_designer
+#: view:base.report.file.sxw:0
+msgid ""
+"This is the template of your requested report.\n"
+"Save it as a .SXW file and open it with OpenOffice.\n"
+"Don't forget to install the OpenERP SA OpenOffice package to modify it.\n"
+"Once it is modified, re-upload it in OpenERP using this wizard."
+msgstr ""
+"Dette er malen for den forespurte rapporten.\n"
+"Lagre det som en. Sxw fil og åpne den med OpenOffice.\n"
+"Ikke glem å installere OpenERP SA OpenOffice-pakken til å endre det.\n"
+"Når den er modifisert, laste opp det i OpenERP bruke denne veiviseren."
+
+#. module: base_report_designer
+#: field:base_report_designer.installer,config_logo:0
+msgid "Image"
+msgstr "Bilde"
+
+#. module: base_report_designer
+#: model:ir.actions.act_window,name:base_report_designer.action_view_base_report_sxw
+msgid "Base Report sxw"
+msgstr "Basen rapport sxw"
+
+#. module: base_report_designer
+#: model:ir.model,name:base_report_designer.model_base_report_file_sxw
+msgid "base.report.file.sxw"
+msgstr "basen.rapport.fil.sxw"
+
+#. module: base_report_designer
+#: field:base_report_designer.installer,plugin_file:0
+msgid "OpenObject Report Designer Plug-in"
+msgstr "OpenObject Rapport Designer Plug-in"
+
+#. module: base_report_designer
+#: model:ir.actions.act_window,name:base_report_designer.action_report_designer_installer
+msgid "OpenERP Report Designer Installation"
+msgstr "OpenERP Rapport Designer Installasjon"
+
+#. module: base_report_designer
+#: view:base.report.file.sxw:0
+#: view:base.report.rml.save:0
+#: view:base.report.sxw:0
+#: view:base_report_designer.installer:0
+msgid "Cancel"
+msgstr "Kanseller"
+
+#. module: base_report_designer
+#: model:ir.model,name:base_report_designer.model_ir_actions_report_xml
+msgid "ir.actions.report.xml"
+msgstr "ir.handlinger.rapport.xml"
+
+#. module: base_report_designer
+#: view:base.report.sxw:0
+msgid "Select your report"
+msgstr "Velg din rapport"
+
+#~ msgid "The RML report"
+#~ msgstr "RML rapport"
diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py
index 26afe548217..9bb2764d8bd 100644
--- a/addons/base_status/base_stage.py
+++ b/addons/base_status/base_stage.py
@@ -297,55 +297,31 @@ class base_stage(object):
destination=False)
def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True):
- mail_message = self.pool.get('mail.message')
- for case in self.browse(cr, uid, ids, context=context):
- if not destination and not case.email_from:
- return False
- if not case.user_id.email:
- return False
- if destination and case.section_id.user_id:
- case_email = case.section_id.user_id.email
- else:
- case_email = case.user_id.email
-
- src = case_email
- dest = case.user_id.email or ""
- body = case.description or ""
- for message in case.message_ids:
- if message.email_from and message.body:
- body = message.body
- break
-
- if not destination:
- src, dest = dest, case.email_from
- if body and case.user_id.signature:
- if body:
- body += '\n\n%s' % (case.user_id.signature)
- else:
- body = '\n\n%s' % (case.user_id.signature)
-
- body = self.format_body(body)
-
- attach_to_send = {}
-
- if attach:
- attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', case.id)])
- attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname', 'datas'])
- attach_to_send = dict(map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send))
-
- # Send an email
- subject = "Reminder: [%s] %s" % (str(case.id), case.name, )
- mail_message.schedule_with_attach(cr, uid,
- src,
- [dest],
- subject,
- body,
- model=self._name,
- reply_to=case.section_id.reply_to,
- res_id=case.id,
- attachments=attach_to_send,
- context=context
- )
+ if 'message_post' in self:
+ for case in self.browse(cr, uid, ids, context=context):
+ if destination:
+ recipient_id = case.user_id.partner_id.id
+ else:
+ if not case.email_from:
+ return False
+ recipient_id = self.pool.get('res.partner').find_or_create(cr, uid, case.email_from, context=context)
+
+ body = case.description or ""
+ for message in case.message_ids:
+ if message.type == 'email' and message.body:
+ body = message.body
+ break
+ body = self.format_body(body)
+ attach_to_send = {}
+ if attach:
+ attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', case.id)])
+ attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname', 'datas'])
+ attach_to_send = dict(map(lambda x: (x['datas_fname'], x['datas'].decode('base64')), attach_to_send))
+
+ subject = "Reminder: [%s] %s" % (case.id, case.name)
+ self.message_post(cr, uid, case.id, body=body,
+ subject=subject, attachments=attach_to_send,
+ partner_ids=[recipient_id], context=context)
return True
def _check(self, cr, uid, ids=False, context=None):
@@ -360,17 +336,6 @@ class base_stage(object):
def format_mail(self, obj, body):
return self.pool.get('base.action.rule').format_mail(obj, body)
- def message_thread_followers(self, cr, uid, ids, context=None):
- res = {}
- for case in self.browse(cr, uid, ids, context=context):
- l=[]
- if case.email_cc:
- l.append(case.email_cc)
- if case.user_id and case.user_id.email:
- l.append(case.user_id.email)
- res[case.id] = l
- return res
-
# ******************************
# Notifications
# ******************************
@@ -401,13 +366,13 @@ class base_stage(object):
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_post(cr, uid, [id], body=msg, context=context)
+ self.message_post(cr, uid, [id], body=msg, subtype="closed", 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_post(cr, uid, [id], body=msg, context=context)
+ msg = _('%s has been cancelled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
+ self.message_post(cr, uid, [id], body=msg, subtype="cancelled", context=context)
return True
def case_pending_send_note(self, cr, uid, ids, context=None):
diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py
index 36700b5b6c2..8b1ba655afc 100644
--- a/addons/crm/crm_action_rule.py
+++ b/addons/crm/crm_action_rule.py
@@ -46,21 +46,11 @@ class base_action_rule(osv.osv):
}
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from', False), context=None):
- mail_message = self.pool.get('mail.message')
- body = self.format_mail(obj, body)
- if not emailfrom:
- if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email:
- emailfrom = obj.user_id.email
-
- name = '[%d] %s' % (obj.id, tools.ustr(obj.name))
- emailfrom = tools.ustr(emailfrom)
- if hasattr(obj, 'section_id') and obj.section_id and obj.section_id.alias_id:
+ mail_id = super(base_action_rule, self).email_send(cr, uid, obj, emails, body, emailfrom=emailfrom, context=context)
+ if mail_id and hasattr(obj, 'section_id') and obj.section_id and obj.section_id.alias_id:
reply_to = obj.section_id.alias_id.name_get()[0][1]
- else:
- reply_to = emailfrom
- if not emailfrom:
- raise osv.except_osv(_('Error!'), _("There is no email for your company address."))
- return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model=obj._name, reply_to=reply_to, res_id=obj.id)
+ self.pool.get('mail.mail').write(cr, uid, [mail_id], {'reply_to': reply_to}, context=context)
+ return mail_id
def do_check(self, cr, uid, action, obj, context=None):
ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context)
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 801895885b2..36af90fcf07 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -671,24 +671,6 @@ class crm_lead(base_stage, osv.osv):
partner_ids[lead.id] = partner_id
return partner_ids
- def _send_mail_to_salesman(self, cr, uid, lead, context=None):
- """
- Send mail to salesman with updated Lead details.
- @ lead: browse record of 'crm.lead' object.
- """
- #TOFIX: mail template should be used here instead of fix subject, body text.
- message = self.pool.get('mail.message')
- email_to = lead.user_id and lead.user_id.email
- if not email_to:
- return False
-
- email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.email or email_to
- partner = lead.partner_id and lead.partner_id.name or lead.partner_name
- subject = "lead %s converted into opportunity" % lead.name
- body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description)
- return message.schedule_with_attach(cr, uid, email_from, [email_to], subject, body)
-
-
def allocate_salesman(self, cr, uid, ids, user_ids, team_id=False, context=None):
index = 0
for lead_id in ids:
diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml
index 4442b22e77e..b3c00256b06 100644
--- a/addons/crm/crm_lead_demo.xml
+++ b/addons/crm/crm_lead_demo.xml
@@ -23,7 +23,7 @@
1
-
+ Hello,
I am Jason from Le Club SARL,
@@ -47,7 +47,7 @@ Can you send details,4
-
+
@@ -108,7 +108,7 @@ Can you send details,
3
-
+ Hi, Can you send a quotation for 20 Computers with speakers?
Regards,
@@ -135,7 +135,7 @@ Contact: +1 813 494 50053
-
+
@@ -194,7 +194,7 @@ Contact: +1 813 494 5005
2
-
+
@@ -297,7 +297,7 @@ Andrew
Meeting for pricing information.
-
+
@@ -342,7 +342,7 @@ Andrew
Call to ask system requirement
-
+
@@ -411,7 +411,7 @@ Andrew
Call to define real needs about training
-
+
@@ -434,7 +434,7 @@ Andrew
Ask for the good receprion of the proposition
-
+
@@ -466,7 +466,7 @@ Andrew
3
-
+
@@ -484,7 +484,7 @@ Andrew
3
-
+
@@ -519,7 +519,7 @@ Andrew
5
-
+
@@ -542,7 +542,7 @@ Andrew
2Conf call with technical service
-
+
diff --git a/addons/crm/res_config.py b/addons/crm/res_config.py
index c6d33b4bec2..1d30abdc33c 100644
--- a/addons/crm/res_config.py
+++ b/addons/crm/res_config.py
@@ -38,7 +38,7 @@ class crm_configuration(osv.osv_memory):
'module_import_google': fields.boolean("Google (Contacts and Calendar)",
help="""Import google contact in partner address and add google calendar events details in Meeting.
This installs the module import_google."""),
- 'module_google_map': fields.boolean("add google maps on customer",
+ 'module_google_map': fields.boolean("add google maps on customers",
help="""Locate customers on Google Map.
This installs the module google_map."""),
'group_fund_raising': fields.boolean("Manage Fund Raising",
diff --git a/addons/crm/wizard/crm_partner_to_opportunity_view.xml b/addons/crm/wizard/crm_partner_to_opportunity_view.xml
index 765a22de0a6..7f0b5957071 100644
--- a/addons/crm/wizard/crm_partner_to_opportunity_view.xml
+++ b/addons/crm/wizard/crm_partner_to_opportunity_view.xml
@@ -23,23 +23,5 @@
-
-
-
- Create Opportunity
- crm.partner2opportunity
- form
- form,tree,kanban,calendar
- new
-
-
-
-
-
diff --git a/addons/crm_caldav/i18n/nb.po b/addons/crm_caldav/i18n/nb.po
new file mode 100644
index 00000000000..c5a1c3cfe37
--- /dev/null
+++ b/addons/crm_caldav/i18n/nb.po
@@ -0,0 +1,33 @@
+# Norwegian Bokmal translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:36+0000\n"
+"PO-Revision-Date: 2012-09-04 14:04+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Norwegian Bokmal \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
+"X-Generator: Launchpad (build 15901)\n"
+
+#. module: crm_caldav
+#: model:ir.actions.act_window,name:crm_caldav.action_caldav_browse
+msgid "Caldav Browse"
+msgstr "CalDAV Bla"
+
+#. module: crm_caldav
+#: model:ir.ui.menu,name:crm_caldav.menu_caldav_browse
+msgid "Synchronize This Calendar"
+msgstr "Synkroniser denne kalenderen"
+
+#. module: crm_caldav
+#: model:ir.model,name:crm_caldav.model_crm_meeting
+msgid "Meeting"
+msgstr "Møte"
diff --git a/addons/crm_claim/test/ui/claim_demo.yml b/addons/crm_claim/test/ui/claim_demo.yml
index 6b6d380f5be..044e0482e93 100644
--- a/addons/crm_claim/test/ui/claim_demo.yml
+++ b/addons/crm_claim/test/ui/claim_demo.yml
@@ -12,4 +12,3 @@
self.message_update(cr, uid,[ref('crm_claim_4')], {'subject': 'Claim Update record','body': 'first training session completed',})
except:
pass
-
diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml
index 057d5240847..cd2e3f08c9a 100644
--- a/addons/crm_partner_assign/crm_lead_view.xml
+++ b/addons/crm_partner_assign/crm_lead_view.xml
@@ -19,7 +19,7 @@
attrs="{'invisible':[('partner_assigned_id','=',False)]}"
name="%(crm_lead_forward_to_partner_act)d"
icon="terp-mail-forward" type="action"
- context="{'mail.compose.message.mode': 'forward', 'default_partner_ids': [partner_assigned_id]}"/>
+ context="{'default_composition_mode': 'forward', 'default_partner_ids': [partner_assigned_id]}"/>
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 5b0fe97b015..0cac38e0163 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -36,12 +36,12 @@ class crm_lead_forward_to_partner(osv.osv_memory):
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'
+ old_mode = context.get('default_composition_mode', 'forward')
+ context['default_composition_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']
+ context['default_composition_mode'] = old_mode
+ res['composition_mode'] = context['default_composition_mode']
return res
def _get_composition_mode_selection(self, cr, uid, context=None):
@@ -89,11 +89,6 @@ class crm_lead_forward_to_partner(osv.osv_memory):
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_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
@@ -106,9 +101,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
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'}
@@ -126,7 +119,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
self.send_mail(cr, uid, ids, context=context)
# for case in lead.browse(cr, uid, lead_ids, context=context):
- # TDE: WHAT TO DO WITH THAT ?
+ # TODO: 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)
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 600bd301b3f..0d8f27eec74 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
@@ -16,7 +16,7 @@
on_change="on_change_history_mode(history_mode, model, res_id)"/>
+ on_change="onchange_partner_ids(partner_ids)"/>
@@ -51,7 +51,7 @@
key2="client_action_multi" name="Mass forward to partner"
res_model="crm.lead.forward.to.partner" src_model="crm.lead"
view_mode="form" target="new" view_type="form"
- context="{'mail.compose.message.mode' : 'mass_mail'}"
+ context="{'default_composition_mode' : 'mass_mail'}"
view_id="crm_lead_forward_to_partner_form"
/>
diff --git a/addons/crm_todo/i18n/nb.po b/addons/crm_todo/i18n/nb.po
new file mode 100644
index 00000000000..44a49165e40
--- /dev/null
+++ b/addons/crm_todo/i18n/nb.po
@@ -0,0 +1,95 @@
+# Norwegian Bokmal translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:36+0000\n"
+"PO-Revision-Date: 2012-09-04 14:07+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Norwegian Bokmal \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
+"X-Generator: Launchpad (build 15901)\n"
+
+#. module: crm_todo
+#: model:ir.model,name:crm_todo.model_project_task
+msgid "Task"
+msgstr "Oppgave"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "Timebox"
+msgstr "Timeboks"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "For cancelling the task"
+msgstr "For å avbryte oppgaven"
+
+#. module: crm_todo
+#: constraint:project.task:0
+msgid "Error ! Task end-date must be greater then task start-date"
+msgstr "Feil! Oppgave sluttdato må være større enn oppgave startdato"
+
+#. module: crm_todo
+#: model:ir.model,name:crm_todo.model_crm_lead
+msgid "crm.lead"
+msgstr "crm.lead"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "Next"
+msgstr "Neste"
+
+#. module: crm_todo
+#: model:ir.actions.act_window,name:crm_todo.crm_todo_action
+#: model:ir.ui.menu,name:crm_todo.menu_crm_todo
+msgid "My Tasks"
+msgstr "Mine oppgaver"
+
+#. module: crm_todo
+#: view:crm.lead:0
+#: field:crm.lead,task_ids:0
+msgid "Tasks"
+msgstr "Oppgaver"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "Done"
+msgstr "Utført"
+
+#. module: crm_todo
+#: constraint:project.task:0
+msgid "Error ! You cannot create recursive tasks."
+msgstr "Feil! Du kan ikke lage en rekursive oppgaver."
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "Cancel"
+msgstr "Kanseller"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "Extra Info"
+msgstr "Ekstra informasjon"
+
+#. module: crm_todo
+#: field:project.task,lead_id:0
+msgid "Lead / Opportunity"
+msgstr "Lede / mulighet"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "For changing to done state"
+msgstr "For å bytte til ferdig tilstand"
+
+#. module: crm_todo
+#: view:crm.lead:0
+msgid "Previous"
+msgstr "Tidligere"
diff --git a/addons/document_page/static/src/css/document_page.css b/addons/document_page/static/src/css/document_page.css
index 723ff8d9b11..77597fb4281 100644
--- a/addons/document_page/static/src/css/document_page.css
+++ b/addons/document_page/static/src/css/document_page.css
@@ -1,7 +1,3 @@
-.oe_form_readonly .oe_notebook {
- display: none;
-}
-
.oe_document_page ul, .oe_document_page li {
padding: 2px 8px;
margin: 2px 8px;
diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
index 73dc5ed2754..b68005bd997 100644
--- a/addons/email_template/email_template.py
+++ b/addons/email_template/email_template.py
@@ -171,7 +171,7 @@ class email_template(osv.osv):
'res_model': 'mail.compose.message',
'src_model': src_obj,
'view_type': 'form',
- 'context': "{'mail.compose.message.mode':'mass_mail', 'mail.compose.template_id' : %d}" % (template.id),
+ 'context': "{'default_composition_mode': 'mass_mail', 'default_template_id' : %d}" % (template.id),
'view_mode':'form,tree',
'view_id': res_id,
'target': 'new',
diff --git a/addons/email_template/tests/test_mail.py b/addons/email_template/tests/test_mail.py
index 5ca608e6b81..05f8f81d76d 100644
--- a/addons/email_template/tests/test_mail.py
+++ b/addons/email_template/tests/test_mail.py
@@ -71,23 +71,50 @@ class test_message_compose(common.TransactionCase):
_subject1 = 'Pigs'
_subject2 = 'Bird'
_body_text1 = 'Pigs rules'
- _body_text_html1 = 'Pigs rules
Admin
'
+ _body_text_html1 = 'Fans of Pigs, unite !\n
Admin
\n'
_body_text2 = 'I am angry !'
_body_text_html2 = 'I am angry !
Admin
'
- # CASE1: create in mass_mail composition mode that should work with email_template installed
+ # CASE1: create in comment
+ compose_id = mail_compose.create(cr, uid,
+ {'subject': 'Forget me subject', 'body': 'Dummy body'},
+ {'default_composition_mode': 'comment', 'default_model': 'mail.group',
+ 'default_res_id': self.group_pigs_id, 'default_use_template': True,
+ 'active_ids': [self.group_pigs_id, group_bird_id] })
+ compose = mail_compose.browse(cr, uid, compose_id)
+
+ # Perform 'onchange_template_id' with 'use_template' set
+ values = mail_compose.onchange_template_id(cr, uid, [], compose.use_template, email_template_id, compose.composition_mode, compose.model, compose.res_id)
+ compose.write(values.get('value', {}), {'default_composition_mode': 'comment', 'default_model': 'mail.group'})
+ compose.refresh()
+ message_pids = [partner.id for partner in compose.partner_ids]
+ partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
+ partners = self.res_partner.browse(cr, uid, partner_ids)
+ # Test: subject, body, partner_ids
+ self.assertEqual(compose.subject, _subject1, 'mail.compose.message subject incorrect')
+ self.assertEqual(compose.body, _body_text_html1, 'mail.compose.message body incorrect')
+ self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
+
+ # Perform 'onchange_use_template': use_template is not set anymore
+ values = mail_compose.onchange_use_template(cr, uid, [], not compose.use_template, compose.template_id, compose.composition_mode, compose.model, compose.res_id)
+ compose.write(values.get('value', {}), {'default_composition_mode': 'comment', 'default_model': 'mail.group'})
+ compose.refresh()
+ # Test: subject, body, partner_ids
+ self.assertEqual(compose.subject, False, 'mail.compose.message subject incorrect')
+ self.assertEqual(compose.body, '', 'mail.compose.message body incorrect')
+
+ # CASE12 create in mass_mail composition
compose_id = mail_compose.create(cr, uid,
{'subject': 'Forget me subject', 'body': 'Dummy body'},
{'default_composition_mode': 'mass_mail', 'default_model': 'mail.group',
'default_res_id': -1, 'default_use_template': True,
- 'active_ids': [self.group_pigs_id, group_bird_id], 'default_template_id': email_template_id})
+ 'active_ids': [self.group_pigs_id, group_bird_id] })
compose = mail_compose.browse(cr, uid, compose_id)
- # print compose.subject
-
- # Try the 'onchange_template_id'
- values = mail_compose.onchange_template_id(cr, uid, [], compose.use_template, compose.template_id, compose.composition_mode, compose.model, compose.res_id)
+ # Test 'onchange_template_id' with 'use_template' set
+ values = mail_compose.onchange_template_id(cr, uid, [], compose.use_template, email_template_id, compose.composition_mode, compose.model, compose.res_id)
print values
+ # self.assertEqual()
# compose.write(values['value'])
values = mail_compose.onchange_use_template(cr, uid, [], not compose.use_template, compose.template_id, compose.composition_mode, compose.model, compose.res_id)
print values
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index 71586649f37..85dfe8bc843 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -28,15 +28,17 @@ from tools.translate import _
class mail_compose_message(osv.osv_memory):
_inherit = 'mail.compose.message'
+ _compose_fields = ['body', 'body_html', 'subject', 'partner_ids', 'attachment_ids']
def _get_templates(self, cr, uid, context=None):
if context is None:
context = {}
model = False
email_template_obj= self.pool.get('email.template')
+ message_id = context.get('default_parent_id', context.get('message_id', context.get('active_id')))
- if context.get('default_composition_mode') == 'reply' and context.get('active_id'):
- message_data = self.pool.get('mail.message').browse(cr, uid, int(context.get('active_id')), context)
+ if context.get('default_composition_mode') == 'reply' and message_id:
+ message_data = self.pool.get('mail.message').browse(cr, uid, message_id, context=context)
if message_data:
model = message_data.model
else:
@@ -62,32 +64,17 @@ class mail_compose_message(osv.osv_memory):
def onchange_template_id(self, cr, uid, ids, use_template, template_id, composition_mode, model, res_id, context=None):
""" - use_template not set: return default_get
- - use_template set:
- - mass_mailing: we cannot render, so return the template values
- - else: return rendered values """
- fields = ['body', 'body_html', 'subject', 'partner_ids', 'email_to', 'email_cc']
+ - use_template set in mass_mailing: we cannot render, so return the template values
+ - use_template set: return rendered values """
if use_template and template_id and composition_mode == 'mass_mail':
- values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
+ values = self.pool.get('email.template').read(cr, uid, template_id, self._compose_fields, context)
elif use_template and template_id:
- values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
-
- values['attachment_ids'] = []
- attachment_obj = self.pool.get('ir.attachment')
- for attach_fname, attach_datas in values.get('attachments', []):
- data_attach = {
- 'name': attach_fname,
- 'datas': attach_datas,
- 'datas_fname': attach_fname,
- 'description': fname,
- 'res_model': model,
- 'res_id': res_id,
- }
- values['attachment_ids'].append(attachment_obj.create(cr, uid, data_attach), context=context)
+ values = self.generate_email_for_composer(cr, uid, template_id, res_id, context=context)
else:
- values = self.default_get(cr, uid, fields, context=context)
+ values = self.default_get(cr, uid, self._compose_fields, context=context)
- if values.get('body_html') and not values.get('body'):
- values['body'] = values.get('body_html')
+ if values.get('body_html'):
+ values['body'] = values.pop('body_html')
values.update(use_template=use_template, template_id=template_id)
return {'value': values}
@@ -98,14 +85,17 @@ class mail_compose_message(osv.osv_memory):
for record in self.browse(cr, uid, ids, context=context):
onchange_res = self.onchange_use_template(cr, uid, ids, not record.use_template,
record.template_id, record.composition_mode, record.model, record.res_id, context=context)['value']
- record.write(onchange_res)
+ record.write(onchange_res.get('value', {}))
return True
def onchange_use_template(self, cr, uid, ids, use_template, template_id, composition_mode, model, res_id, context=None):
""" onchange_use_template (values: True or False). If use_template is
False, we do like an onchange with template_id False for values """
- return self.onchange_template_id(cr, uid, ids, use_template,
+ values = self.onchange_template_id(cr, uid, ids, use_template,
template_id, composition_mode, model, res_id, context=context)
+ if use_template:
+ values['content_subtype'] = 'html'
+ return values
def save_as_template(self, cr, uid, ids, context=None):
""" hit save as template button: current form value will be a new
@@ -113,8 +103,7 @@ class mail_compose_message(osv.osv_memory):
email_template = self.pool.get('email.template')
ir_model_pool = self.pool.get('ir.model')
for record in self.browse(cr, uid, ids, context=context):
- model = record.model
- model_ids = ir_model_pool.search(cr, uid, [('model', '=', model)])
+ model_ids = ir_model_pool.search(cr, uid, [('model', '=', record.model)], context=context)
model_id = model_ids and model_ids[0] or False
model_name = ''
if model_id:
@@ -135,14 +124,49 @@ class mail_compose_message(osv.osv_memory):
# Wizard validation and send
#------------------------------------------------------
+ def generate_email_for_composer(self, cr, uid, template_id, res_id, context=None):
+ """ Call email_template.generate_email(), get fields relevant for
+ mail.compose.message, transform email_cc and email_to into partner_ids """
+ fields = ['body', 'body_html', 'subject', 'email_to', 'email_cc', 'attachment_ids']
+ template_values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
+ values = {field: template_values[field] for field in fields if template_values.get(field)}
+
+ # transform email_to, email_cc into partner_ids
+ values['partner_ids'] = []
+ mails = tools.email_split(values.pop('email_to', '') + ' ' + values.pop('email_cc', ''))
+ for mail in mails:
+ partner_search_ids = self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', mail)], context=context)
+ if partner_search_ids:
+ values['partner_ids'].append((4, partner_search_ids[0]))
+ else:
+ partner_id = self.pool.get('res.partner').name_create(cr, uid, mail, context=context)[0]
+ partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
+ values['partner_ids'].append((4, partner_id))
+
+ # transform attachments into attachment_ids
+ values['attachment_ids'] = []
+ for attach_fname, attach_datas in template_values.get('attachments', []):
+ data_attach = {
+ 'name': attach_fname,
+ 'datas': attach_datas,
+ 'datas_fname': attach_fname,
+ 'res_model': model,
+ 'res_id': res_id,
+ }
+ values['attachment_ids'].append((0, 0, data_attach))
+
+ return values
+
def render_message(self, cr, uid, wizard, model, res_id, context=None):
""" Generate an email from the template for given (model, res_id) pair.
This method is meant to be inherited by email_template that will
produce a more complete dictionary, with email_to, ...
"""
# render the template to get the email
+ fields = ['body', 'body_html', 'subject', 'email_to', 'email_cc', 'partner_ids', 'attachment_ids']
template_values = self.pool.get('email.template').generate_email(cr, uid, wizard.template_id, res_id, context=context)
- # TDE TODO: handle fields to update / not to update (mail_server_id, auto_delete, ...)
+ template_values = {field: template_values[field] for field in fields if template_values.get(field)}
+
# transform email_to, email_cc into partner_ids
partner_ids = []
mails = tools.email_split(template_values.pop('email_to', '') + ' ' + template_values.pop('email_cc', ''))
@@ -154,10 +178,10 @@ class mail_compose_message(osv.osv_memory):
partner_id = self.pool.get('res.partner').name_create(cr, uid, mail, context=context)[0]
partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
partner_ids.append((4, partner_id))
+
# get values to return
email_dict = super(mail_compose_message, self).render_message(cr, uid, wizard, model, res_id, context)
- email_dict.update(template_values)
- email_dict.update(partner_ids=partner_ids, attachments=template_values.get('attachments'))
+ email_dict.update(template_values, partner_ids=partner_ids)
return email_dict
def render_template(self, cr, uid, template, model, res_id, context=None):
diff --git a/addons/event/email_template.xml b/addons/event/email_template.xml
index 49738185547..95ffbf46d8d 100644
--- a/addons/event/email_template.xml
+++ b/addons/event/email_template.xml
@@ -7,15 +7,12 @@
${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.
-
- we thank you for your participation
-
- best regards
-
+ 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.
+
Thank you for your participation!
+
Best regards
]]>
@@ -27,15 +24,12 @@
${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.
-
- we thank you for your participation
-
- best regards
-
+ Hello ${object.name},
+
We confirm 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 agenda...) as soon as the event is confirmed.
by on
+ context="{'default_composition_mode':'reply', 'default_parent_id': active_id}" states='received,sent,exception,cancel'/>
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index 4a25a8aa0c9..1559a412e44 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -136,7 +136,8 @@ class mail_message(osv.Model):
_defaults = {
'type': 'email',
'date': lambda *a: fields.datetime.now(),
- 'author_id': _get_default_author
+ 'author_id': lambda self,cr,uid,ctx: self._get_default_author(cr, uid, ctx),
+ 'body': '',
}
#------------------------------------------------------
diff --git a/addons/mail/mail_message_subtype.py b/addons/mail/mail_message_subtype.py
index 0c4f5e7baa6..ab41c83ed61 100644
--- a/addons/mail/mail_message_subtype.py
+++ b/addons/mail/mail_message_subtype.py
@@ -28,8 +28,7 @@ class mail_message_subtype(osv.osv):
_description = 'mail_message_subtype'
_columns = {
'name': fields.char(' Message Subtype ', size = 128,
- required = True, select = 1,
- help = 'Subtype Of Message'),
+ required = True, help = 'Subtype Of Message'),
'model_ids': fields.many2many('ir.model',
'mail_message_subtyp_message_rel',
'message_subtype_id', 'model_id', 'Model',
diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml
index 3e9f0d6a7ff..8438eba6979 100644
--- a/addons/mail/mail_message_view.xml
+++ b/addons/mail/mail_message_view.xml
@@ -90,13 +90,15 @@
News Feedmail.wall
-
+ My Feedsmail.wall
-
+
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index ecf8bb5485b..2422f556446 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -29,7 +29,6 @@ import time
import tools
import xmlrpclib
-from email.utils import parsedate
from email.message import Message
from mail_message import decode
from osv import osv, fields
@@ -42,24 +41,20 @@ def decode_header(message, header, separator=' '):
return separator.join(map(decode,message.get_all(header, [])))
class many2many_reference(fields.many2many):
- """ many2many_reference is an override of fields.many2many. It manages
- many2many-like table where one id is given by two fields, res_model
- and res_id.
- """
+ """ many2many_reference manages many2many fields where one id is found
+ by a reference-like key (a char column in addition to the foreign id).
+ The reference_column attribute on the many2many fields is used;
+ if not defined, ``res_model`` is used. """
def _get_query_and_where_params(self, cr, model, ids, values, where_params):
- """ Add in where:
- - ``mail_followers``.res_model = 'crm.lead'
- """
- # reference column name: given by attribute or res_model
- ref_col_name = self.ref_col_name if self.ref_col_name else 'res_model'
- values.update({'ref_col_name': ref_col_name, 'ref_col_value': model._name})
-
+ """ Add in where condition like mail_followers.res_model = 'crm.lead' """
+ reference_column = self.reference_column if self.reference_column else 'res_model'
+ values.update(reference_column=reference_column, reference_value=model._name)
query = 'SELECT %(rel)s.%(id2)s, %(rel)s.%(id1)s \
FROM %(rel)s, %(from_c)s \
WHERE %(rel)s.%(id1)s IN %%s \
AND %(rel)s.%(id2)s = %(tbl)s.id \
- AND %(rel)s.%(ref_col_name)s = \'%(ref_col_value)s\' \
+ AND %(rel)s.%(reference_column)s = \'%(reference_value)s\' \
%(where_c)s \
%(order_by)s \
%(limit)s \
@@ -68,41 +63,41 @@ class many2many_reference(fields.many2many):
return query, where_params
def set(self, cr, model, id, name, values, user=None, context=None):
- """ Override to add the res_model field in queries. """
+ """ Override to add the reference field in queries. """
if not values: return
rel, id1, id2 = self._sql_names(model)
obj = model.pool.get(self._obj)
# reference column name: given by attribute or res_model
- ref_col_name = self.ref_col_name if self.ref_col_name else 'res_model'
+ reference_column = self.reference_column if self.reference_column else 'res_model'
for act in values:
if not (isinstance(act, list) or isinstance(act, tuple)) or not act:
continue
if act[0] == 0:
idnew = obj.create(cr, user, act[2], context=context)
- cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+ref_col_name+') VALUES (%s,%s,%s)', (id, idnew, model._name))
+ cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+reference_column+') VALUES (%s,%s,%s)', (id, idnew, model._name))
elif act[0] == 3:
- cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+ref_col_name+'=%s', (id, act[1], model._name))
+ cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+reference_column+'=%s', (id, act[1], model._name))
elif act[0] == 4:
# following queries are in the same transaction - so should be relatively safe
- cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+ref_col_name+'=%s', (id, act[1], model._name))
+ cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+reference_column+'=%s', (id, act[1], model._name))
if not cr.fetchone():
- cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+ref_col_name+') VALUES (%s,%s,%s)', (id, act[1], model._name))
+ cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+reference_column+') VALUES (%s,%s,%s)', (id, act[1], model._name))
elif act[0] == 5:
- cr.execute('delete from '+rel+' where '+id1+' = %s AND '+ref_col_name+'=%s', (id, model._name))
+ cr.execute('delete from '+rel+' where '+id1+' = %s AND '+reference_column+'=%s', (id, model._name))
elif act[0] == 6:
d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
d1 = ' and ' + ' and '.join(d1)
else:
d1 = ''
- cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+ref_col_name+'=%s AND '+id2+' IN (SELECT '+rel+'.'+id2+' FROM '+rel+', '+','.join(tables)+' WHERE '+rel+'.'+id1+'=%s AND '+rel+'.'+id2+' = '+obj._table+'.id '+ d1 +')', [id, model._name, id]+d2)
+ cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+reference_column+'=%s AND '+id2+' IN (SELECT '+rel+'.'+id2+' FROM '+rel+', '+','.join(tables)+' WHERE '+rel+'.'+id1+'=%s AND '+rel+'.'+id2+' = '+obj._table+'.id '+ d1 +')', [id, model._name, id]+d2)
for act_nbr in act[2]:
- cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+ref_col_name+') VALUES (%s,%s,%s)', (id, act_nbr, model._name))
+ cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+reference_column+') VALUES (%s,%s,%s)', (id, act_nbr, model._name))
# cases 1, 2: performs write and unlink -> default implementation is ok
else:
return super(many2many_reference, self).set(cr, model, id, name, values, user, context)
-class mail_thread(osv.Model):
+class mail_thread(osv.AbstractModel):
''' mail_thread model is meant to be inherited by any model that needs to
act as a discussion topic on which messages can be attached. Public
methods are prefixed with ``message_`` in order to avoid name
@@ -161,19 +156,18 @@ class mail_thread(osv.Model):
type='boolean', string='Is a Follower', multi='_get_message_data'),
'message_follower_ids': many2many_reference('res.partner',
'mail_followers', 'res_id', 'partner_id',
- ref_col_name='res_model', string='Followers'),
+ reference_column='res_model', string='Followers'),
'message_comment_ids': fields.one2many('mail.message', 'res_id',
- domain=lambda self: [('model','=',self._name),('type','in',('comment','email'))],
- string='Related Messages',
- help="All messages related to the current document."),
+ domain=lambda self: [('model', '=', self._name), ('type', 'in', ('comment', 'email'))],
+ string='Comments and emails',
+ help="Comments and emails"),
'message_ids': fields.one2many('mail.message', 'res_id',
domain=lambda self: [('model','=',self._name)],
- string='Related Messages',
- help="All messages related to the current document."),
+ string='Messages',
+ help="Messages and communication history"),
'message_unread': fields.function(_get_message_data, fnct_search=_search_unread,
- string='Has Unread Messages', type='boolean',
- help="When checked, new messages require your attention.",
- multi="_get_message_data"),
+ type='boolean', string='Unread Messages', multi="_get_message_data",
+ help="If checked new messages require your attention."),
'message_summary': fields.function(_get_message_data, method=True,
type='text', string='Summary', multi="_get_message_data",
help="Holds the Chatter summary (number of messages, ...). "\
@@ -186,7 +180,7 @@ class mail_thread(osv.Model):
#------------------------------------------------------
def create(self, cr, uid, vals, context=None):
- """ Override of create to subscribe the current user. """
+ """ Override to subscribe the current user. """
thread_id = super(mail_thread, self).create(cr, uid, vals, context=context)
self.message_subscribe_users(cr, uid, [thread_id], [uid], context=context)
return thread_id
@@ -217,14 +211,20 @@ class mail_thread(osv.Model):
# Mail gateway
#------------------------------------------------------
+ def message_capable_models(self, cr, uid, context=None):
+ """ Used by the plugin addon, based for plugin_outlook and others. """
+ ret_dict = {}
+ for model_name in self.pool.obj_list():
+ model = self.pool.get(model_name)
+ if 'mail.thread' in getattr(model, '_inherit', []):
+ ret_dict[model_name] = model._description
+ return ret_dict
+
def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None):
""" Find partners related to some header fields of the message. """
s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)])
- mails = tools.email_split(s)
- result = []
- for email in mails:
- result += self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)
- return result
+ return [partner_id for email in tools.email_split(s)
+ for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)]
def _message_find_user_id(self, cr, uid, message, context=None):
from_local_part = tools.email_split(decode(message.get('From')))[0]
@@ -387,9 +387,7 @@ class mail_thread(osv.Model):
for a given thread model, if the message did not belong to
an existing thread.
The default behavior is to create a new record of the corresponding
- model (based on some very basic info extracted from the message),
- then attach the message to the newly created record
- (by calling ``message_append_dict``).
+ model (based on some very basic info extracted from the message).
Additional behavior may be implemented by overriding this method.
:param dict msg_dict: a map containing the email details and
@@ -422,9 +420,8 @@ class mail_thread(osv.Model):
def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
"""Called by ``message_process`` when a new message is received
- for an existing thread. The default behavior is to create a
- new mail.message in the given thread (by calling
- ``message_append_dict``)
+ for an existing thread. The default behavior is to update the record
+ with update_vals taken from the incoming email.
Additional behavior may be implemented by overriding this
method.
:param dict msg_dict: a map containing the email details and
@@ -556,23 +553,23 @@ class mail_thread(osv.Model):
#------------------------------------------------------
def log(self, cr, uid, id, message, secondary=False, context=None):
- _logger.warning("log() is deprecated. As this module inherit from \
- mail.thread, the message will be managed by this \
- module instead of by the res.log mechanism. Please \
- use the mail.thread OpenChatter API instead of the \
- now deprecated res.log.")
+ _logger.warning("log() is deprecated. As this module inherit from "\
+ "mail.thread, the message will be managed by this "\
+ "module instead of by the res.log mechanism. Please "\
+ "use mail_thread.message_post() instead of the "\
+ "now deprecated res.log.")
self.message_post(cr, uid, [id], message, context=context)
def message_post(self, cr, uid, thread_id, body='', subject=False,
- msg_type='notification', parent_id=False, attachments=None, subtype='other', context=None, **kwargs):
- """ Post a new message in an existing message thread, returning the new
+ type='notification', parent_id=False, attachments=None, subtype='other', context=None, **kwargs):
+ """ Post a new message in an existing thread, returning the new
mail.message ID. Extra keyword arguments will be used as default
column values for the new mail.message record.
:param int thread_id: thread ID to post into, or list with one ID
:param str body: body of the message, usually raw HTML that will
be sanitized
:param str subject: optional subject
- :param str msg_type: mail_message.type
+ :param str type: mail_message.type
:param int parent_id: optional ID of parent message in this thread
:param tuple(str,str) attachments: list of attachment tuples in the form
``(name,content)``, where content is NOT base64 encoded
@@ -608,11 +605,11 @@ class mail_thread(osv.Model):
if self._name in [model.model for model in subtype_browse.model_ids]:
values['subtype_id']=subtype_browse.id
values.update( {
- 'model': thread_id and context.get('thread_model', self._name) or False,
+ 'model': context.get('thread_model', self._name) if thread_id else False,
'res_id': thread_id or False,
'body': body,
'subject': subject,
- 'type': msg_type,
+ 'type': type,
'parent_id': parent_id,
'attachment_ids': attachment_ids,
})
@@ -626,16 +623,14 @@ class mail_thread(osv.Model):
def message_subscribe_users(self, cr, uid, ids, user_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
provided, subscribe uid instead. """
- # isinstance: because using message_subscribe_users called in a view set the context as user_ids
- if not user_ids or isinstance(user_ids, dict): user_ids = [uid]
+ if not user_ids: user_ids = [uid]
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_subscribe(cr, uid, ids, partner_ids, context=context)
def message_subscribe(self, cr, uid, ids, partner_ids,subtype_ids = None, context=None):
""" Add partners to the records followers.
-
:param partner_ids: a list of partner_ids to subscribe
- :param return: new value of followers, for Chatter
+ :param return: new value of followers if read_back key in context
"""
self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
if not subtype_ids:
@@ -643,29 +638,27 @@ class mail_thread(osv.Model):
subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)])
if subtype_ids:
self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context)
-
- # TDE: temp, must check followers widget
+ if context and context.get('read_back'):
+ return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
return []
- # return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
+
def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
provided, unsubscribe uid instead. """
- # isinstance: because using message_subscribe_users called in a view set the context as user_ids
- if not user_ids or isinstance(user_ids, dict): user_ids = [uid]
+ if not user_ids: user_ids = [uid]
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
""" Remove partners from the records followers.
-
:param partner_ids: a list of partner_ids to unsubscribe
- :param return: new value of followers, for Chatter
+ :param return: new value of followers if read_back key in context
"""
self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
- # TDE: temp, must check followers widget
+ if context and context.get('read_back'):
+ return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
return []
- # return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
#------------------------------------------------------
# Thread state
diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml
index f6ef5bc2ee9..34efa05f812 100644
--- a/addons/mail/mail_thread_view.xml
+++ b/addons/mail/mail_thread_view.xml
@@ -3,7 +3,7 @@
-
@@ -11,8 +11,18 @@
-
-
+
+ My Feeds
+
+
+
+
+
+ My Posts
+
+
+
+
diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py
index ebaff2bdce7..1bc193051a1 100644
--- a/addons/mail/res_users.py
+++ b/addons/mail/res_users.py
@@ -96,6 +96,10 @@ class res_users(osv.Model):
alias_pool.unlink(cr, uid, alias_ids, context=context)
return res
+ def message_post(self, cr, uid, thread_id, **kwargs):
+ partner_id = self.pool.get('res.users').browse(cr, uid, thread_id)[0].partner_id.id
+ return self.pool.get('res.partner').message_post(cr, uid, partner_id, **kwargs)
+
class res_users_mail_group(osv.Model):
""" Update of res.users class
- if adding groups to an user, check mail.groups linked to this user
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index f33f1c6ed99..240627c9e6c 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -8,7 +8,7 @@
margin: 0;
}
-.openerp .oe_mail_recthread ul, .openerp .oe_mail_recthread li {
+.openerp .oe_chatter ul, .openerp .oe_chatter li {
list-style-type: none;
padding: 0;
margin: 0;
@@ -78,10 +78,6 @@
overflow: auto;
}
-.openerp div.oe_mail_recthread {
- /*overflow: auto;*/
-}
-
.openerp div.oe_mail_recthread_main {
float: left;
width: 560px;
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index 5eda999f874..a5a64a59a8b 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -17,9 +17,15 @@ openerp.mail = function(session) {
*/
session.web.FormView = session.web.FormView.extend({
- // #FIXME TODO: CHECK WITH NEW BRANCH
+ // TDE FIXME TODO: CHECK WITH NEW BRANCH
do_action: function(action, on_close) {
- if (action.res_model == 'mail.compose.message' && this.fields && this.fields.message_ids && this.fields.message_ids.view.get("actual_mode") != 'create') {
+ if (action.res_model == 'mail.compose.message' &&
+ this.fields && this.fields.message_ids &&
+ this.fields.message_ids.view.get("actual_mode") != 'create') {
+ // debug
+ console.groupCollapsed('FormView do_action on mail.compose.message');
+ console.log('message_ids field:', this.fields.message_ids);
+ console.groupEnd();
var record_thread = this.fields.message_ids;
var thread = record_thread.thread;
thread.instantiate_composition_form('comment', true, false, 0, action.context);
@@ -40,14 +46,11 @@ openerp.mail = function(session) {
* the various Chatter widgets.
*
* Some regular expressions not used anymore, kept because I want to
- * - (^|\s)@((\w|@|\.)*): @login@log.log, supports inner '@' for
- * logins that are emails
+ * - (^|\s)@((\w|@|\.)*): @login@log.log
* 1. '(void)'
* 2. login@log.log
* - (^|\s)\[(\w+).(\w+),(\d)\|*((\w|[@ .,])*)\]: [ir.attachment,3|My Label],
- * for internal links to model ir.attachment, id=3, and with
- * optional label 'My Label'. Note that having a '|Label' is not
- * mandatory, because the regex should still be correct.
+ * for internal links
* 1. '(void)'
* 2. 'ir'
* 3. 'attachment'
@@ -62,7 +65,7 @@ openerp.mail = function(session) {
return session_prefix + '/web/binary/image?session_id=' + session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
},
- /** checks if tue current user is the message author */
+ /** check if the current user is the message author */
is_author: function (widget, message_user_id) {
return (widget.session && widget.session.uid != 0 && widget.session.uid == message_user_id);
},
@@ -71,7 +74,6 @@ openerp.mail = function(session) {
* - :name - shortcut to an image
*/
do_replace_expressions: function (string) {
- var self = this;
var icon_list = ['al', 'pinky']
/* special shortcut: :name, try to find an icon if in list */
var regex_login = new RegExp(/(^|\s):((\w)*)/g);
@@ -93,8 +95,7 @@ openerp.mail = function(session) {
* ------------------------------------------------------------
*
* This widget handles the display of a form to compose a new message.
- * This form is an OpenERP form_view, build on a mail.compose.message
- * wizard.
+ * This form is a mail.compose.message form_view.
*/
mail.ComposeMessage = session.web.Widget.extend({
@@ -102,14 +103,10 @@ openerp.mail = function(session) {
/**
* @param {Object} parent parent
- * @param {Object} [options]
- * @param {Object} [options.context] context
- * @param {String} [context.res_model] res_model of document [REQUIRED]
- * @param {Number} [context.res_id] res_id of record [REQUIRED]
- * @param {String} [context.composition_mode] mail.compose.message.mode
- * (see composition wizard)
- * @param {Number} [context.msg_id] id of a message in case we are in
- * reply mode
+ * @param {Object} [options]
+ * @param {Object} [options.context] context passed to the
+ * mail.compose.message DataSetSearch. Please refer to this model
+ * for more details about fields and default values.
*/
init: function (parent, options) {
var self = this;
@@ -120,9 +117,9 @@ openerp.mail = function(session) {
this.options.form_xml_id = options.form_xml_id || 'email_compose_message_wizard_form_chatter';
this.options.form_view_id = options.form_view_id || false;
// debug
- console.groupCollapsed('New ComposeMessage: model', this.options.context.default_res_model, ', id', this.options.context.default_res_id);
- console.log('context:', this.options.context);
- console.groupEnd();
+ // console.groupCollapsed('New ComposeMessage: model', this.options.context.default_res_model, ', id', this.options.context.default_res_id);
+ // console.log('context:', this.options.context);
+ // console.groupEnd();
},
start: function () {
@@ -132,33 +129,22 @@ openerp.mail = function(session) {
this.$el.find('img.oe_mail_icon').attr('src', user_avatar);
this.$el.find('div.oe_mail_msg_content').empty();
// create a context for the dataset and default_get of the wizard
- var context = this._update_context({});
- console.log(context);
+ var context = _.extend({}, this.options.context);
this.ds_compose = new session.web.DataSetSearch(this, 'mail.compose.message', context);
// find the id of the view to display in the chatter form
- var data_ds = new session.web.DataSetSearch(this, 'ir.model.data');
- return data_ds.call('get_object_reference', ['mail', this.options.form_xml_id]).pipe(this.proxy('create_form_view'));
- },
-
- /** Update the context of the compose wizard */
- _update_context: function (dest_context) {
- // TDE TOCHECK: after posting, back to reply mode !
- _.extend(dest_context, this.options.context, {
- 'mail.compose.message.mode': this.options.context.composition_mode,
- });
- if (this.options.context.composition_mode == 'comment') {
- // _.extend(dest_context, {'default_res_id': this.options.res_id});
+ if (this.options.form_view_id) {
+ return this.create_form_view();
}
- else if (this.options.context.composition_mode == 'reply') {
- _.extend(dest_context, {'active_id': this.options.context.msg_id});
+ else {
+ var data_ds = new session.web.DataSetSearch(this, 'ir.model.data');
+ return data_ds.call('get_object_reference', ['mail', this.options.form_xml_id]).pipe(this.proxy('create_form_view'));
}
- return dest_context
},
/** Create a FormView, then append it to the to widget DOM. */
- create_form_view: function (form_view_id) {
- this.options.form_view_id = form_view_id[1] || false;
+ create_form_view: function (new_form_view_id) {
var self = this;
+ this.options.form_view_id = (new_form_view_id && new_form_view_id[1]) || this.options.form_view_id;
// destroy previous form_view if any
if (this.form_view) { this.form_view.destroy(); }
// create the FormView
@@ -177,14 +163,15 @@ openerp.mail = function(session) {
},
/**
- * Reinitialize the widget field values to the default values. The
- * purpose is to avoid to destroy and re-build a form view. Default
- * values are therefore given as for an on_change. */
- refresh: function (options_update_values) {
- var self = this;
- this.options.context = _.extend(this.options.context, options_update_values || {});
+ * Reinitialize the widget field values to the default values obtained
+ * using default_get on mail.compose.message. This allows to reinitialize
+ * the widget without having to rebuild a complete form view.
+ * @param {Object} new_context: context of the refresh */
+ refresh: function (new_context) {
if (! this.form_view) return;
- this.ds_compose.context = this._update_context(this.ds_compose.context);
+ var self = this;
+ this.options.context = _.extend(this.options.context, new_context || {});
+ this.ds_compose.context = _.extend(this.ds_compose.context, this.options.context);
return this.ds_compose.call('default_get', [
['subject', 'body_text', 'body', 'attachment_ids', 'partner_ids', 'composition_mode',
'model', 'res_id', 'parent_id', 'content_subtype'],
@@ -192,13 +179,6 @@ openerp.mail = function(session) {
]).then( function (result) { self.form_view.on_processed_onchange({'value': result}, []); });
},
- /**
- * Override-hack of do_action: clean the form */
- do_action: function(action, on_close) {
- console.log('compose_message do_action', action, on_close);
- return this._super(action, on_close);
- },
-
/**
* Bind events in the widget. Each event is slightly described
* in the function. */
@@ -223,9 +203,6 @@ openerp.mail = function(session) {
* - - sub message (parent_id = root message)
* - - - sub sub message (parent id = sub message)
* - - sub message (parent_id = root message)
- * This widget has 2 ways of initialization, either you give records
- * to be rendered, either it will fetch [limit] messages related to
- * [res_model]:[res_id].
*/
mail.Thread = session.web.Widget.extend({
@@ -234,71 +211,54 @@ openerp.mail = function(session) {
/**
* @param {Object} parent parent
* @param {Object} [options]
- * @param {String} [options.res_model] res_model of document [REQUIRED]
- * @param {Number} [options.res_id] res_id of record [REQUIRED]
- * @param {Number} [options.uid] user id [REQUIRED]
- * @param {Bool} [options.parent_id=false] parent_id of message
- * @param {Number} [options.thread_level=0] number of levels in the thread
- * (only 0 or 1 currently)
- * @param {Bool} [options.is_wall=false] thread is displayed in the wall
- * @param {Number} [options.msg_more_limit=150] number of character to
+ * @param {Object} [options.context] context of the thread. It should
+ contain at least default_model, default_res_id. Please refer to
+ the ComposeMessage widget for more information about it.
+ * @param {Number} [options.thread_level=0] number of thread levels
+ * @param {Number} [options.message_ids=null] ids for message_fetch
+ * @param {Number} [options.message_data=null] already formatted message
+ data, for subthreads getting data from their parent
+ * @param {Boolean} [options.composer] use the advanced composer, or
+ the default basic textarea if not set
+ * @param {Number} [options.truncate_limit=250] number of character to
* display before having a "show more" link; note that the text
* will not be truncated if it does not have 110% of the parameter
- * (ex: 110 characters needed to be truncated and be displayed as
- * a 100-characters message)
- * @param {Number} [options.limit=100] maximum number of messages to fetch
- * @param {Number} [options.offset=0] offset for fetching messages
- * @param {Number} [options.records=null] records to show instead of fetching messages
*/
init: function(parent, options) {
- console.log(parent);
this._super(parent);
// options
this.options = options || {};
this.options.domain = options.domain || [];
- this.options.context = options.context || {};
- // check in parents, should not define multiple times
- this.options.context.res_model = options.context.res_model || 'mail.thread';
- this.options.context.res_id = options.context.res_id || false;
- this.options.context.parent_id = options.context.parent_id || false;
+ this.options.context = _.extend({
+ default_model: 'mail.thread',
+ default_res_id: 0,
+ default_parent_id: false }, options.context || {});
this.options.thread_level = options.thread_level || 0;
this.options.composer = options.composer || false;
- // TDE: not sure, here for testing / compatibility
- this.options.records = options.records || null;
- this.options.ids = options.ids || null;
+ this.options.message_ids = options.message_ids || null;
+ this.options.message_data = options.message_data || null;
// datasets and internal vars
- this.ds_post = new session.web.DataSetSearch(this, this.options.context.res_model);
- this.ds_notif = new session.web.DataSetSearch(this, 'mail.notification');
- this.ds_msg = new session.web.DataSetSearch(this, 'mail.message');
+ this.ds_thread = new session.web.DataSetSearch(this, this.options.context.default_model);
+ this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification');
+ this.ds_message = new session.web.DataSetSearch(this, 'mail.message');
// display customization vars
- this.display = {};
- this.display.truncate_limit = options.truncate_limit || 250;
- this.display.show_header_compose = options.show_header_compose || false;
- this.display.show_reply = options.show_reply || false;
- this.display.show_delete = options.show_delete || false;
- this.display.show_hide = options.show_hide || false;
- this.display.show_reply_by_email = options.show_reply_by_email || false;
- this.display.show_more = options.show_more || false;
- // for search view
- this.search = {'domain': [], 'context': {}, 'groupby': {}}
- this.search_results = {'domain': [], 'context': {}, 'groupby': {}}
- // debug
- console.groupCollapsed('New Thread: model', this.options.context.res_model, 'id', this.options.context.res_id, 'parent_id', this.options.context.parent_id, 'thread level', this.options.thread_level);
- console.log('records:', this.options.records, 'ids:', this.options.ids);
- console.log('options:', this.options);
- console.log('display:', this.display);
- console.groupEnd();
+ this.display = {
+ truncate_limit: options.truncate_limit || 250,
+ show_header_compose: options.show_header_compose || false,
+ show_reply: options.show_reply || false,
+ show_delete: options.show_delete || false,
+ show_hide: options.show_hide || false,
+ show_reply_by_email: options.show_reply_by_email || false,
+ show_more: options.show_more || false,
+ }
},
start: function() {
+ // TDE TODO: check for deferred, not sure it is correct
this._super.apply(this, arguments);
this.bind_events();
- // display messages: either given by parent, either fetch new ones
- if (this.options.records) var display_done = this.message_display(this.options.records);
- else var display_done = this.message_fetch();
- // customize display
- this.display_user_avatar();
- $.when(display_done).then(this.proxy('do_customize_display'));
+ // fetch and display message, using message_ids if set
+ var display_done = $.when(this.message_fetch(true, [], {})).then(this.proxy('do_customize_display'));
// add message composition form view
if (this.display.show_header_compose && this.options.composer) {
var compose_done = this.instantiate_composition_form();
@@ -309,6 +269,7 @@ openerp.mail = function(session) {
/** Customize the display
* - show_header_compose: show the composition form in the header */
do_customize_display: function() {
+ this.display_user_avatar();
if (this.display.show_header_compose) { this.$el.find('div.oe_mail_thread_action').eq(0).show(); }
},
@@ -366,7 +327,10 @@ openerp.mail = function(session) {
event.stopPropagation();
var msg_id = event.srcElement.dataset.msg_id;
if (! msg_id) return false;
- self.compose_message_widget.refresh({'composition_mode': 'reply', 'msg_id': parseInt(msg_id)});
+ self.compose_message_widget.refresh({
+ 'default_composition_mode': 'reply',
+ 'default_parent_id': parseInt(msg_id),
+ 'default_content_subtype': 'html'} );
});
},
@@ -375,24 +339,26 @@ openerp.mail = function(session) {
* Normally it should be called only when clicking on 'Post/Send'
* in the composition form. */
do_action: function(action, on_close) {
- console.log('thread do_action', action, on_close, this);
this.message_clean();
this.message_fetch();
if (this.compose_message_widget) {
- this.compose_message_widget.refresh(); }
+ this.compose_message_widget.refresh({
+ 'default_composition_mode': 'comment',
+ 'default_parent_id': this.options.default_parent_id,
+ 'default_content_subtype': 'plain'} );
+ }
return this._super(action, on_close);
},
- /** Instantiate the composition form, with parameters coming from thread parameters */
- instantiate_composition_form: function(mode, formatting, msg_id, context) {
+ /** Instantiate the composition form, with every parameters in context
+ or in the widget context. */
+ instantiate_composition_form: function(context) {
if (this.compose_message_widget) {
this.compose_message_widget.destroy();
}
this.compose_message_widget = new mail.ComposeMessage(this, {
- 'context': {
- 'default_model': this.options.context.res_model, 'default_res_id': this.options.context.res_id,
- 'composition_mode': mode || 'comment', 'msg_id': msg_id }
- });
+ 'context': _.extend(context || {}, this.options.context),
+ });
var composition_node = this.$el.find('div.oe_mail_thread_action');
composition_node.empty();
var compose_done = this.compose_message_widget.appendTo(composition_node);
@@ -405,35 +371,33 @@ openerp.mail = function(session) {
},
/** Fetch messages
- * @param {Array} additional_domain
- * @param {Object} additional_context
+ * @param {Bool} initial_mode: initial mode: try to use message_data or
+ * message_ids, if nothing available perform a message_read; otherwise
+ * directly perform a message_read
+ * @param {Array} additional_domain: added to options.domain
+ * @param {Object} additional_context: added to options.context
*/
- message_fetch: function (additional_domain, additional_context) {
+ message_fetch: function (initial_mode, additional_domain, additional_context) {
var self = this;
- // Update the domain and context
- this.search['domain'] = _.union(this.options.domain, this.search_results.domain);
- this.search['context'] = _.extend(this.options.context, this.search_results.context);
- if (additional_domain) var fetch_domain = this.search['domain'].concat(additional_domain);
- else var fetch_domain = this.search['domain'];
- if (additional_context) var fetch_context = _.extend(this.search['context'], additional_context);
- else var fetch_context = this.search['context'];
-
- // TODO first use: use IDS, otherwise set false
-
- var read_defer = this.ds_msg.call('message_read',
- [false, fetch_domain, this.options.thread_level, undefined, fetch_context]
+ // domain and context: options + additional
+ fetch_domain = _.flatten([this.options.domain, additional_domain || []], true)
+ fetch_context = _.extend(this.options.context, additional_context || {})
+ // if message_ids is set: try to use it
+ if (initial_mode && this.options.message_data) {
+ return this.message_display(this.options.message_data);
+ }
+ return this.ds_message.call('message_read',
+ [(initial_mode && this.options.message_ids) || false, fetch_domain, this.options.thread_level, undefined, fetch_context]
).then(this.proxy('message_display'));
- return read_defer;
},
/* Display a list of records
- * - */
+ * A specific case is done for 'expandable' messages that are messages
+ displayed under a 'show more' button form
+ */
message_display: function (records) {
var self = this;
var _expendable = false;
- console.groupCollapsed('message_display');
- console.log('records', records)
- console.groupEnd();
_(records).each(function (record) {
if (record.type == 'expandable') {
_expendable = true;
@@ -443,14 +407,19 @@ openerp.mail = function(session) {
}
else {
self.display_record(record);
+ // if (self.options.thread_level >= 0) {
self.thread = new mail.Thread(self, {
- 'context': { 'res_model': record.model, 'res_id': record.res_id, 'parent_id': record.id},
+ 'context': {
+ 'default_model': record.model,
+ 'default_id': record.res_id,
+ 'default_parent_id': record.id },
+ 'message_data': record.child_ids, 'thread_level': self.options.thread_level-1,
'show_header_compose': false, 'show_reply': self.options.thread_level > 1,
'show_hide': self.display.show_hide, 'show_delete': self.display.show_delete,
- 'uid': self.options.uid, 'records': record.child_ids, 'thread_level': (self.options.thread_level-1),
});
self.$el.find('li.oe_mail_thread_msg:last').append('');
self.thread.appendTo(self.$el.find('div.oe_mail_thread_subthread:last'));
+ // }
}
});
if (! _expendable) {
@@ -522,7 +491,7 @@ openerp.mail = function(session) {
/** Action: 'shows more' to fetch new messages */
do_message_fetch: function () {
- return this.message_fetch(this.fetch_more_domain, this.fetch_more_context);
+ return this.message_fetch(false, this.fetch_more_domain, this.fetch_more_context);
},
// TDE: keep currently because need something similar
@@ -572,19 +541,18 @@ openerp.mail = function(session) {
/** mail_thread widget: thread of comments */
mail.RecordThread = session.web.form.AbstractField.extend({
- // QWeb template to use when rendering the object
template: 'mail.record_thread',
init: function() {
this._super.apply(this, arguments);
this.options.domain = this.options.domain || [];
- this.options.context = {'res_model': 'mail.thread', 'res_id': false, 'parent_id': false};
+ this.options.context = {'default_model': 'mail.thread', 'default_res_id': false};
this.options.thread_level = this.options.thread_level || 0;
this.thread_list = [];
},
start: function() {
- // this._super.apply(this, arguments);
+ this._super.apply(this, arguments);
// NB: all the widget should be modified to check the actual_mode property on view, not use
// any other method to know if the view is in create mode anymore
this.view.on("change:actual_mode", this, this._check_visibility);
@@ -608,14 +576,14 @@ openerp.mail = function(session) {
return;
}
// update context
- this.options.context['res_id'] = this.view.datarecord.id;
- this.options.context['res_model'] = this.view.model;
+ _.extend(this.options.context, {
+ default_res_id: this.view.datarecord.id,
+ default_model: this.view.model });
// create and render Thread widget
this.$el.find('div.oe_mail_recthread_main').empty();
for (var i in this.thread_list) { this.thread_list[i].destroy(); }
- console.log(this);
var thread = new mail.Thread(self, {
- 'context': this.options.context, 'uid': this.session.uid,
+ 'context': this.options.context,
'thread_level': this.options.thread_level, 'show_header_compose': true,
'show_delete': true, 'composer': true });
this.thread_list.push(thread);
@@ -644,7 +612,7 @@ openerp.mail = function(session) {
* @param {Object} [options]
* @param {Number} [options.domain] domain on the Wall, is an array.
* @param {Number} [options.domain] context, is an object. It should
- * contain res_model, res_id, parent_id, to give it to the threads.
+ * contain default_model, default_res_id, to give it to the threads.
*/
init: function (parent, options) {
this._super(parent);
@@ -653,7 +621,7 @@ openerp.mail = function(session) {
this.options.context = options.context || {};
this.options.thread_level = options.thread_level || 1;
this.thread_list = [];
- this.ds_msg = new session.web.DataSet(this, 'mail.message');
+ this.ds_msg = new session.web.DataSetSearch(this, 'mail.message');
// for search view
this.search = {'domain': [], 'context': {}, 'groupby': {}}
this.search_results = {'domain': [], 'context': {}, 'groupby': {}}
@@ -662,29 +630,15 @@ openerp.mail = function(session) {
start: function () {
this._super.apply(this, arguments);
var search_view_ready = this.load_search_view({}, false);
- var thread_displayed = this.display_thread();
+ var thread_displayed = this.message_display();
return (search_view_ready && thread_displayed);
},
destroy: function () {
- for (var i in this.thrad_list) { this.thread_list[i].destroy(); }
+ for (var i in this.thread_list) { this.thread_list[i].destroy(); }
this._super.apply(this, arguments);
},
- /**
- * Override-hack of do_action: automatically reload the chatter.
- * Normally it should be called only when clicking on 'Post/Send'
- * in the composition form. */
- //TDE: still useful ? TO CHECK
- do_action: function(action, on_close) {
- console.log('wall do_action');
- if (this.compose_message_widget) {
- this.compose_message_widget.refresh(); }
- this.message_clean();
- this.display_thread();
- return this._super(action, on_close);
- },
-
/**
* Load the mail.message search view
* @param {Object} defaults ??
@@ -717,7 +671,7 @@ openerp.mail = function(session) {
self.search_results['domain'] = results.domain;
self.search_results['groupby'] = results.group_by;
self.message_clean();
- return self.display_thread();
+ return self.message_display();
});
},
@@ -726,14 +680,12 @@ openerp.mail = function(session) {
this.$el.find('ul.oe_mail_wall_threads').empty();
},
- /** Display comments
- * @param {Array} records tree structure of records
- */
- display_thread: function () {
+ /** Display the Wall threads */
+ message_display: function () {
var render_res = session.web.qweb.render('mail.wall_thread_container', {});
$('
').html(render_res).appendTo(this.$el.find('ul.oe_mail_wall_threads'));
var thread = new mail.Thread(this, {
- 'domain': this.options.domain, 'context': this.options.context, 'uid': this.session.uid,
+ 'domain': this.options.domain, 'context': this.options.context,
'thread_level': this.options.thread_level, 'composer': true,
// display options
'show_header_compose': true, 'show_reply': this.options.thread_level > 0,
diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js
index fc9223b3657..5d7b2ec5116 100644
--- a/addons/mail/static/src/js/mail_followers.js
+++ b/addons/mail/static/src/js/mail_followers.js
@@ -9,7 +9,7 @@ openerp_mail_followers = function(session, mail) {
* mail_followers Widget
* ------------------------------------------------------------
*
- * This widget handles the display of a list of records as a vetical
+ * This widget handles the display of a list of records as a vertical
* list, with an image on the left. The widget itself is a floatting
* right-sided box.
* This widget is mainly used to display the followers of records
@@ -71,25 +71,17 @@ openerp_mail_followers = function(session, mail) {
this.$el.find('div.oe_mail_recthread_aside').hide();
return;
}
- if (this.getParent().fields.message_is_follower === undefined) {
- // TDE: TMP, need to change all form views
- this.message_is_follower = false;
- }
- else {
- this.message_is_follower = this.getParent().fields.message_is_follower.get_value();
- }
return this.fetch_followers(value_);
},
fetch_followers: function (value_) {
- return this.ds_follow.call('read', [value_ || this.get_value(), ['name']]).then(this.proxy('display_followers'));
+ return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers'));
},
- /**
- * Display the followers.
- * TODO: replace the is_follower check by fields read */
+ /** Display the followers, evaluate is_follower directly */
display_followers: function (records) {
var self = this;
+ this.message_is_follower = _.indexOf(_.flatten(_.pluck(records, 'user_ids')), this.session.uid) != -1;
var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty();
this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')');
_(records).each(function (record) {
@@ -137,7 +129,8 @@ openerp_mail_followers = function(session, mail) {
},
do_follow: function () {
- return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id]]).pipe(this.proxy('set_value'));
+ var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
+ return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
},
//fetch subtype from subtype model
@@ -150,7 +143,8 @@ openerp_mail_followers = function(session, mail) {
},
do_unfollow: function () {
- return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id]]).pipe(this.proxy('set_value'));
+ var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
+ return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
},
});
};
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index 06a1ce48605..e31a23ae517 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -47,7 +47,7 @@
Template used to display the communication history in documents
form view.
-->
-
\n'
+ _mail_bodyalt2 = 'Pigs rules\nAdmin\n'
+ filter_subtype_id = self.mail_message_subtype.search(cr, uid, [('default','=',True)])
+ # Post comment with body and subject, comment preference
+ msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype='email')
+ notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)])
+ self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall")
+ # New post: test automatic subject, signature in html, add a partner, email preference, parent_id previous message
+ msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other')
+ notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)])
+ self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall")
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index d141b3cf1e0..3c93440642d 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -35,8 +35,7 @@ class mail_compose_message(osv.TransientModel):
""" Generic message composition wizard. You may inherit from this wizard
at model and view levels to provide specific features.
- The behavior of the wizard can be modified through the context key
- mail.compose.message.mode:
+ The behavior of the wizard depends on the composition_mode field:
- 'reply': reply to a previous message. The wizard is pre-populated
via ``get_message_data``.
- 'comment': new post on a record. The wizard is pre-populated via
@@ -56,10 +55,11 @@ class mail_compose_message(osv.TransientModel):
- default_model or active_model
- default_res_id or active_id
- reply: active_id of a message the user replies to
- - active_id: ID of a mail.message to which we are replying
+ - default_parent_id or message_id or active_id: ID of the
+ mail.message we reply to
- message.res_model or default_model
- message.res_id or default_res_id
- - mass_mailing mode: model and IDs of records the user mass-mails
+ - mass_mail: model and IDs of records the user mass-mails
- active_ids: record IDs
- default_model or active_model
"""
@@ -81,7 +81,7 @@ class mail_compose_message(osv.TransientModel):
elif composition_mode == 'comment' and model and res_id:
vals = self.get_record_data(cr, uid, model, res_id, context=context)
elif composition_mode == 'mass_mail' and model and active_ids:
- vals = {'model': model, 'res_id': res_id, 'content_subtype': 'html'}
+ vals = {'model': model, 'res_id': res_id}
else:
vals = {'model': model, 'res_id': res_id}
if composition_mode:
@@ -106,7 +106,7 @@ class mail_compose_message(osv.TransientModel):
'mail_compose_message_ir_attachments_rel',
'wizard_id', 'attachment_id', 'Attachments'),
'filter_id': fields.many2one('ir.filters', 'Filters'),
- 'body_text': fields.text('Plain-text editor body'),
+ 'body_text': fields.text('Plain-text Contents'),
'content_subtype': fields.char('Message content subtype', size=32, readonly=1,
help="Type of message, usually 'html' or 'plain', used to select "\
"plain-text or rich-text contents accordingly"),
@@ -118,7 +118,6 @@ class mail_compose_message(osv.TransientModel):
'body_text': lambda self,cr, uid, context={}: False,
'body': lambda self,cr, uid, context={}: '',
'subject': lambda self,cr, uid, context={}: False,
- 'partner_ids': [],
}
def notify(self, cr, uid, newid, context=None):
@@ -270,7 +269,7 @@ class mail_compose_message(osv.TransientModel):
post_values['attachments'] += new_attachments
post_values.update(email_dict)
# post the message
- active_model_pool.message_post(cr, uid, [res_id], msg_type='comment', context=context, **post_values)
+ active_model_pool.message_post(cr, uid, [res_id], type='comment', context=context, **post_values)
return {'type': 'ir.actions.act_window_close'}
diff --git a/addons/mail/wizard/mail_compose_message_view.xml b/addons/mail/wizard/mail_compose_message_view.xml
index 4ce5db3f4e3..70b50c154ac 100644
--- a/addons/mail/wizard/mail_compose_message_view.xml
+++ b/addons/mail/wizard/mail_compose_message_view.xml
@@ -6,34 +6,43 @@
mail.compose.message
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
+
-
+
+
- mail.compose.message.form
+ mail.compose.message.form.chattermail.compose.message18
diff --git a/addons/marketing_campaign/marketing_campaign_demo.xml b/addons/marketing_campaign/marketing_campaign_demo.xml
index 19e44eb4ace..92443fe987d 100644
--- a/addons/marketing_campaign/marketing_campaign_demo.xml
+++ b/addons/marketing_campaign/marketing_campaign_demo.xml
@@ -3,29 +3,29 @@
- Template for New Partner
+ welcome new partnerinfo@openerp.com
- Welcome in OpenERP Partner Channel!
+ Welcome to the OpenERP Partner Channel!${object.email or ''}
- Hello, We are very happy to send Welcome message.
+ Hello, you will receive your welcome pack via email shortly.
- Template for Silver Partner
+ congrats silver partnerinfo@openerp.com
- Congratulation! You become now our Silver Partner.
+ Congratulations! You are now a Silver Partner!${object.email or ''}
- Hello, We are happy to announce that you now become our Silver Partner.
+ Hi, we are delighted to welcome you among our Silver Partners as of today!
- Template for Gold Partner
+ congrats gold partnerinfo@openerp.com
- Congratulation! You become our Gold Partner.
+ Congratulations! You are now one of our Gold Partners!${object.email or ''}
- Hello, We are happy to announce that you become our Gold Partner.
+ Hi, we are delighted to let you know that you have entered the select circle of our Gold Partners
@@ -64,7 +64,7 @@
-
+
diff --git a/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml b/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml
index 6545dd93cb2..141981a21d6 100644
--- a/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml
+++ b/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml
@@ -40,7 +40,10 @@
- Hello,Thanks for generous interest you have shown in the openERP.Regards,OpenERP Team,
+ Hello,
+
Thanks for the genuine interest you have shown in OpenERP.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>For OpenERP OnDemand Free Trial 2010
@@ -50,11 +53,11 @@
- Hello,We have very good offer that might suit you.
- We propose you to subscribe to the OpenERP Discovery Day on May 2010.
- If any further information required kindly revert back.
- We really appreciate your co-operation on this.
- Regards,OpenERP Team,
+ Hello,
+
We have very good offer that might suit you.
+ We suggest you subscribe to the OpenERP Discovery Day on May 2010.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>For OpenERP Discovery Day on May 2010
@@ -65,10 +68,10 @@
- Hello,Thanks for showing intrest and for subscribing to the OpenERP Discovery Day.
- If any further information required kindly revert back.
- I really appreciate your co-operation on this.
- Regards,OpenERP Team,
+ Hello,
+
Thanks for showing interest and for subscribing to the OpenERP Discovery Day.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>For OpenERP Discovery Day
@@ -79,10 +82,10 @@
- Hello,Thanks for showing intrest and buying the OpenERP book.
+ Hello,
+
Thanks for showing interest and buying the OpenERP book.
If any further information required kindly revert back.
- I really appreciate your co-operation on this.
- Regards,OpenERP Team,
+
Regards,OpenERP Team,
]]>For OpenERP book
@@ -92,12 +95,12 @@
- Hello, We have very good offer that might suit you.
- For our gold partners,We are arranging free technical training on june,2010.
- If any further information required kindly revert back.
- I really appreciate your co-operation on this.
- Regards,OpenERP Team,
- For technical training to Gold partners
+ Hello,
+
We have very good offer that might suit you.
+ For our gold partners,We are arranging free technical training on june,2010.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>
+ technical training to gold partners
@@ -107,12 +110,12 @@
- Hello, We have very good offer that might suit you.
- For our silver partners,We are paid technical training on june,2010.
- If any further information required kindly revert back.
- I really appreciate your co-operation on this.
- Regards,OpenERP Team,
- For training to Silver partners
+ Hello,
+
We have very good offer that might suit you.
+ For our silver partners,We are paid technical training on june,2010.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>
+ training to silver partners
@@ -122,12 +125,12 @@
- Hello, We have very good offer that might suit you.
- For our silver partners,We are offering Gold partnership.
- If any further information required kindly revert back.
- I really appreciate your co-operation on this.
- Regards,OpenERP Team,
- For gold partnership to silver partners
+ Hello,
+
We have very good offer that might suit you.
+ For our silver partners, we are offering Gold partnership.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>
+ gold partnership to silver partners
@@ -137,9 +140,12 @@
- Hello, Thanks for showing intrest and for subscribing to technical training.If any further information required kindly revert back.I really appreciate your co-operation on this.
- Regards,OpenERP Team,
- For subscribing to technical training
+ Hello,
+
Thanks for showing interest and for subscribing to technical training.
+ If any further information required kindly revert back.I really appreciate your co-operation on this.
+
If any further information is required, do not hesitate to reply to this message.
+
Regards,OpenERP Team,
]]>
+ subscribing to technical training
diff --git a/addons/membership/__openerp__.py b/addons/membership/__openerp__.py
index e4b596183af..316a2f0f120 100644
--- a/addons/membership/__openerp__.py
+++ b/addons/membership/__openerp__.py
@@ -46,7 +46,6 @@ invoice and send propositions for membership renewal.
'membership_view.xml',
'report/report_membership_view.xml',
'process/membership_process.xml',
- 'membership_data.xml'
],
'demo': ['membership_demo.xml'],
'test': ['test/test_membership.yml'],
diff --git a/addons/membership/membership.py b/addons/membership/membership.py
index 3439f97f833..2a006814629 100644
--- a/addons/membership/membership.py
+++ b/addons/membership/membership.py
@@ -146,7 +146,7 @@ class membership_line(osv.osv):
'date_to': fields.date('To', readonly=True),
'date_cancel': fields.date('Cancel date'),
'date': fields.date('Join Date', help="Date on which member has joined the membership"),
- 'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Product Price'), required=True, help='Amount for the membership'),
+ 'member_price': fields.float('Membership Fee', digits_compute= dp.get_precision('Product Price'), required=True, help='Amount for the membership'),
'account_invoice_line': fields.many2one('account.invoice.line', 'Account Invoice line', readonly=True),
'account_invoice_id': fields.related('account_invoice_line', 'invoice_id', type='many2one', relation='account.invoice', string='Invoice', readonly=True),
'state': fields.function(_state,
@@ -444,14 +444,6 @@ class Partner(osv.osv):
Partner()
-class product_template(osv.osv):
- _inherit = 'product.template'
- _columns = {
- 'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Product Price')),
- }
-
-product_template()
-
class Product(osv.osv):
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
diff --git a/addons/membership/membership_data.xml b/addons/membership/membership_data.xml
deleted file mode 100644
index 14fbb00f9a2..00000000000
--- a/addons/membership/membership_data.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
- Member Price
- member_price
-
-
-
-
- Member Sale Pricelist
- sale
-
-
-
- Member Sale Pricelist Version
-
-
-
-
- Member Sale Pricelist Line
-
-
-
-
diff --git a/addons/membership/membership_view.xml b/addons/membership/membership_view.xml
index fb128585fd2..ce0e55e37c9 100644
--- a/addons/membership/membership_view.xml
+++ b/addons/membership/membership_view.xml
@@ -88,11 +88,11 @@
-
+
-
+
@@ -270,17 +270,5 @@
-
-
- product.normal.form
- product.product
-
-
-
-
-
-
-
-
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index d57eba2ceb5..8121f6e84d1 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -501,7 +501,7 @@
mrp.bomform
- [('bom_id','!=',False)]
+ []
Click to add a component to a bill of material.
@@ -524,6 +524,7 @@
action="mrp_bom_form_action2"
id="menu_mrp_bom_form_action2"
parent="menu_mrp_configuration"
+ groups="base.group_no_one"
sequence="20"/>
@@ -647,50 +648,42 @@
-
-
+ Fill is this for to launch a procurement request for this
+ product. According to the product configuration, this may
+ trigger a draft purchase order, a manufacturing order or
+ a new task.
+
+
+
+
+
+
+
+
+
-
+
+ Procurement Request
+ make.procurement
+ product.product
+ form
+ new
+
diff --git a/addons/product/product.py b/addons/product/product.py
index 7d26b47519d..16b08e67cee 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -288,13 +288,13 @@ class product_template(osv.osv):
'rental': fields.boolean('Can be Rent'),
'categ_id': fields.many2one('product.category','Category', required=True, change_default=True, domain="[('type','=','normal')]" ,help="Select category for the current product"),
'list_price': fields.float('Sale Price', digits_compute=dp.get_precision('Product Price'), help="Base price for computing the customer price. Sometimes called the catalog price."),
- 'standard_price': fields.float('Cost Price', required=True, digits_compute=dp.get_precision('Product Price'), help="Product's cost for accounting stock valuation. It is the base price for the supplier price.", groups="base.group_user"),
+ 'standard_price': fields.float('Cost', digits_compute=dp.get_precision('Product Price'), help="Product's cost for accounting stock valuation. It is the base price for the supplier price.", groups="base.group_user"),
'volume': fields.float('Volume', help="The volume in m3."),
'weight': fields.float('Gross Weight', digits_compute=dp.get_precision('Stock Weight'), help="The gross weight in Kg."),
'weight_net': fields.float('Net Weight', digits_compute=dp.get_precision('Stock Weight'), help="The net weight in Kg."),
'cost_method': fields.selection([('standard','Standard Price'), ('average','Average Price')], 'Costing Method', required=True,
help="Standard Price: the cost price is fixed and recomputed periodically (usually at the end of the year), Average Price: the cost price is recomputed at each reception of products."),
- 'warranty': fields.float('Warranty (months)'),
+ 'warranty': fields.float('Warranty'),
'sale_ok': fields.boolean('Can be Sold', help="Determines if the product can be visible in the list of product within a selection from a sale order line."),
'purchase_ok': fields.boolean('Can be Purchased', help="Determine if the product is visible in the list of products within a selection from a purchase order line."),
'state': fields.selection([('',''),
@@ -302,7 +302,7 @@ class product_template(osv.osv):
('sellable','Normal'),
('end','End of Lifecycle'),
('obsolete','Obsolete')], 'Status', help="Tells the user if he can use the product or not."),
- 'uom_id': fields.many2one('product.uom', 'Default Unit of Measure', required=True, help="Default Unit of Measure used for all stock operation."),
+ 'uom_id': fields.many2one('product.uom', 'Unit of Measure', required=True, help="Default Unit of Measure used for all stock operation."),
'uom_po_id': fields.many2one('product.uom', 'Purchase Unit of Measure', required=True, help="Default Unit of Measure used for purchase orders. It must be in the same category than the default unit of measure."),
'uos_id' : fields.many2one('product.uom', 'Unit of Sale',
help='Used by companies that manage two units of measure: invoicing and inventory management. For example, in food industries, you will manage a stock of ham but invoice in Kg. Keep empty to use the default Unit of Measure.'),
@@ -354,7 +354,7 @@ class product_template(osv.osv):
'list_price': lambda *a: 1,
'cost_method': lambda *a: 'standard',
'supply_method': lambda *a: 'buy',
- 'standard_price': lambda *a: 1,
+ 'standard_price': lambda *a: 0.0,
'sale_ok': lambda *a: 1,
'sale_delay': lambda *a: 7,
'produce_delay': lambda *a: 1,
@@ -535,9 +535,9 @@ class product_product(osv.osv):
'outgoing_qty': fields.function(_product_outgoing_qty, type='float', string='Outgoing'),
'price': fields.function(_product_price, type='float', string='Pricelist', digits_compute=dp.get_precision('Product Price')),
'lst_price' : fields.function(_product_lst_price, type='float', string='Public Price', digits_compute=dp.get_precision('Product Price')),
- 'code': fields.function(_product_code, type='char', string='Reference'),
+ 'code': fields.function(_product_code, type='char', string='Internal Reference'),
'partner_ref' : fields.function(_product_partner_ref, type='char', string='Customer ref'),
- 'default_code' : fields.char('Reference', size=64, select=True),
+ 'default_code' : fields.char('Internal Reference', size=64, select=True),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the product without removing it."),
'variants': fields.char('Variants', size=64),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade"),
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index d341b5883d6..ae769528d3c 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -12,8 +12,6 @@
-
-
@@ -71,6 +69,12 @@