\n"
+" The check payment form allows you to track the payment you "
+"do\n"
+" to your suppliers using checks. When you select a supplier, "
+"the\n"
+" payment method and an amount for the payment, OpenERP will\n"
+" propose to reconcile your payment with the open supplier\n"
+" invoices or bills.\n"
+"
\n"
+" "
+msgstr ""
+"
\n"
+" Kliknite da kreirate nove čekove. \n"
+"
\n"
+" Forma plaćanje čekom omogućava vam da pratite plaćanja koja "
+"izvršavate\n"
+" vašim dobavljačima koristeći čekove. Kada odaberete "
+"dobavljača,\n"
+" metodu plaćanja i iznos za plaćanje, OpenERP će predložiti "
+"da izravna\n"
+" vašu uplatu sa otvorenom fakturom ili računom dobavljača.\n"
+"
\n"
+" "
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Due Date"
+msgstr "Datum dospijeća"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
+msgid "Print Check (Middle)"
+msgstr "Štampaj ček (srednji)"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_res_company
+msgid "Companies"
+msgstr "Kompanije"
+
+#. module: account_check_writing
+#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
+#, python-format
+msgid "Error!"
+msgstr "Greška!"
+
+#. module: account_check_writing
+#: help:account.check.write,check_number:0
+msgid "The number of the next check number to be printed."
+msgstr "Broj sljedećeg čeka za štampanje."
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+msgid "Balance Due"
+msgstr "Saldo valute"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
+msgid "Print Check (Top)"
+msgstr "Štampaj ček (na vrhu)"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Check Amount"
+msgstr "Iznos čeka"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_voucher
+msgid "Accounting Voucher"
+msgstr "Računovodstveni vaučer"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "or"
+msgstr "ili"
+
+#. module: account_check_writing
+#: field:account.voucher,amount_in_word:0
+msgid "Amount in Word"
+msgstr "Pisani iznos"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_check_write
+msgid "Prin Check in Batch"
+msgstr "Štampaj čekove grupno"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "Cancel"
+msgstr "Otkaži"
+
+#. module: account_check_writing
+#: field:account.check.write,check_number:0
+msgid "Next Check Number"
+msgstr "Sljedeći broj čeka"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "Check"
+msgstr "Ček"
diff --git a/addons/base_status/i18n/bs.po b/addons/base_status/i18n/bs.po
new file mode 100644
index 00000000000..0fdd8821dd2
--- /dev/null
+++ b/addons/base_status/i18n/bs.po
@@ -0,0 +1,80 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-08-08 22:20+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Bosnian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-09 05:06+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid "Error !"
+msgstr "Greška !"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:166
+#, python-format
+msgid "%s has been opened."
+msgstr "%s je bio otvoren."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:199
+#, python-format
+msgid "%s has been renewed."
+msgstr "%s je bio obnovljen."
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid "Error!"
+msgstr "Greška!"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid ""
+"You can not escalate, you are already at the top level regarding your sales-"
+"team category."
+msgstr ""
+"Ne možete eskalirati, već ste na najvišem nivou u odnosu na kategoriju "
+"prodajnog tima."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:193
+#, python-format
+msgid "%s is now pending."
+msgstr "%s je sad Na čekanju."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:187
+#, python-format
+msgid "%s has been canceled."
+msgstr "%s je bio otkazan."
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid ""
+"You are already at the top level of your sales-team category.\n"
+"Therefore you cannot escalate furthermore."
+msgstr ""
+"Već ste na najvišem nivou vaše kategorije prodajnog tima.\n"
+"Zato ne možete dalje eskalirati."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:181
+#, python-format
+msgid "%s has been closed."
+msgstr "%s je bio zatvoren."
diff --git a/addons/crm/crm_action_rule_demo.xml b/addons/crm/crm_action_rule_demo.xml
index 7204f666db5..569b2d676e0 100644
--- a/addons/crm/crm_action_rule_demo.xml
+++ b/addons/crm/crm_action_rule_demo.xml
@@ -14,13 +14,7 @@
Trueir.actions.serveremail
- object.user_id.email
- Reminder on Lead: [[object.id ]] [[object.partner_id and 'of ' +object.partner_id.name or '']]
- Warning unprocessed incoming lead is more than 5 day old.
-Name: [[object.name ]]
-ID: [[object.id ]]
-Description: [[object.description]]
-
+ Set Auto Reminder on leads which are not open since 5 days.
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 46a3f6e199e..c0f003f9792 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -945,42 +945,6 @@ class crm_lead(format_address, osv.osv):
vals.update(onchange_stage_values)
return super(crm_lead, self).write(cr, uid, ids, vals, context=context)
- def new_mail_send(self, cr, uid, ids, context=None):
- '''
- This function opens a window to compose an email, with the edi sale template message loaded by default
- '''
- assert len(ids) == 1, 'This option should only be used for a single id at a time.'
- ir_model_data = self.pool.get('ir.model.data')
- try:
- template_id = ir_model_data.get_object_reference(cr, uid, 'crm', 'email_template_opportunity_mail')[1]
- except ValueError:
- template_id = False
- try:
- compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1]
- except ValueError:
- compose_form_id = False
- if context is None:
- context = {}
- ctx = context.copy()
- ctx.update({
- 'default_model': 'crm.lead',
- 'default_res_id': ids[0],
- 'default_use_template': bool(template_id),
- 'default_template_id': template_id,
- 'default_composition_mode': 'comment',
- })
- return {
- 'name': _('Compose Email'),
- 'type': 'ir.actions.act_window',
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'mail.compose.message',
- 'views': [(compose_form_id, 'form')],
- 'view_id': compose_form_id,
- 'target': 'new',
- 'context': ctx,
- }
-
# ----------------------------------------
# Mail Gateway
# ----------------------------------------
diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml
index 92914542d9d..219ff2cdeee 100644
--- a/addons/crm/crm_lead_data.xml
+++ b/addons/crm/crm_lead_data.xml
@@ -220,6 +220,20 @@
${not object.partner_id and object.email_from}
+
+ Reminder to User
+
+
+ admin@example.com
+ ${object.user_id != False and object.user_id.email}
+ Reminder on Lead: ${object.id} from ${object.partner_id != False and object.partner_id.name or object.contact_name}
+ This opportunity did not have any activity since at least 5 days. Here are some details:
+
+
Name: ${object.name}
+
ID: ${object.id}
+
Description: ${object.description}
+
]]>
+
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index cb4302166a1..aa5aac76b9d 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -408,7 +408,7 @@
diff --git a/addons/crm/i18n/hu.po b/addons/crm/i18n/hu.po
index 0289fac77cf..791273361eb 100644
--- a/addons/crm/i18n/hu.po
+++ b/addons/crm/i18n/hu.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-07-09 07:36+0000\n"
+"PO-Revision-Date: 2013-07-25 13:52+0000\n"
"Last-Translator: krnkris \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-07-10 05:25+0000\n"
-"X-Generator: Launchpad (build 16696)\n"
+"X-Launchpad-Export-Date: 2013-07-26 05:14+0000\n"
+"X-Generator: Launchpad (build 16700)\n"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead3
@@ -241,7 +241,7 @@ msgstr "Kilép"
#: view:crm.lead:0
#: field:crm.lead,state_id:0
msgid "State"
-msgstr "Állapot"
+msgstr "Állam/Megye"
#. module: crm
#: field:res.partner,meeting_count:0
diff --git a/addons/crm/i18n/zh_CN.po b/addons/crm/i18n/zh_CN.po
index 9064502ba33..aaac89319a8 100644
--- a/addons/crm/i18n/zh_CN.po
+++ b/addons/crm/i18n/zh_CN.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-07-23 03:21+0000\n"
+"PO-Revision-Date: 2013-08-06 09:41+0000\n"
"Last-Translator: fanvil \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-07-24 05:31+0000\n"
-"X-Generator: Launchpad (build 16700)\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
#. module: crm
#: view:crm.lead.report:0
@@ -185,7 +185,7 @@ msgstr "预计结束月份"
msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
-msgstr "保留复杂的摘要(消息数量,……等)。为了插入到看板视图,这一摘要直接是是HTML格式。"
+msgstr "保留复杂的摘要(消息数量,……等)。这一摘要直接是是HTML格式,以便插入到看板视图。"
#. module: crm
#: code:addons/crm/crm_lead.py:640
@@ -583,6 +583,7 @@ msgid ""
" If the call needs to be done then the status is set "
"to 'Not Held'."
msgstr ""
+"当一个案子新建时,状态被设为‘待处理’,当案子进行中,状态被设为‘打开’,当电话结束,状态被设为‘挂起’。如果需要电话,状态设为‘未挂起’"
#. module: crm
#: field:crm.case.section,message_summary:0
@@ -843,7 +844,7 @@ msgstr "参考2"
msgid ""
"Link between stages and sales teams. When set, this limitate the current "
"stage to the selected sales teams."
-msgstr ""
+msgstr "在阶段和销售团队之间建立链接。设置后将限制此阶段只能用于被选中的销售团队。"
#. module: crm
#: view:crm.case.stage:0
@@ -979,7 +980,7 @@ msgstr "下一动作"
#: code:addons/crm/crm_lead.py:780
#, python-format
msgid "Partner set to %s."
-msgstr ""
+msgstr "业务伙伴 设给 %s."
#. module: crm
#: selection:crm.lead.report,state:0
@@ -1338,7 +1339,7 @@ msgstr "发送邮件的时候,默认的邮件地址来自销售团队。"
msgid ""
"Phone Calls Assigned to the current user or with a team having the current "
"user as team leader"
-msgstr ""
+msgstr "被分配给当前用户或者当前用户领导的销售团队的电话沟通任务。"
#. module: crm
#: view:crm.segmentation:0
@@ -2884,7 +2885,7 @@ msgstr "发现日期"
#. module: crm
#: view:crm.lead:0
msgid "at"
-msgstr ""
+msgstr "在"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead1
diff --git a/addons/email_template/__init__.py b/addons/email_template/__init__.py
index d1cf5b28431..3f091fd8645 100644
--- a/addons/email_template/__init__.py
+++ b/addons/email_template/__init__.py
@@ -22,5 +22,6 @@
import email_template
import wizard
import res_partner
+import ir_actions
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/email_template/__openerp__.py b/addons/email_template/__openerp__.py
index 1dc3baaf63c..b7977660134 100644
--- a/addons/email_template/__openerp__.py
+++ b/addons/email_template/__openerp__.py
@@ -59,6 +59,7 @@ campaigns on any OpenERP document.
'wizard/email_template_preview_view.xml',
'email_template_view.xml',
'res_partner_view.xml',
+ 'ir_actions_view.xml',
'wizard/mail_compose_message_view.xml',
'security/ir.model.access.csv'
],
diff --git a/addons/email_template/doc/changelog.rst b/addons/email_template/doc/changelog.rst
new file mode 100644
index 00000000000..77e342c920a
--- /dev/null
+++ b/addons/email_template/doc/changelog.rst
@@ -0,0 +1,12 @@
+.. _changelog:
+
+Changelog
+=========
+
+`trunk (saas-2)`
+----------------
+
+ - ``mail.compose.message``: added support of ``mail_server_id`` from template
+ - Server action update
+
+ - added `email` server action type, now entirely based on email templates.
\ No newline at end of file
diff --git a/addons/email_template/doc/index.rst b/addons/email_template/doc/index.rst
new file mode 100644
index 00000000000..58cf9413601
--- /dev/null
+++ b/addons/email_template/doc/index.rst
@@ -0,0 +1,13 @@
+Email Template module documentation
+===================================
+
+Email Template documentation topics
+'''''''''''''''''''''''''''''''''''
+
+Changelog
+'''''''''
+
+.. toctree::
+ :maxdepth: 1
+
+ changelog.rst
diff --git a/addons/email_template/ir_actions.py b/addons/email_template/ir_actions.py
new file mode 100644
index 00000000000..bd860785da4
--- /dev/null
+++ b/addons/email_template/ir_actions.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013 OpenERP S.A.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv import fields, osv
+
+
+class actions_server(osv.Model):
+ """ Add email option in server actions. """
+ _name = 'ir.actions.server'
+ _inherit = ['ir.actions.server']
+
+ def _get_states(self, cr, uid, context=None):
+ res = super(actions_server, self)._get_states(cr, uid, context=context)
+ res.insert(0, ('email', 'Send Email'))
+ return res
+
+ _columns = {
+ 'email_from': fields.char('From',
+ help="Sender address; define the template to see its value. If not set, the default "
+ "value will be the author's email alias if configured, or email address."),
+ 'email_to': fields.char('To (Emails)',
+ help="Comma-separated recipient addresses; define the template to see its value"),
+ 'partner_to': fields.char('To (Partners)',
+ help="Comma-separated ids of recipient partners; define the template to see its value"),
+ 'subject': fields.char('Subject',
+ help="Email subject; define the template to see its value"),
+ 'body_html': fields.text('Body',
+ help="Rich-text/HTML version of the message; define the template to see its value"),
+ 'template_id': fields.many2one('email.template', 'Email Template', ondelete='set null',
+ help="Define the email template to use for the email to send.")
+ }
+
+ def on_change_template_id(self, cr, uid, ids, template_id, context=None):
+ """ Render the raw template in the server action fields. """
+ if template_id:
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
+ template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
+ values = dict((field, template_values[field]) for field in fields if template_values.get(field))
+ if not values.get('email_from'):
+ return {'warning': {'title': 'Incomplete template', 'message': 'Your template should define email_from'}, 'value': values}
+ else:
+ values = self.default_get(cr, uid, ['subject', 'body_html', 'email_from', 'email_to', 'partner_to'], context=context)
+
+ return {'value': values}
+
+ def create(self, cr, uid, values, context=None):
+ if values.get('template_id'):
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
+ template_values = self.pool.get('email.template').read(cr, uid, values.get('template_id'), fields, context)
+ values.update(dict((field, template_values[field]) for field in fields if template_values.get(field)))
+ return super(actions_server, self).create(cr, uid, values, context=context)
+
+ def write(self, cr, uid, ids, values, context=None):
+ if values.get('template_id'):
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
+ template_values = self.pool.get('email.template').read(cr, uid, values.get('template_id'), fields, context)
+ values.update(dict((field, template_values[field]) for field in fields if template_values.get(field)))
+ return super(actions_server, self).write(cr, uid, ids, values, context=context)
+
+ def run_action_email(self, cr, uid, action, eval_context=None, context=None):
+ if not action.template_id or not context.get('active_id'):
+ return False
+ self.pool['email.template'].send_mail(cr, uid, action.template_id.id, context.get('active_id'),
+ force_send=False, raise_exception=False, context=context)
+ return False
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/email_template/ir_actions_view.xml b/addons/email_template/ir_actions_view.xml
new file mode 100644
index 00000000000..fae9c364312
--- /dev/null
+++ b/addons/email_template/ir_actions_view.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ ir.actions.server.form
+ ir.actions.server
+
+
+
+
+
+ Please set the Base Model before setting the action details.
+
+
+
+
+ Choose a template to display its values.
+
+
+ The values displayed hereunder are informative. When sending the email, the values
+ will be taken from the email template.
+
+
+
+
+
+
+
+ Your template does not defined any email_from. Please update your template.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/email_template/tests/__init__.py b/addons/email_template/tests/__init__.py
index d63c5634cc3..9418985b06c 100644
--- a/addons/email_template/tests/__init__.py
+++ b/addons/email_template/tests/__init__.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-from . import test_mail
+from . import test_mail, test_ir_actions
checks = [
test_mail,
+ test_ir_actions,
]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/email_template/tests/test_ir_actions.py b/addons/email_template/tests/test_ir_actions.py
new file mode 100644
index 00000000000..d323ee36c1f
--- /dev/null
+++ b/addons/email_template/tests/test_ir_actions.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.addons.base.tests.test_ir_actions import TestServerActionsBase
+
+
+class TestServerActionsEmail(TestServerActionsBase):
+
+ def test_00_state_email(self):
+ """ Test ir.actions.server email type """
+ cr, uid = self.cr, self.uid
+
+ # create email_template
+ template_id = self.registry('email.template').create(cr, uid, {
+ 'name': 'TestTemplate',
+ 'email_from': 'myself@example.com',
+ 'email_to': 'brigitte@example.com',
+ 'partner_to': '[%s]' % self.test_partner_id,
+ 'model_id': self.res_partner_model_id,
+ 'subject': 'About ${object.name}',
+ 'body_html': '
Dear ${object.name}, your parent is ${object.parent_id and object.parent_id.name or "False"}
',
+ 'ir_actions_server: TODO')
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index 746c2cc55f6..92bf7c3aedf 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -22,6 +22,7 @@
from openerp import tools
from openerp.osv import osv, fields
+
def _reopen(self, res_id, model):
return {'type': 'ir.actions.act_window',
'view_mode': 'form',
@@ -34,7 +35,8 @@ def _reopen(self, res_id, model):
'context': {
'default_model': model,
},
- }
+ }
+
class mail_compose_message(osv.TransientModel):
_inherit = 'mail.compose.message'
@@ -58,7 +60,7 @@ class mail_compose_message(osv.TransientModel):
context = {}
wizard_context = dict(context)
for wizard in self.browse(cr, uid, ids, context=context):
- if wizard.template_id and not wizard.template_id.user_signature:
+ if wizard.template_id:
wizard_context['mail_notify_user_signature'] = False # template user_signature is added when generating body_html
if not wizard.attachment_ids or wizard.composition_mode == 'mass_mail' or not wizard.template_id:
continue
@@ -75,7 +77,7 @@ class mail_compose_message(osv.TransientModel):
""" - mass_mailing: we cannot render, so return the template values
- normal mode: return rendered values """
if template_id and composition_mode == 'mass_mail':
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'mail_server_id']
template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
elif template_id:
@@ -95,7 +97,7 @@ class mail_compose_message(osv.TransientModel):
}
values['attachment_ids'].append(ir_attach_obj.create(cr, uid, data_attach, context=context))
else:
- values = self.default_get(cr, uid, ['subject', 'body', 'email_from', 'email_to', 'email_cc', 'partner_to', 'reply_to', 'attachment_ids'], context=context)
+ values = self.default_get(cr, uid, ['subject', 'body', 'email_from', 'email_to', 'email_cc', 'partner_to', 'reply_to', 'attachment_ids', 'mail_server_id'], context=context)
if values.get('body_html'):
values['body'] = values.pop('body_html')
@@ -150,7 +152,7 @@ class mail_compose_message(osv.TransientModel):
mail.compose.message, transform email_cc and email_to into partner_ids """
template_values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
# filter template values
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments']
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments', 'mail_server_id']
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
values['body'] = values.pop('body_html', '')
diff --git a/addons/google_base_account/google_base_account.py b/addons/google_base_account/google_base_account.py
index a6cf67bbe62..50fbf233ce6 100644
--- a/addons/google_base_account/google_base_account.py
+++ b/addons/google_base_account/google_base_account.py
@@ -28,7 +28,7 @@ import urllib2
import simplejson
-class google_service(osv.osv):
+class google_service(osv.osv_memory):
_name = 'google.service'
def generate_refresh_token(self, cr, uid, service, authorization_code, context=None):
@@ -51,10 +51,10 @@ class google_service(osv.osv):
content = simplejson.loads(content)
return content.get('refresh_token')
- def _get_google_token_uri(self, cr, uid, service, context=None):
+ def _get_google_token_uri(self, cr, uid, service, scope, context=None):
ir_config = self.pool['ir.config_parameter']
params = {
- 'scope': 'https://www.googleapis.com/auth/drive',
+ 'scope': scope,
'redirect_uri': ir_config.get_param(cr, SUPERUSER_ID, 'google_redirect_uri'),
'client_id': ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service),
'response_type': 'code',
diff --git a/addons/google_drive/google_drive.py b/addons/google_drive/google_drive.py
index 1dc6b25f27c..8bc487ada7c 100644
--- a/addons/google_drive/google_drive.py
+++ b/addons/google_drive/google_drive.py
@@ -54,58 +54,69 @@ class config(osv.osv):
attachment = attach_pool.browse(cr, uid, attach_ids[0], context)
url = attachment.url
else:
- url = self.copy_doc(cr, uid, res_id, template_id, name_gdocs, model.model, context)
+ url = self.copy_doc(cr, uid, res_id, template_id, name_gdocs, model.model, context).get('url')
return url
- def copy_doc(self, cr, uid, res_id, template_id, name_gdocs, res_model, context=None):
+ def get_access_token(self, cr, uid, scope=None, context=None):
ir_config = self.pool['ir.config_parameter']
google_drive_refresh_token = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_refresh_token')
+ group_config = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'group_erp_manager')[1]
+ user = self.pool['res.users'].read(cr, uid, uid, "groups_id")
if not google_drive_refresh_token:
- raise self.pool.get('res.config.settings').get_config_warning(cr, _("You haven't configured 'Authorization Code' generated from google, Please generate and configure it in %(menu:base_setup.menu_general_configuration)s."), context=context)
+ if group_config in user['groups_id']:
+ raise self.pool.get('res.config.settings').get_config_warning(cr, _("You haven't configured 'Authorization Code' generated from google, Please generate and configure it in %(menu:base_setup.menu_general_configuration)s."), context=context)
+ else:
+ raise osv.except_osv(_('Error!'), _("Google Drive is not yet configured. Please contact your administrator."))
google_drive_client_id = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_client_id')
google_drive_client_secret = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_client_secret')
- google_web_base_url = ir_config.get_param(cr, SUPERUSER_ID, 'web.base.url')
-
#For Getting New Access Token With help of old Refresh Token
- headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
- data = dict(client_id=google_drive_client_id,
- refresh_token=google_drive_refresh_token,
- client_secret=google_drive_client_secret,
- grant_type="refresh_token")
- data = urllib.urlencode(data)
+ data = urllib.urlencode(dict(client_id=google_drive_client_id,
+ refresh_token=google_drive_refresh_token,
+ client_secret=google_drive_client_secret,
+ grant_type="refresh_token",
+ scope=scope or 'https://www.googleapis.com/auth/drive'))
+ headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
try:
req = urllib2.Request('https://accounts.google.com/o/oauth2/token', data, headers)
content = urllib2.urlopen(req).read()
except urllib2.HTTPError:
- raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during the token generation. Please request again an authorization code in %(menu:base_setup.menu_general_configuration)s."), context=context)
+ if group_config in user['groups_id']:
+ raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during the token generation. Please request again an authorization code in %(menu:base_setup.menu_general_configuration)s."), context=context)
+ else:
+ raise osv.except_osv(_('Error!'), _("Google Drive is not yet configured. Please contact your administrator."))
content = json.loads(content)
+ return content.get('access_token')
+ def copy_doc(self, cr, uid, res_id, template_id, name_gdocs, res_model, context=None):
+ ir_config = self.pool['ir.config_parameter']
+ google_web_base_url = ir_config.get_param(cr, SUPERUSER_ID, 'web.base.url')
+ access_token = self.get_access_token(cr, uid, context=context)
# Copy template in to drive with help of new access token
- if 'access_token' in content:
- request_url = "https://www.googleapis.com/drive/v2/files/%s?fields=parents/id&access_token=%s" % (template_id, content['access_token'])
- try:
- req = urllib2.Request(request_url, None, headers)
- parents = urllib2.urlopen(req).read()
- except urllib2.HTTPError:
- raise self.pool.get('res.config.settings').get_config_warning(cr, _("The Google Template cannot be found. Maybe it has been deleted."), context=context)
- parents_dict = json.loads(parents)
+ request_url = "https://www.googleapis.com/drive/v2/files/%s?fields=parents/id&access_token=%s" % (template_id, access_token)
+ headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
+ try:
+ req = urllib2.Request(request_url, None, headers)
+ parents = urllib2.urlopen(req).read()
+ except urllib2.HTTPError:
+ raise self.pool.get('res.config.settings').get_config_warning(cr, _("The Google Template cannot be found. Maybe it has been deleted."), context=context)
+ parents_dict = json.loads(parents)
- record_url = "Click on link to open Record in OpenERP\n %s/?db=%s#id=%s&model=%s" % (google_web_base_url, cr.dbname, res_id, res_model)
- data = {"title": name_gdocs, "description": record_url, "parents": parents_dict['parents']}
- request_url = "https://www.googleapis.com/drive/v2/files/%s/copy?access_token=%s" % (template_id, content['access_token'])
- headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
- data_json = json.dumps(data)
- # resp, content = Http().request(request_url, "POST", data_json, headers)
- req = urllib2.Request(request_url, data_json, headers)
- content = urllib2.urlopen(req).read()
- content = json.loads(content)
- res = False
- if 'alternateLink' in content.keys():
- attach_pool = self.pool.get("ir.attachment")
- attach_vals = {'res_model': res_model, 'name': name_gdocs, 'res_id': res_id, 'type': 'url', 'url': content['alternateLink']}
- attach_pool.create(cr, uid, attach_vals)
- res = content['alternateLink']
+ record_url = "Click on link to open Record in OpenERP\n %s/?db=%s#id=%s&model=%s" % (google_web_base_url, cr.dbname, res_id, res_model)
+ data = {"title": name_gdocs, "description": record_url, "parents": parents_dict['parents']}
+ request_url = "https://www.googleapis.com/drive/v2/files/%s/copy?access_token=%s" % (template_id, access_token)
+ headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+ data_json = json.dumps(data)
+ # resp, content = Http().request(request_url, "POST", data_json, headers)
+ req = urllib2.Request(request_url, data_json, headers)
+ content = urllib2.urlopen(req).read()
+ content = json.loads(content)
+ res = {}
+ if content.get('alternateLink'):
+ attach_pool = self.pool.get("ir.attachment")
+ attach_vals = {'res_model': res_model, 'name': name_gdocs, 'res_id': res_id, 'type': 'url', 'url': content['alternateLink']}
+ res['id'] = attach_pool.create(cr, uid, attach_vals)
+ res['url'] = content['alternateLink']
return res
def get_google_drive_config(self, cr, uid, res_model, res_id, context=None):
@@ -166,6 +177,7 @@ class config(osv.osv):
'google_drive_resource_id': fields.function(_resource_get, type="char", string='Resource Id'),
'google_drive_client_id': fields.function(_client_id_get, type="char", string='Google Client '),
'name_template': fields.char('Google Drive Name Pattern', size=64, help='Choose how the new google drive will be named, on google side. Eg. gdoc_%(field_name)s', required=True),
+ 'active': fields.boolean('Active'),
}
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
@@ -179,6 +191,7 @@ class config(osv.osv):
_defaults = {
'name_template': 'Document %(name)s',
+ 'active': True,
}
def _check_model_id(self, cr, uid, ids, context=None):
@@ -191,6 +204,9 @@ class config(osv.osv):
(_check_model_id, 'Model of selected filter is not matching with model of current template.', ['model_id', 'filter_id']),
]
+ def get_google_scope(self):
+ return 'https://www.googleapis.com/auth/drive'
+
config()
@@ -202,7 +218,7 @@ class base_config_settings(osv.osv):
'google_drive_uri': fields.char('URI', readonly=True, help="The URL to generate the authorization code from Google"),
}
_defaults = {
- 'google_drive_uri': lambda s, cr, uid, c: s.pool['google.service']._get_google_token_uri(cr, uid, 'drive', context=c),
+ 'google_drive_uri': lambda s, cr, uid, c: s.pool['google.service']._get_google_token_uri(cr, uid, 'drive', scope=s.pool['google.drive.config'].get_google_scope(), context=c),
}
def set_google_authorization_code(self, cr, uid, ids, context=None):
diff --git a/addons/google_drive/google_drive_data.xml b/addons/google_drive/google_drive_data.xml
index c9266547969..b1f9883c149 100644
--- a/addons/google_drive/google_drive_data.xml
+++ b/addons/google_drive/google_drive_data.xml
@@ -4,12 +4,12 @@
google_drive_client_id
- 39623646228-eg3ggo3mk6o40m7rguobi3rkl9frh4tb.apps.googleusercontent.com
+ 598905559630.apps.googleusercontent.comgoogle_drive_client_secret
- Ul-PtmnSWs3euWs20fdono0e
+ vTmou73c-njP-1qCxm7qx7QE
diff --git a/addons/google_drive/i18n/es.po b/addons/google_drive/i18n/es.po
index 65d28726ba4..8e7770930e0 100644
--- a/addons/google_drive/i18n/es.po
+++ b/addons/google_drive/i18n/es.po
@@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2013-06-27 16:03+0000\n"
-"PO-Revision-Date: 2012-12-12 12:51+0000\n"
-"Last-Translator: Pedro Manuel Baeza \n"
+"PO-Revision-Date: 2013-08-07 02:00+0000\n"
+"Last-Translator: Alejandro Santana \n"
"Language-Team: Spanish \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-06-28 05:42+0000\n"
-"X-Generator: Launchpad (build 16681)\n"
+"X-Launchpad-Export-Date: 2013-08-08 04:39+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
#. module: google_drive
#: model:ir.ui.menu,name:google_drive.menu_google_drive_config
msgid "Google Drive configuration"
-msgstr ""
+msgstr "Configuración de Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:48
@@ -39,6 +39,11 @@ msgid ""
"in your Google Drive and in OpenERP attachment will be named\n"
" 'Agrolait_SO0001_Sales'."
msgstr ""
+"El nombre del documento adjunto puede contener información fija o variable. "
+"Para distinguir documentos en Google Drive, use palabras y campos fijos. "
+"Así, en el ejemplo anterior, si se escribió 'Agrolait_%(name)s_Sales' en el "
+"campo de nombre de GoogleDrive, el documento en su Google Drive y en los "
+"adjuntos de OpenERP se llamarán 'Agrolait_SO0001_Sales'."
#. module: google_drive
#: view:google.drive.config:0
@@ -46,16 +51,18 @@ msgid ""
"- If filter is not specified, link of google document will appear in "
"\"More\" option for all users for all opportunities."
msgstr ""
+"- Si no especifica un filtro, el enlace del documento de Google aparecerá en "
+"la opción \"Más\" para todos los usuarios para todas las oportunidades."
#. module: google_drive
#: view:google.drive.config:0
msgid "To create a new filter:"
-msgstr ""
+msgstr "Para crear un nuevo filtro:"
#. module: google_drive
#: model:ir.model,name:google_drive.model_base_config_settings
msgid "base.config.settings"
-msgstr ""
+msgstr "base.config.settings"
#. module: google_drive
#: model:ir.actions.act_window,help:google_drive.action_google_drive_users_config
@@ -73,17 +80,29 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Pulse para añadir una plantilla.\n"
+"
\n"
+"
\n"
+" Enlace sus propias plantillas de Google Drive a "
+"cualquier registro de OpenERP. Si tiene documentos realmente específicos que "
+"quiere que su colaborador rellene (como usar una hoja de cálculo para "
+"controlar la calidad de su producto o revisar los detalles de entrega de "
+"cada pedido en un país extranjero,...) es muy sencillo gestionarlo. "
+"Enlácelos en OpenERP y úselos para colaborar con sus empleados.\n"
+"
\n"
+" "
#. module: google_drive
#: code:addons/google_drive/google_drive.py:150
#, python-format
msgid "Incorrect URL!"
-msgstr ""
+msgstr "¡URL incorrecta!"
#. module: google_drive
#: view:base.config.settings:0
msgid "Configure your templates"
-msgstr ""
+msgstr "Configure sus plantillas"
#. module: google_drive
#: help:google.drive.config,name_template:0
@@ -91,6 +110,8 @@ msgid ""
"Choose how the new google drive will be named, on google side. Eg. "
"gdoc_%(field_name)s"
msgstr ""
+"Elija el nombre de la nueva unidad de Google Drive, en el lado de Google. "
+"P.ej.: gdoc_%(field_name)s"
#. module: google_drive
#: view:google.drive.config:0
@@ -98,6 +119,8 @@ msgid ""
"- Go to the OpenERP document you want to filter. For instance, go to "
"Opportunities and search on Sales Department."
msgstr ""
+"- Vaya al documento de OpenERP que quiera filtrar. Por ejemplo, vaya a "
+"Oportunidades y busque en el Departamento de ventas."
#. module: google_drive
#: view:google.drive.config:0
@@ -105,6 +128,8 @@ msgid ""
"- In this \"Search\" view, select the option \"Save Current Filter\", enter "
"the name (Ex: Sales Department)"
msgstr ""
+"- En esta vista de \"Búsqueda\", seleccione la opción \"Guardar filtro "
+"actual\" e introduzca el nombre (p.ej.: Departamento de ventas)"
#. module: google_drive
#: view:google.drive.config:0
@@ -113,6 +138,9 @@ msgid ""
"\"More\" options will appear for all users in opportunities of Sales "
"Department."
msgstr ""
+"- Si selecciona \"Compartir con todos los usuarios\", el enlace al documento "
+"de Google en la opción \"Más\" aparecerá para todos los usuarios en las "
+"oportunidades del Departamento de ventas."
#. module: google_drive
#: view:google.drive.config:0
@@ -121,23 +149,28 @@ msgid ""
"\"More\" options will not appear for other users in opportunities of Sales "
"Department."
msgstr ""
+"- Si no selecciona \"Compartir con todos los usuarios\", el enlace al "
+"documento de Google en la opción \"Más\" no aparecerá para otros usuarios en "
+"las oportunidades del Departamento de ventas."
#. module: google_drive
#: code:addons/google_drive/google_drive.py:48
#, python-format
msgid "At least one key cannot be found in your Google Drive name pattern"
msgstr ""
+"No se ha podido encontrar al menos una clave de su patrón de nombres de "
+"Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:150
#, python-format
msgid "Please enter a valid Google Document URL."
-msgstr ""
+msgstr "Por favor, introduzca una URL de documento de Google válida."
#. module: google_drive
#: field:google.drive.config,google_drive_client_id:0
msgid "Google Client "
-msgstr ""
+msgstr "Cliente de Google "
#. module: google_drive
#: view:google.drive.config:0
@@ -145,43 +178,45 @@ msgid ""
"https://docs.google.com/document/d/1vOtpJK9scIQz6taD9tJRIETWbEw3fSiaQHArsJYcu"
"a4/edit"
msgstr ""
+"https://docs.google.com/document/d/1vOtpJK9scIQz6taD9tJRIETWbEw3fSiaQHArsJYcu"
+"a4/edit"
#. module: google_drive
#: field:google.drive.config,filter_id:0
msgid "Filter"
-msgstr ""
+msgstr "Filtro"
#. module: google_drive
#: field:google.drive.config,name_template:0
msgid "Google Drive Name Pattern"
-msgstr ""
+msgstr "Patrón de nombres de Google Drive"
#. module: google_drive
#: help:base.config.settings,google_drive_uri:0
msgid "The URL to generate the authorization code from Google"
-msgstr ""
+msgstr "La URL para generar el código de autorización de Google"
#. module: google_drive
#: model:ir.filters,name:google_drive.filter_partner
msgid "Customer"
-msgstr ""
+msgstr "Cliente"
#. module: google_drive
#: field:google.drive.config,google_drive_resource_id:0
msgid "Resource Id"
-msgstr ""
+msgstr "ID del recurso"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:91
#, python-format
msgid "The Google Template cannot be found. Maybe it has been deleted."
-msgstr ""
+msgstr "No se encuentra la plantilla de Google. Tal vez se haya eliminado."
#. module: google_drive
#: model:ir.actions.act_window,name:google_drive.action_google_drive_users_config
#: model:ir.ui.menu,name:google_drive.menu_google_drive_model_config
msgid "Google Drive Templates"
-msgstr ""
+msgstr "Plantillas de Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:81
@@ -190,23 +225,27 @@ msgid ""
"Something went wrong during the token generation. Please request again an "
"authorization code in %(menu:base_setup.menu_general_configuration)s."
msgstr ""
+"Algo ha ido mal durante la creación del testigo. Por favor, solicite un "
+"código de autorización otra vez en "
+"%(menu:base_setup.menu_general_configuration)s."
#. module: google_drive
#: code:addons/google_drive/google_drive.py:124
#, python-format
msgid "Google Drive Error!"
-msgstr ""
+msgstr "¡Error de Google Drive!"
#. module: google_drive
#: field:base.config.settings,google_drive_uri:0
msgid "URI"
-msgstr ""
+msgstr "URI"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:124
#, python-format
msgid "Creating google drive may only be done by one at a time."
msgstr ""
+"Es posible que la creación de Google Drive sólo se pueda hacer de una en una."
#. module: google_drive
#: field:google.drive.config,model:0
@@ -217,38 +256,40 @@ msgstr "Modelo"
#. module: google_drive
#: view:google.drive.config:0
msgid "Google Drive Configuration"
-msgstr ""
+msgstr "Configuración de Google Drive"
#. module: google_drive
#: field:google.drive.config,name:0
msgid "Template Name"
-msgstr ""
+msgstr "Nombre de la plantilla"
#. module: google_drive
#: constraint:google.drive.config:0
msgid ""
"Model of selected filter is not matching with model of current template."
msgstr ""
+"El modelo del filtro seleccionado no coincide con el modelo de la plantilla "
+"actual."
#. module: google_drive
#: field:google.drive.config,google_drive_template_url:0
msgid "Template URL"
-msgstr ""
+msgstr "URL de la plantilla"
#. module: google_drive
#: view:base.config.settings:0
msgid "and paste it here"
-msgstr ""
+msgstr "y péguela aquí"
#. module: google_drive
#: field:base.config.settings,google_drive_authorization_code:0
msgid "Authorization Code"
-msgstr ""
+msgstr "Cídigo de autorización"
#. module: google_drive
#: model:ir.model,name:google_drive.model_google_drive_config
msgid "Google Drive templates config"
-msgstr ""
+msgstr "Configuración de plantillas de Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:64
@@ -257,3 +298,6 @@ msgid ""
"You haven't configured 'Authorization Code' generated from google, Please "
"generate and configure it in %(menu:base_setup.menu_general_configuration)s."
msgstr ""
+"No ha configurado el 'código de autorización' generado por Google. Por "
+"favor, genérelo y configúrelo en "
+"%(menu:base_setup.menu_general_configuration)s."
diff --git a/addons/google_drive/res_config_user_view.xml b/addons/google_drive/res_config_user_view.xml
index 728ef03c5dd..dc563a76c2b 100644
--- a/addons/google_drive/res_config_user_view.xml
+++ b/addons/google_drive/res_config_user_view.xml
@@ -23,6 +23,7 @@
+
@@ -54,7 +55,7 @@
- Google Drive Templates
+ Templatesgoogle.drive.configir.actions.act_windowform
@@ -87,7 +88,7 @@
-
+
diff --git a/addons/google_drive/static/src/js/gdrive.js b/addons/google_drive/static/src/js/gdrive.js
index 3267487b4e3..dbbe50d0794 100644
--- a/addons/google_drive/static/src/js/gdrive.js
+++ b/addons/google_drive/static/src/js/gdrive.js
@@ -29,19 +29,24 @@ openerp.google_drive = function (instance, m) {
ds.call('get_google_drive_config', [view.dataset.model, res_id, context]).done(function (r) {
if (!_.isEmpty(r)) {
_.each(r, function (res) {
- var g_item = _.indexOf(_.pluck(self.items.other, 'label'), res.name);
- if (g_item !== -1) {
- self.items.other.splice(g_item, 1);
+ var already_there = false;
+ for (var i = 0;i < self.items.other.length;i++){
+ if (self.items.other[i].classname === "oe_share_gdoc" && self.items.other[i].label.indexOf(res.name) > -1){
+ already_there = true;
+ break;
+ }
+ }
+ if (!already_there){
+ self.add_items('other', [{
+ label: res.name+ '',
+ config_id: res.id,
+ res_id: res_id,
+ res_model: view.dataset.model,
+ callback: self.on_google_doc,
+ classname: 'oe_share_gdoc'
+ },
+ ]);
}
- self.add_items('other', [{
- label: res.name+ '',
- config_id: res.id,
- res_id: res_id,
- res_model: view.dataset.model,
- callback: self.on_google_doc,
- classname: 'oe_share_gdoc'
- },
- ]);
})
}
});
diff --git a/addons/google_spreadsheet/__init__.py b/addons/google_spreadsheet/__init__.py
new file mode 100644
index 00000000000..f57aaed7749
--- /dev/null
+++ b/addons/google_spreadsheet/__init__.py
@@ -0,0 +1 @@
+import google_spreadsheet
\ No newline at end of file
diff --git a/addons/google_spreadsheet/__openerp__.py b/addons/google_spreadsheet/__openerp__.py
new file mode 100644
index 00000000000..1ae2d48d349
--- /dev/null
+++ b/addons/google_spreadsheet/__openerp__.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+
+{
+ 'name': 'Google Spreadsheet',
+ 'version': '1.0',
+ 'category': 'Tools',
+ 'description': """
+The module adds the possibility to display data from OpenERP in Google Spreadsheets in real time.
+========================================
+""",
+ 'author': 'OpenERP SA',
+ 'website': 'http://www.openerp.com',
+ 'depends': ['board', 'google_drive'],
+ 'js': [
+ 'static/src/js/search.js',
+ ],
+ 'qweb': ['static/src/xml/*.xml'],
+ 'data': ['google_spreadsheet_view.xml', 'google_spreadsheet_data.xml'],
+ 'demo': [],
+ 'installable': True,
+ 'auto_install': False,
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/google_spreadsheet/google_spreadsheet.py b/addons/google_spreadsheet/google_spreadsheet.py
new file mode 100644
index 00000000000..693300904d0
--- /dev/null
+++ b/addons/google_spreadsheet/google_spreadsheet.py
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2012 OpenERP SA ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import simplejson
+import logging
+from lxml import etree
+import re
+import urllib
+import urllib2
+
+from openerp.osv import osv
+from openerp import SUPERUSER_ID
+
+_logger = logging.getLogger(__name__)
+
+class config(osv.osv):
+ _inherit = 'google.drive.config'
+
+ def get_google_scope(self):
+ scope = super(config, self).get_google_scope()
+ return '%s https://spreadsheets.google.com/feeds' % scope
+
+ def write_config_formula(self, cr, uid, attachment_id, spreadsheet_key, model, domain, groupbys, view_id, context=None):
+ access_token = self.get_access_token(cr, uid, scope='https://spreadsheets.google.com/feeds', context=context)
+
+ fields = self.pool.get(model).fields_view_get(cr, uid, view_id=view_id, view_type='tree')
+ doc = etree.XML(fields.get('arch'))
+ display_fields = []
+ for node in doc.xpath("//field"):
+ if node.get('modifiers'):
+ modifiers = simplejson.loads(node.get('modifiers'))
+ if not modifiers.get('invisible') and not modifiers.get('tree_invisible'):
+ display_fields.append(node.get('name'))
+ fields = " ".join(display_fields)
+ domain = domain.replace("'", r"\'").replace('"', "'")
+ if groupbys:
+ fields = "%s %s" % (groupbys, fields)
+ formula = '=oe_read_group("%s";"%s";"%s";"%s")' % (model, fields, groupbys, domain)
+ else:
+ formula = '=oe_browse("%s";"%s";"%s")' % (model, fields, domain)
+ url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
+ dbname = cr.dbname
+ user = self.pool['res.users'].read(cr, uid, uid, ['login', 'password'], context=context)
+ username = user['login']
+ password = user['password']
+ if self.pool['ir.module.module'].search_count(cr, SUPERUSER_ID, ['&', ('name', '=', 'auth_crypt'), ('state', '=', 'installed')]) == 1:
+ config_formula = '=oe_settings("%s";"%s")' % (url, dbname)
+ else:
+ config_formula = '=oe_settings("%s";"%s";"%s";"%s")' % (url, dbname, username, password)
+ request = '''
+ https://spreadsheets.google.com/feeds/cells/%s/od6/private/full
+
+ A1
+
+ https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R1C1
+
+
+
+
+ A2
+
+ https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R60C15
+
+
+
+''' % (spreadsheet_key, spreadsheet_key, spreadsheet_key, formula.replace('"', '"'), spreadsheet_key, spreadsheet_key, config_formula.replace('"', '"'))
+
+ try:
+ req = urllib2.Request(
+ 'https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/batch?%s' % (spreadsheet_key, urllib.urlencode({'v': 3, 'access_token': access_token})),
+ data=request,
+ headers={'content-type': 'application/atom+xml', 'If-Match': '*'})
+ urllib2.urlopen(req)
+ except (urllib2.HTTPError, urllib2.URLError):
+ _logger.warning("An error occured while writting the formula on the Google Spreadsheet.")
+
+ description = '''
+ formula: %s
+ ''' % formula
+ if attachment_id:
+ self.pool['ir.attachment'].write(cr, uid, attachment_id, {'description': description}, context=context)
+ return True
+
+ def set_spreadsheet(self, cr, uid, model, domain, groupbys, view_id, context=None):
+ try:
+ config_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'google_spreadsheet', 'google_spreadsheet_template')[1]
+ except ValueError:
+ raise
+ config = self.browse(cr, uid, config_id, context=context)
+ title = 'Spreadsheet %s' % model
+ res = self.copy_doc(cr, uid, False, config.google_drive_resource_id, title, model, context=context)
+
+ mo = re.search("(key=|/d/)([A-Za-z0-9-_]+)", res['url'])
+ if mo:
+ key = mo.group(2)
+
+ self.write_config_formula(cr, uid, res.get('id'), key, model, domain, groupbys, view_id, context=context)
+ return res
diff --git a/addons/google_spreadsheet/google_spreadsheet_data.xml b/addons/google_spreadsheet/google_spreadsheet_data.xml
new file mode 100644
index 00000000000..19802e9d140
--- /dev/null
+++ b/addons/google_spreadsheet/google_spreadsheet_data.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ Base Spreadsheet Template
+
+ https://docs.google.com/spreadsheet/ccc?key=0ApGVjjwUC-ygdDZ0TG5EQnRlLVFQNlFGdFN5b1ZrY1E
+ Reporting %(name)s
+
+
+
+
\ No newline at end of file
diff --git a/addons/google_spreadsheet/google_spreadsheet_view.xml b/addons/google_spreadsheet/google_spreadsheet_view.xml
new file mode 100644
index 00000000000..e99826dae52
--- /dev/null
+++ b/addons/google_spreadsheet/google_spreadsheet_view.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+ ir.attachment.google.spreadsheet.tree
+ ir.attachment
+
+
+
+
+
+
+
+
+
+ ir.attachment.google.spreadsheet.form
+ ir.attachment
+
+
+
+
+
+
+ Google Spreadsheets
+ ir.attachment
+ form
+ tree,form
+ {}
+ [('url', 'like', '/spreadsheet/')]
+ Google Spreadsheets
+
+
+
+
+ tree
+
+
+
+
+
+
+ form
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/google_spreadsheet/i18n/google_spreadsheet.pot b/addons/google_spreadsheet/i18n/google_spreadsheet.pot
new file mode 100644
index 00000000000..3cf39bd8df5
--- /dev/null
+++ b/addons/google_spreadsheet/i18n/google_spreadsheet.pot
@@ -0,0 +1,42 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * google_spreadsheet
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 8.0alpha1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-25 12:39+0000\n"
+"PO-Revision-Date: 2013-07-25 12:39+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: google_spreadsheet
+#: model:ir.actions.act_window,help:google_spreadsheet.action_ir_attachment_google_spreadsheet_tree
+#: model:ir.actions.act_window,name:google_spreadsheet.action_ir_attachment_google_spreadsheet_tree
+#: view:ir.attachment:0
+#: model:ir.ui.menu,name:google_spreadsheet.menu_reporting_dashboard_google_spreadsheets
+msgid "Google Spreadsheets"
+msgstr ""
+
+#. module: google_spreadsheet
+#. openerp-web
+#: code:addons/google_spreadsheet/static/src/xml/addtospreadsheet.xml:3
+#, python-format
+msgid "Add to Google Spreadsheet"
+msgstr ""
+
+#. module: google_spreadsheet
+#: view:ir.attachment:0
+msgid "Name"
+msgstr ""
+
+#. module: google_spreadsheet
+#: model:ir.model,name:google_spreadsheet.model_google_drive_config
+msgid "Google Drive templates config"
+msgstr ""
+
diff --git a/addons/google_spreadsheet/static/src/js/search.js b/addons/google_spreadsheet/static/src/js/search.js
new file mode 100644
index 00000000000..c46ec615792
--- /dev/null
+++ b/addons/google_spreadsheet/static/src/js/search.js
@@ -0,0 +1,54 @@
+openerp.google_spreadsheet = function(instance) {
+ var _t = instance.web._t;
+ instance.web.FormView.include({
+ on_processed_onchange: function(result, processed) {
+ var self = this;
+
+ var fields = self.fields;
+ _(result.selection).each(function (selection, fieldname) {
+ var field = fields[fieldname];
+ if (!field) { return; }
+ field.field.selection = selection;
+ field.values = selection;
+ field.renderElement();
+ });
+ return this._super(result, processed);
+ },
+ });
+ instance.board.AddToGoogleSpreadsheet = instance.web.search.Input.extend({
+ template: 'SearchView.addtogooglespreadsheet',
+ _in_drawer: true,
+ start: function () {
+ var self = this;
+ this.$el.on('click', 'h4', function(){
+ var view = self.view;
+ var data = view.build_search_data();
+ var model = view.model;
+ var list_view = self.view.getParent().views['list'];
+ var view_id = list_view ? list_view.view_id : false;
+ var context = new instance.web.CompoundContext(view.dataset.get_context() || []);
+ var domain = new instance.web.CompoundDomain(view.dataset.get_domain() || []);
+ _.each(data.contexts, context.add, context);
+ _.each(data.domains, domain.add, domain);
+ domain = JSON.stringify(domain.eval());
+ var groupbys = instance.web.pyeval.eval('groupbys', data.groupbys).join(" ");
+ var view_id = view_id;
+ var ds = new instance.web.DataSet(self, 'google.drive.config');
+ ds.call('set_spreadsheet', [model, domain, groupbys, view_id]).done(function (res) {
+ if (res['url']){
+ window.open(res['url'], '_blank');
+ }
+ });
+ });
+ },
+ });
+ instance.web.SearchView.include({
+ add_common_inputs: function() {
+ this._super();
+ var vm = this.getParent().getParent();
+ if (vm.inner_action && vm.inner_action.views) {
+ (new instance.board.AddToGoogleSpreadsheet(this));
+ }
+ }
+ });
+};
\ No newline at end of file
diff --git a/addons/google_spreadsheet/static/src/xml/addtospreadsheet.xml b/addons/google_spreadsheet/static/src/xml/addtospreadsheet.xml
new file mode 100644
index 00000000000..faf984141a6
--- /dev/null
+++ b/addons/google_spreadsheet/static/src/xml/addtospreadsheet.xml
@@ -0,0 +1,5 @@
+
+
+
Add to Google Spreadsheet
+
+
\ No newline at end of file
diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py
index 8f072dd9082..1b9111d3040 100644
--- a/addons/mail/__openerp__.py
+++ b/addons/mail/__openerp__.py
@@ -83,7 +83,6 @@ Main Features
'static/src/css/mail_group.css',
],
'js': [
- 'static/lib/jquery.expander/jquery.expander.js',
'static/src/js/mail.js',
'static/src/js/mail_followers.js',
'static/src/js/many2many_tags_email.js',
diff --git a/addons/mail/doc/changelog.rst b/addons/mail/doc/changelog.rst
index f6674bb42ad..a7a2cfcf2b5 100644
--- a/addons/mail/doc/changelog.rst
+++ b/addons/mail/doc/changelog.rst
@@ -6,6 +6,12 @@ Changelog
`trunk (saas-2)`
----------------
+ - added support of ``active_domain`` form context, coming from the list view.
+ When checking the header hook, the mass mailing will be done on all records
+ matching the ``active_domain``.
+ - added ``mail_server_id`` to mail_message, removing it from mail_mail. This allows
+ to set the preferred mail server to use for notifications emails, when using
+ templates.
- added ``_mail_post_access`` attribute that specifies the access right that
should have the user in order to post a new message on a given model. Values
- are ``read`` (portal documents), ``write`` (default value), ``unlink`` or ``create``.
\ No newline at end of file
+ are ``read`` (portal documents), ``write`` (default value), ``unlink`` or ``create``.
diff --git a/addons/mail/i18n/bs.po b/addons/mail/i18n/bs.po
new file mode 100644
index 00000000000..b50a043e2a7
--- /dev/null
+++ b/addons/mail/i18n/bs.po
@@ -0,0 +1,1687 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-08-06 10:21+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Bosnian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
+
+#. module: mail
+#: view:mail.followers:0
+msgid "Followers Form"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_publisher_warranty_contract
+msgid "publisher_warranty.contract"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,author_id:0
+#: view:mail.mail:0
+#: field:mail.message,author_id:0
+msgid "Author"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Message Details"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,email_to:0
+msgid "Message recipients"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,default:0
+msgid "Activated by default when subscribing."
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Comments"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: view:mail.mail:0
+msgid "Group By..."
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,body:0
+#: help:mail.message,body:0
+msgid "Automatically sanitized HTML contents"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_name:0
+msgid ""
+"The name of the email alias, e.g. 'jobs' if you want to catch emails for "
+""
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard
+#: view:mail.compose.message:0
+msgid "Compose Email"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:132
+#, python-format
+msgid "Add them into recipients and followers"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Group Name"
+msgstr ""
+
+#. module: mail
+#: selection:mail.group,public:0
+msgid "Public"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Body"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Show messages to read"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,email_from:0
+#: help:mail.message,email_from:0
+msgid ""
+"Email address of the sender. This field is set when no matching partner is "
+"found for incoming emails."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_compose_message
+msgid "Email composition wizard"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:23
+#, python-format
+msgid "Add others"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,parent_id:0
+msgid "Parent"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,message_unread:0
+#: field:mail.thread,message_unread:0
+#: field:res.partner,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:313
+#, python-format
+msgid "show"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,group_ids:0
+msgid ""
+"Members of those groups will automatically added as followers. Note that "
+"they will be able to manage their subscription manually if necessary."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail.js:1029
+#, python-format
+msgid "Do you really want to delete this message?"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+#: field:mail.notification,read:0
+msgid "Read"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Search Groups"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail_followers.js:157
+#, python-format
+msgid "followers"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:737
+#, python-format
+msgid "Access Denied"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,image_medium:0
+msgid ""
+"Medium-sized photo of the group. It is automatically resized as a 128x128px "
+"image, with aspect ratio preserved. Use this field in form views or some "
+"kanban views."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:212
+#, python-format
+msgid "Uploading error"
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_support
+msgid "Support"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:738
+#, python-format
+msgid ""
+"The requested operation cannot be completed due to security restrictions. "
+"Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: selection:mail.mail,state:0
+msgid "Received"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Thread"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:29
+#, python-format
+msgid "Open the full mail composer"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:29
+#, python-format
+msgid "ò"
+msgstr ""
+
+#. module: mail
+#: field:base.config.settings,alias_domain:0
+msgid "Alias Domain"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,group_ids:0
+msgid "Auto Subscription"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,references:0
+msgid "References"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:206
+#, python-format
+msgid "No messages."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_group
+msgid "Discussion group"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:96
+#: code:addons/mail/static/src/xml/mail.xml:108
+#, python-format
+msgid "uploading"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:52
+#, python-format
+msgid "more."
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,type:0
+#: help:mail.message,type:0
+msgid ""
+"Message type: email for email message, notification for system message, "
+"comment for other messages such as user replies"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,relation_field:0
+msgid ""
+"Field used to link the related model to the subtype model when using "
+"automatic subscription on a related document. The field is used to compute "
+"getattr(related_document.relation_field)."
+msgstr ""
+
+#. module: mail
+#: selection:mail.mail,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,reply_to:0
+msgid "Reply-To"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/wizard/invite.py:37
+#, python-format
+msgid "
You have been invited to follow %s.
"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,message_unread:0
+#: help:mail.thread,message_unread:0
+#: help:res.partner,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: mail
+#: field:mail.group,image_medium:0
+msgid "Medium-sized photo"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_to_me_feeds
+#: model:ir.ui.menu,name:mail.mail_tomefeeds
+msgid "To: me"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,name:0
+msgid "Message Type"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,auto_delete:0
+msgid "Auto Delete"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:12
+#: view:mail.group:0
+#, python-format
+msgid "Unfollow"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:312
+#, python-format
+msgid "show one more message"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_mail.py:75
+#: code:addons/mail/res_users.py:69
+#, python-format
+msgid "Invalid Action!"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:25
+#, python-format
+msgid "User img"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_mail_mail
+#: model:ir.ui.menu,name:mail.menu_mail_mail
+#: view:mail.mail:0
+#: view:mail.message:0
+msgid "Emails"
+msgstr ""
+
+#. module: mail
+#: field:mail.followers,partner_id:0
+msgid "Related Partner"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,message_summary:0
+#: help:mail.thread,message_summary:0
+#: help:res.partner,message_summary:0
+msgid ""
+"Holds the Chatter summary (number of messages, ...). This summary is "
+"directly in html format in order to be inserted in kanban views."
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_model_id:0
+msgid ""
+"The model (OpenERP Document Kind) to which this alias corresponds. Any "
+"incoming email that does not reply to an existing record will cause the "
+"creation of a new record of this model (e.g. a Project Task)"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,relation_field:0
+msgid "Relation field"
+msgstr ""
+
+#. module: mail
+#: selection:mail.compose.message,type:0
+#: selection:mail.message,type:0
+msgid "System notification"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: mail
+#: model:ir.ui.menu,name:mail.mail_my_stuff
+msgid "Organizer"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,subject:0
+#: field:mail.message,subject:0
+msgid "Subject"
+msgstr ""
+
+#. module: mail
+#: field:mail.wizard.invite,partner_ids:0
+msgid "Partners"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Retry"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,email_from:0
+#: field:mail.mail,email_from:0
+#: field:mail.message,email_from:0
+msgid "From"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: view:mail.message.subtype:0
+msgid "Email message"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_base_config_settings
+msgid "base.config.settings"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:36
+#: view:mail.compose.message:0
+#, python-format
+msgid "Send"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail_followers.js:153
+#, python-format
+msgid "No followers"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Failed"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:22
+#: model:ir.actions.act_window,name:mail.action_view_followers
+#: model:ir.ui.menu,name:mail.menu_email_followers
+#: view:mail.followers:0
+#: field:mail.group,message_follower_ids:0
+#: field:mail.thread,message_follower_ids:0
+#: field:res.partner,message_follower_ids:0
+#, python-format
+msgid "Followers"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_archives_feeds
+#: model:ir.ui.menu,name:mail.mail_archivesfeeds
+msgid "Archives"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:95
+#: code:addons/mail/static/src/xml/mail.xml:107
+#, python-format
+msgid "Delete this attachment"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:245
+#: view:mail.mail:0
+#, python-format
+msgid "Reply"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail_followers.js:155
+#, python-format
+msgid "One follower"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,type:0
+#: field:mail.message,type:0
+msgid "Type"
+msgstr ""
+
+#. module: mail
+#: selection:mail.compose.message,type:0
+#: view:mail.mail:0
+#: selection:mail.message,type:0
+msgid "Email"
+msgstr ""
+
+#. module: mail
+#: field:ir.ui.menu,mail_group_id:0
+msgid "Mail Group"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "Comments and Emails"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_defaults:0
+msgid "Default Values"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/res_users.py:89
+#, python-format
+msgid "%s has joined the %s network."
+msgstr ""
+
+#. module: mail
+#: help:mail.group,image_small:0
+msgid ""
+"Small-sized photo of the group. It is automatically resized as a 64x64px "
+"image, with aspect ratio preserved. Use this field anywhere a small image is "
+"required."
+msgstr ""
+
+#. module: mail
+#: view:mail.compose.message:0
+#: field:mail.message,partner_ids:0
+msgid "Recipients"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:140
+#, python-format
+msgid "<<<"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:43
+#, python-format
+msgid "Write to the followers of this document..."
+msgstr ""
+
+#. module: mail
+#: field:mail.group,group_public_id:0
+msgid "Authorized Group"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Join Group"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,email_from:0
+msgid "Message sender, taken from user preferences."
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/wizard/invite.py:40
+#, python-format
+msgid "
\n"
+" This list contains messages sent to you.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_rd
+msgid "R&D"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:61
+#, python-format
+msgid "/web/binary/upload_attachment"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_thread
+msgid "Email Thread"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Advanced"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:244
+#, python-format
+msgid "Move to Inbox"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/wizard/mail_compose_message.py:193
+#, python-format
+msgid "Re:"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,to_read:0
+#: field:mail.message,to_read:0
+msgid "To read"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/res_users.py:69
+#, python-format
+msgid ""
+"You may not create a user. To create new users, you should use the "
+"\"Settings > Users\" menu."
+msgstr ""
+
+#. module: mail
+#: help:mail.followers,res_model:0
+#: help:mail.wizard.invite,res_model:0
+msgid "Model of the followed resource"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:337
+#, python-format
+msgid "like"
+msgstr ""
+
+#. module: mail
+#: view:mail.compose.message:0
+#: view:mail.wizard.invite:0
+msgid "Cancel"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:47
+#, python-format
+msgid "Share with my followers..."
+msgstr ""
+
+#. module: mail
+#: field:mail.notification,partner_id:0
+msgid "Contact"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid ""
+"Only the invited followers can read the\n"
+" discussions on this group."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_ir_ui_menu
+msgid "ir.ui.menu"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Has attachments"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "on"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:926
+#, python-format
+msgid ""
+"The following partners chosen as recipients for the email have no email "
+"address linked :"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_defaults:0
+msgid ""
+"A Python dictionary that will be evaluated to provide default values when "
+"creating new records for this alias."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_message_subtype
+msgid "Message subtypes"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,notified_partner_ids:0
+#: help:mail.message,notified_partner_ids:0
+msgid ""
+"Partners that have a notification pushing this message in their mailboxes"
+msgstr ""
+
+#. module: mail
+#: selection:mail.compose.message,type:0
+#: view:mail.mail:0
+#: selection:mail.message,type:0
+msgid "Comment"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_inbox_feeds
+msgid ""
+"
\n"
+" Good Job! Your inbox is empty.\n"
+"
\n"
+" Your inbox contains private messages or emails sent to "
+"you\n"
+" as well as information related to documents or people "
+"you\n"
+" follow.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,notification:0
+msgid "Is Notification"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:188
+#, python-format
+msgid "Compose a new message"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Send Now"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_mail.py:75
+#, python-format
+msgid ""
+"Unable to send email, please configure the sender's email address or alias."
+msgstr ""
+
+#. module: mail
+#: help:res.users,alias_id:0
+msgid ""
+"Email address internally associated with this user. Incoming emails will "
+"appear in the user's notifications."
+msgstr ""
+
+#. module: mail
+#: field:mail.group,image:0
+msgid "Photo"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:54
+#: code:addons/mail/static/src/xml/mail.xml:191
+#: view:mail.compose.message:0
+#: view:mail.wizard.invite:0
+#, python-format
+msgid "or"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,vote_user_ids:0
+#: help:mail.message,vote_user_ids:0
+msgid "Users that voted for this message"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,alias_id:0
+msgid ""
+"The email address associated with this group. New emails received will "
+"automatically create new topics."
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Month"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Email Search"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,child_ids:0
+#: field:mail.message,child_ids:0
+msgid "Child Messages"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_user_id:0
+msgid "Owner"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_message
+#: field:mail.mail,mail_message_id:0
+#: view:mail.message:0
+#: field:mail.notification,message_id:0
+#: field:mail.wizard.invite,message:0
+msgid "Message"
+msgstr ""
+
+#. module: mail
+#: help:mail.followers,res_id:0
+#: help:mail.wizard.invite,res_id:0
+msgid "Id of the followed resource"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,body:0
+#: field:mail.message,body:0
+msgid "Contents"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_mail_alias
+#: model:ir.ui.menu,name:mail.mail_alias_menu
+msgid "Aliases"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,description:0
+msgid ""
+"Description that will be added in the message posted for this subtype. If "
+"void, the name will be added instead."
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,vote_user_ids:0
+#: field:mail.message,vote_user_ids:0
+msgid "Votes"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Group"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,starred:0
+#: help:mail.message,starred:0
+msgid "Current user has a starred notification linked to this message"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,public:0
+msgid "Privacy"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Notification"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail.js:654
+#, python-format
+msgid "Please complete partner's informations"
+msgstr ""
+
+#. module: mail
+#: view:mail.wizard.invite:0
+msgid "Add Followers"
+msgstr ""
+
+#. module: mail
+#: view:mail.compose.message:0
+msgid "Followers of selected items and"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_force_thread_id:0
+msgid "Record Thread ID"
+msgstr ""
+
+#. module: mail
+#: model:ir.ui.menu,name:mail.mail_group_root
+msgid "My Groups"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_archives_feeds
+msgid ""
+"
\n"
+" No message found and no message sent yet.\n"
+"
\n"
+" Click on the top-right icon to compose a message. This\n"
+" message will be sent by email if it's an internal "
+"contact.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: field:mail.mail,state:0
+msgid "Status"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: selection:mail.mail,state:0
+msgid "Outgoing"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "All feeds"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,record_name:0
+#: help:mail.message,record_name:0
+msgid "Name get of the related document."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_notifications
+#: model:ir.model,name:mail.model_mail_notification
+#: model:ir.ui.menu,name:mail.menu_email_notifications
+#: field:mail.compose.message,notification_ids:0
+#: view:mail.message:0
+#: field:mail.message,notification_ids:0
+#: view:mail.notification:0
+msgid "Notifications"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+msgid "Search Alias"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_force_thread_id:0
+msgid ""
+"Optional ID of a thread (record) to which all incoming messages will be "
+"attached, even if they did not reply to it. If set, this will disable the "
+"creation of new records completely."
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,name:0
+msgid ""
+"Message subtype gives a more precise type on the message, especially for "
+"system notifications. For example, it can be a notification related to a new "
+"record (New), or to a stage change in a process (Stage change). Message "
+"subtypes allow to precisely tune the notifications the user want to receive "
+"on its wall."
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "by"
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_best_sales_practices
+msgid "Best Sales Practices"
+msgstr ""
+
+#. module: mail
+#: selection:mail.group,public:0
+msgid "Selected Group Only"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,message_is_follower:0
+#: field:mail.thread,message_is_follower:0
+#: field:res.partner,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: view:mail.mail:0
+msgid "User"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Groups"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Messages Search"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,date:0
+#: field:mail.message,date:0
+msgid "Date"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:34
+#, python-format
+msgid "Post"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Extended Filters..."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:120
+#, python-format
+msgid "To:"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:193
+#, python-format
+msgid "Write to my followers"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_res_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,default:0
+msgid "Default"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:311
+#, python-format
+msgid "show more message"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:246
+#, python-format
+msgid "Mark as Todo"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,parent_id:0
+msgid "Parent subtype, used for automatic subscription."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_wizard_invite
+msgid "Invite wizard"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,message_summary:0
+#: field:mail.thread,message_summary:0
+#: field:res.partner,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,res_model:0
+msgid ""
+"Model the subtype applies to. If False, this subtype applies to all models."
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,subtype_id:0
+#: field:mail.followers,subtype_ids:0
+#: field:mail.message,subtype_id:0
+#: view:mail.message.subtype:0
+msgid "Subtype"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Group Form"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,starred:0
+#: field:mail.message,starred:0
+#: field:mail.notification,starred:0
+msgid "Starred"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:313
+#, python-format
+msgid "more messages"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/update.py:93
+#, python-format
+msgid "Error"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:13
+#, python-format
+msgid "Following"
+msgstr ""
+
+#. module: mail
+#: sql_constraint:mail.alias:0
+msgid ""
+"Unfortunately this email alias is already used, please choose a unique one"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_user_id:0
+msgid ""
+"The owner of records created upon receiving emails on this alias. If this "
+"field is not set the system will attempt to find the right owner based on "
+"the sender (From) address, or will use the Administrator account if no "
+"system user is found for that address."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:52
+#, python-format
+msgid "And"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,message_id:0
+#: field:mail.message,message_id:0
+msgid "Message-Id"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,image:0
+msgid ""
+"This field holds the image used as photo for the group, limited to "
+"1024x1024px."
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,attachment_ids:0
+#: view:mail.mail:0
+#: field:mail.message,attachment_ids:0
+msgid "Attachments"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,record_name:0
+#: field:mail.message,record_name:0
+msgid "Message Record Name"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,email_cc:0
+msgid "Cc"
+msgstr ""
+
+#. module: mail
+#: help:mail.notification,starred:0
+msgid "Starred message that goes into the todo mailbox"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:123
+#: view:mail.compose.message:0
+#, python-format
+msgid "Followers of"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,auto_delete:0
+msgid "Permanently delete this email after sending it, to save space"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_group_feeds
+msgid "Discussion Group"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:242
+#, python-format
+msgid "Done"
+msgstr ""
+
+#. module: mail
+#: model:mail.message.subtype,name:mail.mt_comment
+msgid "Discussions"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:11
+#, python-format
+msgid "Follow"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,name:0
+msgid "Name"
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_all_employees
+msgid "Whole Company"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:129
+#: code:addons/mail/static/src/xml/mail.xml:292
+#: view:mail.compose.message:0
+#, python-format
+msgid "and"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,body_html:0
+msgid "Rich-text/HTML message"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Creation Month"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:323
+#, python-format
+msgid "Compose new Message"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,menu_id:0
+msgid "Related Menu"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Content"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,email_to:0
+msgid "To"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,notified_partner_ids:0
+#: field:mail.message,notified_partner_ids:0
+msgid "Notified partners"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,public:0
+msgid ""
+"This group is visible by non members. Invisible groups can add "
+"members through the invite button."
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_board
+msgid "Board meetings"
+msgstr ""
+
+#. module: mail
+#: constraint:mail.alias:0
+msgid ""
+"Invalid expression, it must be a literal python dictionary definition e.g. "
+"\"{'field': 'value'}\""
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_model_id:0
+msgid "Aliased Model"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,message_id:0
+#: help:mail.message,message_id:0
+msgid "Message unique identifier"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,description:0
+#: field:mail.message.subtype,description:0
+msgid "Description"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_followers
+msgid "Document Followers"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:35
+#, python-format
+msgid "Remove this follower"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "Never"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,mail_server_id:0
+msgid "Outgoing mail server"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:930
+#, python-format
+msgid "Partners email addresses not found"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: selection:mail.mail,state:0
+msgid "Sent"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,body_html:0
+msgid "Rich-text Contents"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,to_read:0
+#: help:mail.message,to_read:0
+msgid "Current user has an unread notification linked to this message"
+msgstr ""
+
+#. module: mail
+#: help:res.partner,notification_email_send:0
+msgid ""
+"Choose in which case you want to receive an email when you receive new feeds."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_groups
+#: model:ir.ui.menu,name:mail.mail_allgroups
+msgid "Join a group"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_group_feeds
+msgid ""
+"
\n"
+" No message in this group.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:213
+#, python-format
+msgid "Please, wait while the file is uploading."
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid ""
+"This group is visible by everyone,\n"
+" including your customers if you "
+"installed\n"
+" the portal module."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:243
+#, python-format
+msgid "Set back to Todo"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:126
+#, python-format
+msgid "this document"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,filter_id:0
+msgid "Filters"
+msgstr ""
+
+#. module: mail
+#: field:res.partner,notification_email_send:0
+msgid "Receive Feeds by Email"
+msgstr ""
+
+#. module: mail
+#: help:base.config.settings,alias_domain:0
+msgid ""
+"If you have setup a catch-all email domain redirected to the OpenERP server, "
+"enter the domain name here."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_mail_message
+#: model:ir.ui.menu,name:mail.menu_mail_message
+#: field:mail.group,message_ids:0
+#: view:mail.message:0
+#: field:mail.thread,message_ids:0
+#: field:res.partner,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:139
+#, python-format
+msgid "others..."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_star_feeds
+#: model:ir.ui.menu,name:mail.mail_starfeeds
+msgid "To-do"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: field:mail.alias,alias_name:0
+#: field:mail.group,alias_id:0
+#: field:res.users,alias_id:0
+msgid "Alias"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_mail
+msgid "Outgoing Mails"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,notification_ids:0
+#: help:mail.message,notification_ids:0
+msgid ""
+"Technical field holding the message notifications. Use notified_partner_ids "
+"to access notified partners."
+msgstr ""
+
+#. module: mail
+#: model:ir.ui.menu,name:mail.mail_feeds
+#: model:ir.ui.menu,name:mail.mail_feeds_main
+msgid "Messaging"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: field:mail.message.subtype,res_model:0
+msgid "Model"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Unread"
+msgstr ""
+
+#. module: mail
+#: help:mail.followers,subtype_ids:0
+msgid ""
+"Message subtypes followed, meaning subtypes that will be pushed onto the "
+"user's Wall."
+msgstr ""
+
+#. module: mail
+#: help:mail.group,message_ids:0
+#: help:mail.thread,message_ids:0
+#: help:res.partner,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,references:0
+msgid "Message references, such as identifiers of previous messages"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,composition_mode:0
+msgid "Composition mode"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,model:0
+#: field:mail.followers,res_model:0
+#: field:mail.message,model:0
+#: field:mail.wizard.invite,res_model:0
+msgid "Related Document Model"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:338
+#, python-format
+msgid "unlike"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,author_id:0
+#: help:mail.message,author_id:0
+msgid ""
+"Author of the message. If not set, email_from may hold an email address that "
+"did not match any partner."
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,email_cc:0
+msgid "Carbon copy message recipients"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_domain:0
+msgid "Alias domain"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/update.py:93
+#, python-format
+msgid "Error during communication with the publisher warranty server."
+msgstr ""
+
+#. module: mail
+#: selection:mail.group,public:0
+msgid "Private"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_star_feeds
+msgid ""
+"
\n"
+" No todo.\n"
+"
\n"
+" When you process messages in your inbox, you can mark "
+"some\n"
+" as todo. From this menu, you can process all your "
+"todo.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: mail
+#: selection:mail.mail,state:0
+msgid "Delivery Failed"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,partner_ids:0
+msgid "Additional contacts"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,parent_id:0
+#: help:mail.message,parent_id:0
+msgid "Initial thread message."
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_hr_policies
+msgid "HR Policies"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "Emails only"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_inbox_feeds
+#: model:ir.ui.menu,name:mail.mail_inboxfeeds
+msgid "Inbox"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:58
+#, python-format
+msgid "File"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/many2many_tags_email.js:63
+#, python-format
+msgid "Please complete partner's informations and Email"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_message_subtype
+#: model:ir.ui.menu,name:mail.menu_message_subtype
+msgid "Subtypes"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_alias
+msgid "Email Aliases"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,image_small:0
+msgid "Small-sized photo"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,reply_to:0
+msgid "Preferred response address for the message"
+msgstr ""
diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py
index 9d96a6ff59c..ac350810aa6 100644
--- a/addons/mail/mail_followers.py
+++ b/addons/mail/mail_followers.py
@@ -151,7 +151,7 @@ class mail_notification(osv.Model):
return footer
def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None,
- force_send=False, user_signature=True):
+ force_send=False, user_signature=True):
""" Send by email the notification depending on the user preferences
:param list partners_to_notify: optional list of partner ids restricting
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
index d45ae04ddd1..b105d6677bd 100644
--- a/addons/mail/mail_mail.py
+++ b/addons/mail/mail_mail.py
@@ -44,7 +44,6 @@ class mail_mail(osv.Model):
_columns = {
'mail_message_id': fields.many2one('mail.message', 'Message', required=True, ondelete='cascade'),
- 'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
'state': fields.selection([
('outgoing', 'Outgoing'),
('sent', 'Sent'),
@@ -140,10 +139,16 @@ class mail_mail(osv.Model):
# notification field: if not set, set if mail comes from an existing mail.message
if 'notification' not in values and values.get('mail_message_id'):
values['notification'] = True
+ mail_id = super(mail_mail, self).create(cr, uid, values, context=context)
+
# reply_to: if not set, set with default values that require creation values
+ # but delegate after creation because of mail_message.message_id automatic
+ # creation using existence of reply_to
if not values.get('reply_to'):
- values['reply_to'] = self._get_reply_to(cr, uid, values, context=context)
- return super(mail_mail, self).create(cr, uid, values, context=context)
+ reply_to = self._get_reply_to(cr, uid, values, context=context)
+ if reply_to:
+ self.write(cr, uid, [mail_id], {'reply_to': reply_to}, context=context)
+ return mail_id
def unlink(self, cr, uid, ids, context=None):
# cascade-delete the parent message for all mails that are not created for a notification
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index df8ced65177..88faae22982 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -191,6 +191,7 @@ class mail_message(osv.Model):
'vote_user_ids': fields.many2many('res.users', 'mail_vote',
'message_id', 'user_id', string='Votes',
help='Users that voted for this message'),
+ 'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
}
def _needaction_domain_get(self, cr, uid, context=None):
@@ -395,15 +396,21 @@ class mail_message(osv.Model):
has_voted = uid in [user.id for user in message.vote_user_ids]
try:
- body_html = html_email_clean(message.body)
+ if parent_id:
+ max_length = 300
+ else:
+ max_length = 100
+ body_short = html_email_clean(message.body, remove=False, shorten=True, max_length=max_length)
+
except Exception:
- body_html = '
Encoding Error : Unable to convert this message (id: %s).
' % message.id
+ body_short = '
Encoding Error : Unable to convert this message (id: %s).
' % message.id
_logger.exception(Exception)
return {'id': message.id,
'type': message.type,
'subtype': message.subtype_id.name if message.subtype_id else False,
- 'body': body_html,
+ 'body': message.body,
+ 'body_short': body_short,
'model': message.model,
'res_id': message.res_id,
'record_name': message.record_name,
@@ -781,8 +788,8 @@ class mail_message(osv.Model):
values['message_id'] = tools.generate_tracking_message_id('private')
newid = super(mail_message, self).create(cr, uid, values, context)
self._notify(cr, uid, newid, context=context,
- force_send=context.get('mail_notify_force_send', True),
- user_signature=context.get('mail_notify_user_signature', True))
+ force_send=context.get('mail_notify_force_send', True),
+ user_signature=context.get('mail_notify_user_signature', True))
# TDE FIXME: handle default_starred. Why not setting an inv on starred ?
# Because starred will call set_message_starred, that looks for notifications.
# When creating a new mail_message, it will create a notification to a message
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 306e5fd5905..94e9126f020 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -682,6 +682,12 @@ class mail_thread(osv.AbstractModel):
assert thread_id == 0, 'Routing: posting a message without model should be with a null res_id (private message).'
_warn('posting a message without model should be with a null res_id (private message), resetting thread_id')
thread_id = 0
+ # Private message: should have a parent_id (only answers)
+ if not model and not message_dict.get('parent_id'):
+ if assert_model:
+ assert message_dict.get('parent_id'), 'Routing: posting a message without model should be with a parent_id (private mesage).'
+ _warn('posting a message without model should be with a parent_id (private mesage), skipping')
+ return ()
# Existing Document: check if exists; if not, fallback on create if allowed
if thread_id and not model_pool.exists(cr, uid, thread_id):
@@ -695,7 +701,7 @@ class mail_thread(osv.AbstractModel):
return ()
# Existing Document: check model accepts the mailgateway
- if thread_id and not hasattr(model_pool, 'message_update'):
+ if thread_id and model and not hasattr(model_pool, 'message_update'):
if create_fallback:
_warn('model %s does not accept document update, fall back on document creation' % model)
thread_id = None
@@ -706,7 +712,7 @@ class mail_thread(osv.AbstractModel):
return ()
# New Document: check model accepts the mailgateway
- if not thread_id and not hasattr(model_pool, 'message_new'):
+ if not thread_id and model and not hasattr(model_pool, 'message_new'):
if assert_model:
assert hasattr(model_pool, 'message_new'), 'Model %s does not accept document creation, crashing' % model
_warn('model %s does not accept document creation, skipping' % model)
@@ -798,16 +804,16 @@ class mail_thread(osv.AbstractModel):
# 2. Reply to a private message
if in_reply_to:
- message_ids = self.pool.get('mail.message').search(cr, uid, [
+ mail_message_ids = self.pool.get('mail.message').search(cr, uid, [
('message_id', '=', in_reply_to),
'!', ('message_id', 'ilike', 'reply_to')
], limit=1, context=context)
- if message_ids:
- message = self.pool.get('mail.message').browse(cr, uid, message_ids[0], context=context)
+ if mail_message_ids:
+ mail_message = self.pool.get('mail.message').browse(cr, uid, mail_message_ids[0], context=context)
_logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s',
- email_from, email_to, message_id, message.id, custom_values, uid)
+ email_from, email_to, message_id, mail_message.id, custom_values, uid)
route = self.message_route_verify(cr, uid, message, message_dict,
- (message.model, message.res_id, custom_values, uid, None),
+ (mail_message.model, mail_message.res_id, custom_values, uid, None),
update_author=True, assert_model=True, create_fallback=True, context=context)
return route and [route] or []
diff --git a/addons/mail/static/lib/jquery.expander/jquery.expander.js b/addons/mail/static/lib/jquery.expander/jquery.expander.js
deleted file mode 100644
index 91cc03db918..00000000000
--- a/addons/mail/static/lib/jquery.expander/jquery.expander.js
+++ /dev/null
@@ -1,385 +0,0 @@
-/*!
- * jQuery Expander Plugin v1.4.2
- *
- * Date: Fri Mar 16 14:29:56 2012 EDT
- * Requires: jQuery v1.3+
- *
- * Copyright 2011, Karl Swedberg
- * Dual licensed under the MIT and GPL licenses (just like jQuery):
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- *
- *
- *
-*/
-
-(function($) {
- $.expander = {
- version: '1.4.2',
- defaults: {
- // the number of characters at which the contents will be sliced into two parts.
- slicePoint: 100,
-
- // whether to keep the last word of the summary whole (true) or let it slice in the middle of a word (false)
- preserveWords: true,
-
- // a threshold of sorts for whether to initially hide/collapse part of the element's contents.
- // If after slicing the contents in two there are fewer words in the second part than
- // the value set by widow, we won't bother hiding/collapsing anything.
- widow: 4,
-
- // text displayed in a link instead of the hidden part of the element.
- // clicking this will expand/show the hidden/collapsed text
- expandText: 'read more',
- expandPrefix: '… ',
-
- expandAfterSummary: false,
-
- // class names for summary element and detail element
- summaryClass: 'summary',
- detailClass: 'details',
-
- // class names for around "read-more" link and "read-less" link
- moreClass: 'read-more',
- lessClass: 'read-less',
-
- // number of milliseconds after text has been expanded at which to collapse the text again.
- // when 0, no auto-collapsing
- collapseTimer: 0,
-
- // effects for expanding and collapsing
- expandEffect: 'fadeIn',
- expandSpeed: 250,
- collapseEffect: 'fadeOut',
- collapseSpeed: 200,
-
- // allow the user to re-collapse the expanded text.
- userCollapse: true,
-
- // text to use for the link to re-collapse the text
- userCollapseText: 'read less',
- userCollapsePrefix: ' ',
-
-
- // all callback functions have the this keyword mapped to the element in the jQuery set when .expander() is called
-
- onSlice: null, // function() {}
- beforeExpand: null, // function() {},
- afterExpand: null, // function() {},
- onCollapse: null // function(byUser) {}
- }
- };
-
- $.fn.expander = function(options) {
- var meth = 'init';
-
- if (typeof options == 'string') {
- meth = options;
- options = {};
- }
-
- var opts = $.extend({}, $.expander.defaults, options),
- rSelfClose = /^<(?:area|br|col|embed|hr|img|input|link|meta|param).*>$/i,
- rAmpWordEnd = opts.wordEnd || /(&(?:[^;]+;)?|[a-zA-Z\u00C0-\u0100]+)$/,
- rOpenCloseTag = /<\/?(\w+)[^>]*>/g,
- rOpenTag = /<(\w+)[^>]*>/g,
- rCloseTag = /<\/(\w+)>/g,
- rLastCloseTag = /(<\/[^>]+>)\s*$/,
- rTagPlus = /^<[^>]+>.?/,
- delayedCollapse;
-
- var methods = {
- init: function() {
- this.each(function() {
- var i, l, tmp, newChar, summTagless, summOpens, summCloses,
- lastCloseTag, detailText, detailTagless,
- $thisDetails, $readMore,
- openTagsForDetails = [],
- closeTagsForsummaryText = [],
- defined = {},
- thisEl = this,
- $this = $(this),
- $summEl = $([]),
- o = $.meta ? $.extend({}, opts, $this.data()) : opts,
- hasDetails = !!$this.find('.' + o.detailClass).length,
- hasBlocks = !!$this.find('*').filter(function() {
- var display = $(this).css('display');
- return (/^block|table|list/).test(display);
- }).length,
- el = hasBlocks ? 'div' : 'span',
- detailSelector = el + '.' + o.detailClass,
- moreSelector = 'span.' + o.moreClass,
- expandSpeed = o.expandSpeed || 0,
- allHtml = $.trim( $this.html() ),
- allText = $.trim( $this.text() ),
- summaryText = allHtml.slice(0, o.slicePoint);
-
- // bail out if we've already set up the expander on this element
- if ( $.data(this, 'expander') ) {
- return;
- }
-
- $.data(this, 'expander', true);
-
- // determine which callback functions are defined
- $.each(['onSlice','beforeExpand', 'afterExpand', 'onCollapse'], function(index, val) {
- defined[val] = $.isFunction(o[val]);
- });
-
- // back up if we're in the middle of a tag or word
- summaryText = backup(summaryText);
-
- // summary text sans tags length
- summTagless = summaryText.replace(rOpenCloseTag, '').length;
-
- // add more characters to the summary, one for each character in the tags
- while (summTagless < o.slicePoint) {
- newChar = allHtml.charAt(summaryText.length);
- if (newChar == '<') {
- newChar = allHtml.slice(summaryText.length).match(rTagPlus)[0];
- }
- summaryText += newChar;
- summTagless++;
- }
-
- summaryText = backup(summaryText, o.preserveWords);
-
- // separate open tags from close tags and clean up the lists
- summOpens = summaryText.match(rOpenTag) || [];
- summCloses = summaryText.match(rCloseTag) || [];
-
- // filter out self-closing tags
- tmp = [];
- $.each(summOpens, function(index, val) {
- if ( !rSelfClose.test(val) ) {
- tmp.push(val);
- }
- });
- summOpens = tmp;
-
- // strip close tags to just the tag name
- l = summCloses.length;
- for (i = 0; i < l; i++) {
- summCloses[i] = summCloses[i].replace(rCloseTag, '$1');
- }
-
- // tags that start in summary and end in detail need:
- // a). close tag at end of summary
- // b). open tag at beginning of detail
- $.each(summOpens, function(index, val) {
- var thisTagName = val.replace(rOpenTag, '$1');
- var closePosition = $.inArray(thisTagName, summCloses);
- if (closePosition === -1) {
- openTagsForDetails.push(val);
- closeTagsForsummaryText.push('' + thisTagName + '>');
-
- } else {
- summCloses.splice(closePosition, 1);
- }
- });
-
- // reverse the order of the close tags for the summary so they line up right
- closeTagsForsummaryText.reverse();
-
- // create necessary summary and detail elements if they don't already exist
- if ( !hasDetails ) {
-
- // end script if there is no detail text or if detail has fewer words than widow option
- detailText = allHtml.slice(summaryText.length);
- detailTagless = $.trim( detailText.replace(rOpenCloseTag, '') );
-
- if ( detailTagless === '' || detailTagless.split(/\s+/).length < o.widow ) {
- return;
- }
- // otherwise, continue...
- lastCloseTag = closeTagsForsummaryText.pop() || '';
- summaryText += closeTagsForsummaryText.join('');
- detailText = openTagsForDetails.join('') + detailText;
-
- } else {
- // assume that even if there are details, we still need readMore/readLess/summary elements
- // (we already bailed out earlier when readMore el was found)
- // but we need to create els differently
-
- // remove the detail from the rest of the content
- detailText = $this.find(detailSelector).remove().html();
-
- // The summary is what's left
- summaryText = $this.html();
-
- // allHtml is the summary and detail combined (this is needed when content has block-level elements)
- allHtml = summaryText + detailText;
-
- lastCloseTag = '';
- }
- o.moreLabel = $this.find(moreSelector).length ? '' : buildMoreLabel(o);
-
- if (hasBlocks) {
- detailText = allHtml;
- }
- summaryText += lastCloseTag;
-
- // onSlice callback
- o.summary = summaryText;
- o.details = detailText;
- o.lastCloseTag = lastCloseTag;
-
- if (defined.onSlice) {
- // user can choose to return a modified options object
- // one last chance for user to change the options. sneaky, huh?
- // but could be tricky so use at your own risk.
- tmp = o.onSlice.call(thisEl, o);
-
- // so, if the returned value from the onSlice function is an object with a details property, we'll use that!
- o = tmp && tmp.details ? tmp : o;
- }
-
- // build the html with summary and detail and use it to replace old contents
- var html = buildHTML(o, hasBlocks);
-
- $this.html( html );
-
- // set up details and summary for expanding/collapsing
- $thisDetails = $this.find(detailSelector);
- $readMore = $this.find(moreSelector);
- $thisDetails.hide();
- $readMore.find('a').unbind('click.expander').bind('click.expander', expand);
-
- $summEl = $this.find('div.' + o.summaryClass);
-
- if ( o.userCollapse && !$this.find('span.' + o.lessClass).length ) {
- $this
- .find(detailSelector)
- .append('' + o.userCollapsePrefix + '' + o.userCollapseText + '');
- }
-
- $this
- .find('span.' + o.lessClass + ' a')
- .unbind('click.expander')
- .bind('click.expander', function(event) {
- event.preventDefault();
- clearTimeout(delayedCollapse);
- var $detailsCollapsed = $(this).closest(detailSelector);
- reCollapse(o, $detailsCollapsed);
- if (defined.onCollapse) {
- o.onCollapse.call(thisEl, true);
- }
- });
-
- function expand(event) {
- event.preventDefault();
- $readMore.hide();
- $summEl.hide();
- if (defined.beforeExpand) {
- o.beforeExpand.call(thisEl);
- }
-
- $thisDetails.stop(false, true)[o.expandEffect](expandSpeed, function() {
- $thisDetails.css({zoom: ''});
- if (defined.afterExpand) {o.afterExpand.call(thisEl);}
- delayCollapse(o, $thisDetails, thisEl);
- });
- }
-
- }); // this.each
- },
- destroy: function() {
- if ( !this.data('expander') ) {
- return;
- }
- this.removeData('expander');
- this.each(function() {
- var $this = $(this),
- o = $.meta ? $.extend({}, opts, $this.data()) : opts,
- details = $this.find('.' + o.detailClass).contents();
-
- $this.find('.' + o.moreClass).remove();
- $this.find('.' + o.summaryClass).remove();
- $this.find('.' + o.detailClass).after(details).remove();
- $this.find('.' + o.lessClass).remove();
-
- });
- }
- };
-
- // run the methods (almost always "init")
- if ( methods[meth] ) {
- methods[ meth ].call(this);
- }
-
- // utility functions
- function buildHTML(o, blocks) {
- var el = 'span',
- summary = o.summary;
- if ( blocks ) {
- el = 'div';
- // if summary ends with a close tag, tuck the moreLabel inside it
- if ( rLastCloseTag.test(summary) && !o.expandAfterSummary) {
- summary = summary.replace(rLastCloseTag, o.moreLabel + '$1');
- } else {
- // otherwise (e.g. if ends with self-closing tag) just add moreLabel after summary
- // fixes #19
- summary += o.moreLabel;
- }
-
- // and wrap it in a div
- summary = '