From 045b9019ef70d3fa2df0acb6ea3fd112c06bf7bb Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 9 Nov 2015 14:17:51 +0530 Subject: [PATCH 01/19] [FIX] base_import_module: CSRF handling * disabled CSRF protection for login route * return CSRF token from login and retransmit it during module upload ``deploy`` only sends CSRF token if given one by authenticate so that the command can be used for non-updated modules. Closes #9488 --- addons/base_import_module/controllers/main.py | 6 ++++-- openerp/cli/deploy.py | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/addons/base_import_module/controllers/main.py b/addons/base_import_module/controllers/main.py index 0d2cdc1ab5b..4b51e69f096 100644 --- a/addons/base_import_module/controllers/main.py +++ b/addons/base_import_module/controllers/main.py @@ -21,7 +21,7 @@ class ImportModule(Controller): if not is_admin: raise openerp.exceptions.AccessError("Only administrators can upload a module") - @route('/base_import_module/login', type='http', auth='none', methods=['POST']) + @route('/base_import_module/login', type='http', auth='none', methods=['POST'], csrf=False) @webservice def login(self, login, password, db=None): if db and db != request.db: @@ -30,7 +30,9 @@ class ImportModule(Controller): if not uid: return Response(response="Wrong login/password", status=401) self.check_user(uid) - return "ok" + return Response(headers={ + 'X-CSRF-TOKEN': request.csrf_token(), + }) @route('/base_import_module/upload', type='http', auth='user', methods=['POST']) @webservice diff --git a/openerp/cli/deploy.py b/openerp/cli/deploy.py index 7c5e9536c0c..2e97d838ec2 100644 --- a/openerp/cli/deploy.py +++ b/openerp/cli/deploy.py @@ -17,21 +17,24 @@ class Deploy(Command): def deploy_module(self, module_path, url, login, password, db='', force=False): url = url.rstrip('/') - self.authenticate(url, login, password, db) + csrf_token = self.authenticate(url, login, password, db) module_file = self.zip_module(module_path) try: - return self.upload_module(url, module_file, force=force) + return self.upload_module(url, module_file, force=force, csrf_token=csrf_token) finally: os.remove(module_file) - def upload_module(self, server, module_file, force=False): + def upload_module(self, server, module_file, force=False, csrf_token=None): print("Uploading module file...") url = server + '/base_import_module/upload' - files = dict(mod_file=open(module_file, 'rb')) - force = '1' if force else '' - res = self.session.post(url, files=files, data=dict(force=force)) - if res.status_code != 200: - raise Exception("Could not authenticate on server '%s'" % server) + + post_data = {'force': '1' if force else ''} + if csrf_token: post_data['csrf_token'] = csrf_token + + with open(module_file, 'rb') as f: + res = self.session.post(url, files={'mod_file': f}, data=post_data) + res.raise_for_status() + return res.text def authenticate(self, server, login, password, db=''): @@ -47,6 +50,8 @@ class Deploy(Command): elif res.status_code != 200: raise Exception(res.text) + return res.headers.get('x-csrf-token') + def zip_module(self, path): path = os.path.abspath(path) if not os.path.isdir(path): From 3c86d74941351df8af2e6113fd461c5ff95d59c9 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 09:31:48 +0100 Subject: [PATCH 02/19] [FIX] product_email_template: untranslated label String instead of string, was not exported. Missing "Invoice Confirmation Email" term. --- .../i18n/product_email_template.pot | 11 ++++++++--- addons/product_email_template/views/product_view.xml | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/addons/product_email_template/i18n/product_email_template.pot b/addons/product_email_template/i18n/product_email_template.pot index 8789e6c6893..85d43a1cd35 100644 --- a/addons/product_email_template/i18n/product_email_template.pot +++ b/addons/product_email_template/i18n/product_email_template.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-09-07 14:41+0000\n" -"PO-Revision-Date: 2015-09-07 14:41+0000\n" +"POT-Creation-Date: 2016-01-13 08:24+0000\n" +"PO-Revision-Date: 2016-01-13 08:24+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -657,6 +657,11 @@ msgstr "" msgid "Invoice" msgstr "" +#. module: product_email_template +#: model:ir.ui.view,arch_db:product_email_template.product_template_form_view +msgid "Invoice Confirmation Email" +msgstr "" + #. module: product_email_template #: model:ir.ui.view,arch_db:product_email_template.product_template_form_view msgid "Miscellaneous" diff --git a/addons/product_email_template/views/product_view.xml b/addons/product_email_template/views/product_view.xml index 5d7f17ab6ff..f2699e90f97 100644 --- a/addons/product_email_template/views/product_view.xml +++ b/addons/product_email_template/views/product_view.xml @@ -11,7 +11,7 @@ - Date: Wed, 13 Jan 2016 10:04:48 +0100 Subject: [PATCH 04/19] [FIX] mail: missing terms Please people, stop changing the terms every week... --- addons/mail/i18n/mail.pot | 97 ++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/addons/mail/i18n/mail.pot b/addons/mail/i18n/mail.pot index fae4c77ded0..cf41fec77f9 100644 --- a/addons/mail/i18n/mail.pot +++ b/addons/mail/i18n/mail.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-10 13:38+0000\n" -"PO-Revision-Date: 2015-12-10 13:38+0000\n" +"POT-Creation-Date: 2016-01-13 08:52+0000\n" +"PO-Revision-Date: 2016-01-13 08:52+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -41,7 +41,7 @@ msgid "\n" " % endif\n" "\n" " % if not ctx.get('button_access') and not ctx.get('button_follow') and not ctx.get('button_unfollow') and ctx.get('model_name'):\n" -"

\n" +"

\n" " About ${ctx['model_name']}\n" " % if ctx.get('record_name'):\n" " : ${ctx['record_name']}\n" @@ -55,7 +55,7 @@ msgid "\n" " % if ctx.get('actions'):\n" " % for action in ctx['actions']:\n" " ${action['title']}\n" -" %if len(ctx['actions']) > 1 and loop.index < len(ctx['actions']):\n" +" %if cmp(len(ctx['actions']), 1) == 1 and cmp(len(ctx['actions']), loop.index) == 1:\n" " |\n" " % endif\n" " % endfor\n" @@ -69,8 +69,9 @@ msgid "\n" " \n" " % endif\n" " using\n" -" Odoo\n" +" Odoo\n" " % endif\n" +"

\n" " \n" " \n" " \n" @@ -94,7 +95,7 @@ msgid "\n" " % if ctx.get('tracking'):\n" "
    \n" " % for tracking in ctx['tracking']\n" -"
  • ${tracking[0]} : ${tracking[1]} -> ${tracking[2]}
  • \n" +"
  • ${tracking[0]} : ${tracking[1]} -> ${tracking[2]}
  • \n" " % endfor\n" "
\n" " % endif\n" @@ -112,12 +113,13 @@ msgid "\n" " \n" " \n" "\n" -"% endif" +"% endif\n" +"" msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/js/chat_manager.js:50 +#: code:addons/mail/static/src/js/chat_manager.js:53 #, python-format msgid " from " msgstr "" @@ -199,7 +201,7 @@ msgstr "" #. module: mail #: code:addons/mail/wizard/invite.py:22 #, python-format -msgid "

Hello,

%s invited you to follow %s document: %s.

" +msgid "

Hello,

%s invited you to follow %s document: %s.

" msgstr "" #. module: mail @@ -535,6 +537,13 @@ msgstr "" msgid "Available for mass mailing" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/chatter.xml:162 +#, python-format +msgid "Be careful with channels following internal notifications" +msgstr "" + #. module: mail #: model:ir.model.fields,field_description:mail.field_email_template_preview_body_html #: model:ir.model.fields,field_description:mail.field_ir_act_server_body_html @@ -792,16 +801,11 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/js/client_action.js:217 +#: code:addons/mail/static/src/js/client_action.js:250 #, python-format msgid "Create %s" msgstr "" -#. module: mail -#: model:ir.model.fields,field_description:mail.field_mail_channel_create_date -msgid "Create Date" -msgstr "" - #. module: mail #: model:ir.model.fields,field_description:mail.field_email_template_preview_create_uid #: model:ir.model.fields,field_description:mail.field_mail_alias_create_uid @@ -821,6 +825,7 @@ msgstr "" #. module: mail #: model:ir.model.fields,field_description:mail.field_email_template_preview_create_date #: model:ir.model.fields,field_description:mail.field_mail_alias_create_date +#: model:ir.model.fields,field_description:mail.field_mail_channel_create_date #: model:ir.model.fields,field_description:mail.field_mail_channel_partner_create_date #: model:ir.model.fields,field_description:mail.field_mail_compose_message_create_date #: model:ir.model.fields,field_description:mail.field_mail_mail_create_date @@ -1039,11 +1044,6 @@ msgstr "" msgid "Email Search" msgstr "" -#. module: mail -#: model:ir.model.fields,field_description:mail.field_mail_channel_email_send -msgid "Email Sent" -msgstr "" - #. module: mail #: model:ir.model.fields,field_description:mail.field_ir_act_server_template_id msgid "Email Template" @@ -1345,6 +1345,13 @@ msgstr "" msgid "Id of the followed resource" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:108 +#, python-format +msgid "Idle" +msgstr "" + #. module: mail #: model:ir.model.fields,help:mail.field_mail_channel_message_unread #: model:ir.model.fields,help:mail.field_mail_thread_message_unread @@ -2014,6 +2021,20 @@ msgid "Odoo helps you easily track all activities related to\n" " documents, etc." msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:11 +#, python-format +msgid "Odoo needs your permission to" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:109 +#, python-format +msgid "Offline" +msgstr "" + #. module: mail #: model:ir.model.fields,field_description:mail.field_mail_tracking_value_old_value_char msgid "Old Value Char" @@ -2046,11 +2067,18 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/js/chatter.js:230 +#: code:addons/mail/static/src/js/chatter.js:218 #, python-format msgid "One follower" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:107 +#, python-format +msgid "Online" +msgstr "" + #. module: mail #: selection:mail.channel.partner,fold_state:0 msgid "Open" @@ -2516,11 +2544,16 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/chatter.xml:72 +#: code:addons/mail/static/src/xml/chatter.xml:67 #, python-format msgid "Send a message" msgstr "" +#. module: mail +#: model:ir.model.fields,field_description:mail.field_mail_channel_email_send +msgid "Send messages by email" +msgstr "" + #. module: mail #: model:ir.model.fields,help:mail.field_email_template_preview_email_from #: model:ir.model.fields,help:mail.field_ir_act_server_email_from @@ -2528,6 +2561,13 @@ msgstr "" msgid "Sender address (placeholders may be used here). If not set, the default value will be the author's email alias if configured, or email address." msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:94 +#, python-format +msgid "Sends messages by email" +msgstr "" + #. module: mail #: model:ir.ui.view,arch_db:mail.view_mail_search #: selection:mail.mail,state:0 @@ -2639,12 +2679,15 @@ msgid "Sub-model" msgstr "" #. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/composer.xml:8 #: model:ir.model.fields,field_description:mail.field_email_template_preview_subject #: model:ir.model.fields,field_description:mail.field_ir_act_server_subject #: model:ir.model.fields,field_description:mail.field_mail_compose_message_subject #: model:ir.model.fields,field_description:mail.field_mail_mail_subject #: model:ir.model.fields,field_description:mail.field_mail_message_subject #: model:ir.model.fields,field_description:mail.field_mail_template_subject +#, python-format msgid "Subject" msgstr "" @@ -3098,16 +3141,16 @@ msgid "by" msgstr "" #. module: mail -#. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:33 +#: code:addons/mail/models/mail_thread.py:312 #, python-format -msgid "dm" +msgid "document" msgstr "" #. module: mail -#: code:addons/mail/models/mail_thread.py:313 +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:11 #, python-format -msgid "document" +msgid "enable desktop notifications" msgstr "" #. module: mail From 2bfb880503ba9f0177747aea3da38b8bbeccbe02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 12 Jan 2016 17:12:22 +0100 Subject: [PATCH 05/19] [FIX] mail: auto delete Correctly set the auto delete property coming from the template in the composer. Set the mail_auto_delete context key for message_post, and directly set the auto_delete field value in mass mailing mode. --- addons/mail/wizard/mail_compose_message.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 6ea72c16ed5..59a1f6cac08 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -216,8 +216,8 @@ class MailComposer(models.TransientModel): if wizard.template_id: # template user_signature is added when generating body_html # mass mailing: use template auto_delete value -> note, for emails mass mailing only - Mail = Mail.with_context(mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete, mail_server_id=wizard.template_id.mail_server_id.id) - ActiveModel = ActiveModel.with_context(mail_notify_user_signature=False) + Mail = Mail.with_context(mail_notify_user_signature=False, mail_server_id=wizard.template_id.mail_server_id.id) + ActiveModel = ActiveModel.with_context(mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete) if not hasattr(ActiveModel, 'message_post'): ActiveModel = self.env['mail.thread'].with_context(thread_model=wizard.model) if wizard.composition_mode == 'mass_post': @@ -288,8 +288,8 @@ class MailComposer(models.TransientModel): # always keep a copy, reset record name (avoid browsing records) mail_values.update(notification=True, model=self.model, res_id=res_id, record_name=False) # auto deletion of mail_mail - if 'mail_auto_delete' in self._context: - mail_values['auto_delete'] = self._context.get('mail_auto_delete') + if self.template_id and self.template_id.auto_delete: + mail_values['auto_delete'] = True # rendered values using template email_dict = rendered_values[res_id] mail_values['partner_ids'] += email_dict.pop('partner_ids', []) From fd57dd5713b5a8af68f5fac0c50f058681da0880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 12 Jan 2016 13:14:01 +0100 Subject: [PATCH 06/19] [IMP] mail: chatter: hide notification buttons Using some templates it is possible to have odoo buttons directly in the mail_message body. Hide them in the chatter as this is more noisy than usefull. --- addons/mail/static/src/less/thread.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/mail/static/src/less/thread.less b/addons/mail/static/src/less/thread.less index f2971dcf17e..e523e6ffe2d 100644 --- a/addons/mail/static/src/less/thread.less +++ b/addons/mail/static/src/less/thread.less @@ -111,6 +111,10 @@ color: gray; } + [summary~=o_mail_notification] { // name conflicts with channel notifications, but is odoo notification buttons to hide in chatter if present + display: none; + } + > p { margin: 0 0 9px; // Required by the old design to override a general rule on p's &:last-child { From 17424bd4c8cb0fdf8a63c601633eaa9deeebb8e9 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 12 Jan 2016 16:48:46 +0100 Subject: [PATCH 07/19] [FIX] web: reload view on fail after write/create with action button Issue: Invoicing -> Vendor bills Create a record with reference=0 -> Register Payment Create a second record with reference=0, at least one line with at least one tax -> Save Edit -> change quantity in the line -> Register Payment -> the register fail change the quantity again and change reference=1 -> Register Payment The taxes is include twice --- addons/web/static/src/js/views/form_widgets.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/views/form_widgets.js b/addons/web/static/src/js/views/form_widgets.js index 96107503a5f..4d39d8df806 100644 --- a/addons/web/static/src/js/views/form_widgets.js +++ b/addons/web/static/src/js/views/form_widgets.js @@ -81,7 +81,6 @@ var WidgetButton = common.FormWidget.extend({ }, on_confirmed: function() { var self = this; - var context = this.build_context(); return this.view.do_execute_action( _.extend({}, this.node.attrs, {context: context}), @@ -89,6 +88,8 @@ var WidgetButton = common.FormWidget.extend({ if (!_.isObject(reason)) { self.view.recursive_reload(); } + }).fail(function () { + self.view.recursive_reload(); }); }, check_disable: function() { From f962f0ecc41edb1371c38dd38fad76b7a5c5a50c Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 10:49:29 +0100 Subject: [PATCH 08/19] [FIX] stock: missing terms Added a related field. --- addons/stock/i18n/stock.pot | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index dad94c6f1b4..aaa9409a5cc 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-11-05 14:22+0000\n" -"PO-Revision-Date: 2015-11-05 14:22+0000\n" +"POT-Creation-Date: 2016-01-13 09:40+0000\n" +"PO-Revision-Date: 2016-01-13 09:40+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -3185,12 +3185,6 @@ msgstr "" msgid "Messages" msgstr "" -#. module: stock -#: model:ir.model.fields,help:stock.field_stock_picking_message_ids -#: model:ir.model.fields,help:stock.field_stock_production_lot_message_ids -msgid "Messages and communication history" -msgstr "" - #. module: stock #: model:ir.model.fields,field_description:stock.field_product_putaway_method #: model:ir.model.fields,field_description:stock.field_product_removal_method @@ -5749,6 +5743,11 @@ msgstr "" msgid "Transfer" msgstr "" +#. module: stock +#: model:ir.model.fields,field_description:stock.field_stock_move_picking_partner_id +msgid "Transfer Destination Address" +msgstr "" + #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_move_picking_id msgid "Transfer Reference" From 780b36abe9267c8d74600820543fac849507e394 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 11:42:16 +0100 Subject: [PATCH 09/19] [FIX] hr_timesheet_sheet: missing terms Action act_hr_timesheet_sheet_my_timesheets was not translated --- .../i18n/hr_timesheet_sheet.pot | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/addons/hr_timesheet_sheet/i18n/hr_timesheet_sheet.pot b/addons/hr_timesheet_sheet/i18n/hr_timesheet_sheet.pot index 99621c03b3e..8d00b412eae 100644 --- a/addons/hr_timesheet_sheet/i18n/hr_timesheet_sheet.pot +++ b/addons/hr_timesheet_sheet/i18n/hr_timesheet_sheet.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-09-18 08:11+0000\n" -"PO-Revision-Date: 2015-09-18 08:11+0000\n" +"POT-Creation-Date: 2016-01-13 10:41+0000\n" +"PO-Revision-Date: 2016-01-13 10:41+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -368,11 +368,6 @@ msgstr "" msgid "Messages" msgstr "" -#. module: hr_timesheet_sheet -#: model:ir.model.fields,help:hr_timesheet_sheet.field_hr_timesheet_sheet_sheet_message_ids -msgid "Messages and communication history" -msgstr "" - #. module: hr_timesheet_sheet #: selection:res.company,timesheet_range:0 msgid "Month" @@ -390,6 +385,12 @@ msgstr "" msgid "My Timesheet opens your timesheet so that you can book your activities into the system. From the same form, you can register your attendances (Sign In/Out) and describe the working hours made on the different projects. At the end of the period defined in the company, the timesheet is confirmed by the user and can be validated by his manager. If required, as defined on the project, you can generate the invoices based on the timesheet." msgstr "" +#. module: hr_timesheet_sheet +#: model:ir.actions.act_window,name:hr_timesheet_sheet.act_hr_timesheet_sheet_my_timesheets +#: model:ir.ui.menu,name:hr_timesheet_sheet.menu_act_hr_timesheet_sheet_my_timesheets +msgid "My Timesheets" +msgstr "" + #. module: hr_timesheet_sheet #: selection:hr.timesheet.report,state:0 #: selection:hr_timesheet_sheet.sheet,state:0 @@ -610,6 +611,7 @@ msgstr "" #. module: hr_timesheet_sheet #: model:ir.actions.act_window,help:hr_timesheet_sheet.act_hr_timesheet_sheet_form +#: model:ir.actions.act_window,help:hr_timesheet_sheet.act_hr_timesheet_sheet_my_timesheets msgid "Timesheets can also be invoiced to customers, depending on the\n" " configuration of each project's related contract." msgstr "" @@ -759,26 +761,27 @@ msgid "You cannot have 2 timesheets that overlap!\n" msgstr "" #. module: hr_timesheet_sheet -#: code:addons/hr_timesheet_sheet/hr_timesheet_sheet.py:66 +#: code:addons/hr_timesheet_sheet/hr_timesheet_sheet.py:72 #, python-format msgid "You cannot have 2 timesheets that overlap!\n" "You should use the menu 'My Timesheet' to avoid this problem." msgstr "" #. module: hr_timesheet_sheet -#: code:addons/hr_timesheet_sheet/hr_timesheet_sheet.py:480 +#: code:addons/hr_timesheet_sheet/hr_timesheet_sheet.py:494 #, python-format msgid "You cannot modify an entry in a confirmed timesheet" msgstr "" #. module: hr_timesheet_sheet -#: code:addons/hr_timesheet_sheet/hr_timesheet_sheet.py:343 +#: code:addons/hr_timesheet_sheet/hr_timesheet_sheet.py:353 #, python-format msgid "You cannot modify an entry in a confirmed timesheet." msgstr "" #. module: hr_timesheet_sheet #: model:ir.actions.act_window,help:hr_timesheet_sheet.act_hr_timesheet_sheet_form +#: model:ir.actions.act_window,help:hr_timesheet_sheet.act_hr_timesheet_sheet_my_timesheets msgid "You must record timesheets every day and confirm at the end\n" " of the week. Once the timesheet is confirmed, it should be\n" " validated by a manager." @@ -796,6 +799,11 @@ msgstr "" msgid "hr.timesheet.current.open" msgstr "" +#. module: hr_timesheet_sheet +#: model:ir.actions.act_window,help:hr_timesheet_sheet.act_hr_timesheet_sheet_my_timesheets +msgid "new timesheet." +msgstr "" + #. module: hr_timesheet_sheet #: model:ir.ui.view,arch_db:hr_timesheet_sheet.hr_timesheet_sheet_form msgid "to" From c287d38f5f640fd50aa72d7dfba5499efb50c746 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 12:13:46 +0100 Subject: [PATCH 10/19] [FIX] ...: untranslated selection When using a method returning the list of selections, the labels needs to be translated with a _ call --- addons/barcodes/barcodes.py | 2 +- addons/barcodes/i18n/barcodes.pot | 6 ++++++ addons/product/i18n/product.pot | 12 ++++++++++++ addons/product/product.py | 2 +- addons/stock/i18n/stock.pot | 6 ++++++ addons/stock/product.py | 2 +- .../i18n/website_sale_digital.pot | 6 ++++++ addons/website_sale_digital/product.py | 2 +- 8 files changed, 34 insertions(+), 4 deletions(-) diff --git a/addons/barcodes/barcodes.py b/addons/barcodes/barcodes.py index 5a780657c1a..8f9c6769bcc 100644 --- a/addons/barcodes/barcodes.py +++ b/addons/barcodes/barcodes.py @@ -180,7 +180,7 @@ class barcode_rule(models.Model): @api.model def _encoding_selection_list(self): return [ - ('any', 'Any'), + ('any', _('Any')), ('ean13', 'EAN-13'), ('ean8', 'EAN-8'), ('upca', 'UPC-A'), diff --git a/addons/barcodes/i18n/barcodes.pot b/addons/barcodes/i18n/barcodes.pot index 4d07aa7df22..5018c7b5270 100644 --- a/addons/barcodes/i18n/barcodes.pot +++ b/addons/barcodes/i18n/barcodes.pot @@ -72,6 +72,12 @@ msgstr "" msgid "An internal identification of the barcode nomenclature" msgstr "" +#. module: barcodes +#: code:addons/barcodes/barcodes.py:183 +#, python-format +msgid "Any" +msgstr "" + #. module: barcodes #: model:ir.model.fields,field_description:barcodes.field_barcode_rule_barcode_nomenclature_id #: model:ir.ui.view,arch_db:barcodes.view_barcode_nomenclature_form diff --git a/addons/product/i18n/product.pot b/addons/product/i18n/product.pot index 85a37b94f1e..493de6613d3 100644 --- a/addons/product/i18n/product.pot +++ b/addons/product/i18n/product.pot @@ -648,6 +648,12 @@ msgstr "" msgid "Computers" msgstr "" +#. module: product +#: code:addons/product/product.py:460 +#, python-format +msgid "Consumable" +msgstr "" + #. module: product #: model:ir.model.fields,help:product.field_product_uom_category_id msgid "Conversion between Units of Measure can only occur if they belong to the same category. The conversion will be made based on the ratios." @@ -2394,6 +2400,12 @@ msgstr "" msgid "Server" msgstr "" +#. module: product +#: code:addons/product/product.py:460 +#, python-format +msgid "Service" +msgstr "" + #. module: product #: model:ir.ui.view,arch_db:product.product_template_search_view #: model:product.category,name:product.product_category_3 diff --git a/addons/product/product.py b/addons/product/product.py index c8fa9b8a8b1..0bc1ec3de85 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -457,7 +457,7 @@ class product_template(osv.osv): return [x['product_tmpl_id'][0] for x in r] def _get_product_template_type(self, cr, uid, context=None): - return [('consu', 'Consumable'), ('service', 'Service')] + return [('consu', _('Consumable')), ('service', _('Service'))] _get_product_template_type_wrapper = lambda self, *args, **kwargs: self._get_product_template_type(*args, **kwargs) _columns = { diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index aaa9409a5cc..4cfb78af2f2 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -5233,6 +5233,12 @@ msgstr "" msgid "Stockable" msgstr "" +#. module: stock +#: code:addons/stock/product.py:400 +#, python-format +msgid "Stockable Product" +msgstr "" + #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_location_route_supplied_wh_id msgid "Supplied Warehouse" diff --git a/addons/stock/product.py b/addons/stock/product.py index edf63baa840..6d348e54d68 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -397,7 +397,7 @@ class product_template(osv.osv): def _get_product_template_type(self, cr, uid, context=None): res = super(product_template, self)._get_product_template_type(cr, uid, context=context) if 'product' not in [item[0] for item in res]: - res.append(('product', 'Stockable Product')) + res.append(('product', _('Stockable Product'))) return res _columns = { diff --git a/addons/website_sale_digital/i18n/website_sale_digital.pot b/addons/website_sale_digital/i18n/website_sale_digital.pot index e3e2d31a410..8e2683e9f98 100644 --- a/addons/website_sale_digital/i18n/website_sale_digital.pot +++ b/addons/website_sale_digital/i18n/website_sale_digital.pot @@ -32,6 +32,12 @@ msgstr "" msgid "Digital Attachments" msgstr "" +#. module: website_sale_digital +#: code:addons/website_sale_digital/product.py:22 +#, python-format +msgid "Digital Content" +msgstr "" + #. module: website_sale_digital #: model:ir.ui.view,arch_db:website_sale_digital.orders_followup_downloads msgid "Downloads " diff --git a/addons/website_sale_digital/product.py b/addons/website_sale_digital/product.py index 8262d31d94e..54852cd9c74 100644 --- a/addons/website_sale_digital/product.py +++ b/addons/website_sale_digital/product.py @@ -19,7 +19,7 @@ class product_template(models.Model): def _get_product_template_type(self): res = super(product_template, self)._get_product_template_type() if 'digital' not in [item[0] for item in res]: - res.append(('digital', 'Digital Content')) + res.append(('digital', _('Digital Content'))) return res @api.multi From 2ace8f0270b26eae08c6fd6814605326de28da43 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 13:48:03 +0100 Subject: [PATCH 11/19] [FIX] forum: duplicated method Identical method, written another way. Properly check the translated error. --- addons/website_forum/models/forum.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 629cf0e125f..eaf99a7811a 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -137,13 +137,7 @@ class Forum(models.Model): if (self.default_post_type == 'question' and not self.allow_question) \ or (self.default_post_type == 'discussion' and not self.allow_discussion) \ or (self.default_post_type == 'link' and not self.allow_link): - raise UserError(_('You cannot choose %s as default post since the forum does not allow it.' % self.default_post_type)) - - @api.one - @api.constrains('allow_link', 'allow_question', 'allow_discussion', 'default_post_type') - def _check_default_post_type(self): - if self.default_post_type == 'link' and not self.allow_link or self.default_post_type == 'question' and not self.allow_question or self.default_post_type == 'discussion' and not self.allow_discussion: - raise Warning(_('Post type in "Default post" must be activated')) + raise UserError(_('You cannot choose %s as default post since the forum does not allow it.') % self.default_post_type) @api.one def _compute_count_posts_waiting_validation(self): From bb56e484b767aa037ec697dd11b0bd865ec31db1 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 14:31:02 +0100 Subject: [PATCH 12/19] [FIX] all: construction of translations lookup When evaluated, the translation function never finds a match if a variable is integrated into the untranslated text. SHAME! :bell: :raising_hand: --- addons/account/models/account_move.py | 2 +- addons/account/models/account_payment.py | 2 +- .../account_check_printing/account_journal.py | 2 +- .../report/account_test_report.py | 2 +- addons/anonymization/anonymization.py | 8 +++---- addons/auth_signup/controllers/main.py | 2 +- addons/base_iban/base_iban.py | 2 +- addons/base_vat/base_vat.py | 2 +- addons/calendar/calendar.py | 4 ++-- addons/gamification/models/challenge.py | 4 ++-- addons/gamification/models/goal.py | 2 +- addons/google_account/google_account.py | 12 +++++----- addons/google_account/i18n/google_account.pot | 24 ++++++++++++++++--- addons/google_calendar/google_calendar.py | 8 +++---- addons/sale/sale_analytic.py | 2 +- addons/stock/stock.py | 4 ++-- .../wizard/survey_email_compose_message.py | 2 +- addons/website/models/website.py | 6 ++--- addons/website_blog/models/website_blog.py | 2 +- addons/website_forum/models/forum.py | 20 ++++++---------- addons/website_slides/controllers/main.py | 6 ++--- openerp/models.py | 4 ++-- openerp/tools/translate.py | 2 +- 23 files changed, 68 insertions(+), 56 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 2ecbd523a9c..24eb0312a48 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -172,7 +172,7 @@ class AccountMove(models.Model): if self.user_has_groups('account.group_account_manager'): lock_date = move.company_id.fiscalyear_lock_date if move.date <= lock_date: - raise UserError(_("You cannot add/modify entries prior to and inclusive of the lock date %s. Check the company settings or ask someone with the 'Adviser' role" % (lock_date))) + raise UserError(_("You cannot add/modify entries prior to and inclusive of the lock date %s. Check the company settings or ask someone with the 'Adviser' role") % (lock_date)) return True @api.multi diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py index 7195170a86a..5ea2b0bfd23 100644 --- a/addons/account/models/account_payment.py +++ b/addons/account/models/account_payment.py @@ -118,7 +118,7 @@ class account_register_payments(models.TransientModel): if not active_model or not active_ids: raise UserError(_("Programmation error: wizard action executed without active_model or active_ids in context.")) if active_model != 'account.invoice': - raise UserError(_("Programmation error: the expected model for this action is 'account.invoice'. The provided one is '%d'." % active_model)) + raise UserError(_("Programmation error: the expected model for this action is 'account.invoice'. The provided one is '%d'.") % active_model) # Checks on received invoice records invoices = self.env[active_model].browse(active_ids) diff --git a/addons/account_check_printing/account_journal.py b/addons/account_check_printing/account_journal.py index 03ad48bd8cf..7470787d322 100644 --- a/addons/account_check_printing/account_journal.py +++ b/addons/account_check_printing/account_journal.py @@ -23,7 +23,7 @@ class AccountJournal(models.Model): def _set_check_next_number(self): if self.check_next_number < self.check_sequence_id.number_next_actual: raise ValidationError(_("The last check number was %s. In order to avoid a check being rejected " - "by the bank, you can only use a greater number." % self.check_sequence_id.number_next_actual)) + "by the bank, you can only use a greater number.") % self.check_sequence_id.number_next_actual) if self.check_sequence_id: self.check_sequence_id.sudo().number_next_actual = self.check_next_number diff --git a/addons/account_test/report/account_test_report.py b/addons/account_test/report/account_test_report.py index 208fec8152a..16a06622c09 100644 --- a/addons/account_test/report/account_test_report.py +++ b/addons/account_test/report/account_test_report.py @@ -53,7 +53,7 @@ class ReportAssertAccount(models.AbstractModel): return ', '.join(["%s: %s" % (tup[0], tup[1]) for tup in order_columns(item, column_order)]) else: return item - result = [_(_format(rec)) for rec in result] + result = [_format(rec) for rec in result] return result diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py index 581a5d8f586..5ad6f8eea42 100644 --- a/addons/anonymization/anonymization.py +++ b/addons/anonymization/anonymization.py @@ -72,7 +72,7 @@ class ir_model_fields_anonymization(osv.osv): if global_state == 'anonymized': raise UserError(_("The database is currently anonymized, you cannot create, modify or delete fields.")) elif global_state == 'unstable': - msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \ + msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," " while some fields are not anonymized. You should try to solve this problem before trying to create, write or delete fields.") raise UserError(msg) @@ -339,7 +339,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): # remove the placeholer: eview.remove(placeholder) else: - msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \ + msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," " while some fields are not anonymized. You should try to solve this problem before trying to do anything else.") raise UserError(msg) @@ -372,7 +372,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): if state == 'anonymized': self._raise_after_history_update(cr, uid, history_id, _('Error !'), _("The database is currently anonymized, you cannot anonymize it again.")) elif state == 'unstable': - msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \ + msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," " while some fields are not anonymized. You should try to solve this problem before trying to do anything.") self._raise_after_history_update(cr, uid, history_id, 'Error !', msg) @@ -509,7 +509,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): if state == 'clear': raise UserError(_("The database is not currently anonymized, you cannot reverse the anonymization.")) elif state == 'unstable': - msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \ + msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," " while some fields are not anonymized. You should try to solve this problem before trying to do anything.") raise UserError(msg) diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index b508514617f..0092754e627 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -66,7 +66,7 @@ class AuthSignupHome(openerp.addons.web.controllers.main.Home): qcontext['error'] = _("Could not reset your password") _logger.exception('error when resetting password') except Exception, e: - qcontext['error'] = _(e.message) + qcontext['error'] = e.message return request.render('auth_signup.reset_password', qcontext) diff --git a/addons/base_iban/base_iban.py b/addons/base_iban/base_iban.py index 8468fa12f67..0877c264333 100644 --- a/addons/base_iban/base_iban.py +++ b/addons/base_iban/base_iban.py @@ -32,7 +32,7 @@ def validate_iban(iban): iban_template = _map_iban_template[country_code] if len(iban) != len(iban_template.replace(' ', '')): raise ValidationError(_("The IBAN does not seem to be correct. You should have entered something like this %s\n"\ - "Where B = National bank code, S = Branch code, C = Account No, k = Check digit" % iban_template)) + "Where B = National bank code, S = Branch code, C = Account No, k = Check digit") % iban_template) check_chars = iban[4:] + iban[:4] digits = int(''.join(str(int(char, 36)) for char in check_chars)) # BASE 36: 0..9,A..Z -> 0..35 diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index 887c6560618..9e1dcba46e4 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -108,7 +108,7 @@ class res_partner(osv.osv): continue vat_country, vat_number = self._split_vat(partner.vat) if not check_func(cr, uid, vat_country, vat_number, context=context): - _logger.info(_("Importing VAT Number [%s] is not valid !" % vat_number)) + _logger.info("Importing VAT Number [%s] is not valid !", vat_number) return False return True diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index 35c1db56bab..8686d62b4d4 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -260,7 +260,7 @@ class calendar_attendee(osv.Model): meeting_obj = self.pool['calendar.event'] res = self.write(cr, uid, ids, {'state': 'accepted'}, context) for attendee in self.browse(cr, uid, ids, context=context): - meeting_obj.message_post(cr, uid, attendee.event_id.id, body=_(("%s has accepted invitation") % (attendee.cn)), + meeting_obj.message_post(cr, uid, attendee.event_id.id, body=_("%s has accepted invitation") % (attendee.cn), subtype="calendar.subtype_invitation", context=context) return res @@ -275,7 +275,7 @@ class calendar_attendee(osv.Model): meeting_obj = self.pool['calendar.event'] res = self.write(cr, uid, ids, {'state': 'declined'}, context) for attendee in self.browse(cr, uid, ids, context=context): - meeting_obj.message_post(cr, uid, attendee.event_id.id, body=_(("%s has declined invitation") % (attendee.cn)), subtype="calendar.subtype_invitation", context=context) + meeting_obj.message_post(cr, uid, attendee.event_id.id, body=_("%s has declined invitation") % (attendee.cn), subtype="calendar.subtype_invitation", context=context) return res def create(self, cr, uid, vals, context=None): diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py index f10be1eee18..f05f2ea3a65 100644 --- a/addons/gamification/models/challenge.py +++ b/addons/gamification/models/challenge.py @@ -737,11 +737,11 @@ class gamification_challenge(osv.Model): if challenge_ended: # open chatter message - message_body = _("The challenge %s is finished." % challenge.name) + message_body = _("The challenge %s is finished.") % challenge.name if rewarded_users: user_names = self.pool['res.users'].name_get(cr, uid, rewarded_users, context=context) - message_body += _("
Reward (badge %s) for every succeeding user was sent to %s." % (challenge.reward_id.name, ", ".join([name for (user_id, name) in user_names]))) + message_body += _("
Reward (badge %s) for every succeeding user was sent to %s.") % (challenge.reward_id.name, ", ".join([name for (user_id, name) in user_names])) else: message_body += _("
Nobody has succeeded to reach every goal, no badge is rewarded for this challenge.") diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 2903814f9ba..2f307e03ca0 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -130,7 +130,7 @@ class gamification_goal_definition(osv.Model): obj.search(cr, uid, domain, context=context, count=True) except (ValueError, SyntaxError), e: msg = e.message or (e.msg + '\n' + e.text) - raise UserError(_("The domain for the definition %s seems incorrect, please check it.\n\n%s" % (definition.name, msg))) + raise UserError(_("The domain for the definition %s seems incorrect, please check it.\n\n%s") % (definition.name, msg)) return True def create(self, cr, uid, vals, context=None): diff --git a/addons/google_account/google_account.py b/addons/google_account/google_account.py index 53c02e08ad3..9142dc67638 100644 --- a/addons/google_account/google_account.py +++ b/addons/google_account/google_account.py @@ -34,8 +34,8 @@ class google_service(osv.osv_memory): req = urllib2.Request("https://accounts.google.com/o/oauth2/token", data, headers) content = urllib2.urlopen(req, timeout=TIMEOUT).read() except urllib2.HTTPError: - error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired" - raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context) + error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired") + raise self.pool.get('res.config.settings').get_config_warning(cr, error_msg, context=context) content = json.loads(content) return content.get('refresh_token') @@ -95,8 +95,8 @@ class google_service(osv.osv_memory): st, res, ask_time = self._do_request(cr, uid, uri, params=data, headers=headers, type='POST', preuri='', context=context) except urllib2.HTTPError: - error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid" - raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context) + error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid") + raise self.pool.get('res.config.settings').get_config_warning(cr, error_msg, context=context) return res def _refresh_google_token_json(self, cr, uid, refresh_token, service, context=None): # exchange_AUTHORIZATION vs Token (service = calendar) @@ -125,8 +125,8 @@ class google_service(osv.osv_memory): self.pool['res.users'].write(cur, uid, [uid], {'google_%s_rtoken' % service: False}, context=context) error_key = json.loads(e.read()).get("error", "nc") _logger.exception("Bad google request : %s !" % error_key) - error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]" % error_key - raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context) + error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]") % error_key + raise self.pool.get('res.config.settings').get_config_warning(cr, error_msg, context=context) return res def _do_request(self, cr, uid, uri, params={}, headers={}, type='POST', preuri="https://www.googleapis.com", context=None): diff --git a/addons/google_account/i18n/google_account.pot b/addons/google_account/i18n/google_account.pot index ed9115b97e1..459efa8553a 100644 --- a/addons/google_account/i18n/google_account.pot +++ b/addons/google_account/i18n/google_account.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-09-07 14:40+0000\n" -"PO-Revision-Date: 2015-09-07 14:40+0000\n" +"POT-Creation-Date: 2016-01-13 13:41+0000\n" +"PO-Revision-Date: 2016-01-13 13:41+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -50,6 +50,24 @@ msgstr "" msgid "Last Updated on" msgstr "" +#. module: google_account +#: code:addons/google_account/google_account.py:98 +#, python-format +msgid "Something went wrong during your token generation. Maybe your Authorization Code is invalid" +msgstr "" + +#. module: google_account +#: code:addons/google_account/google_account.py:37 +#, python-format +msgid "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired" +msgstr "" + +#. module: google_account +#: code:addons/google_account/google_account.py:128 +#, python-format +msgid "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]" +msgstr "" + #. module: google_account #: code:addons/google_account/google_account.py:173 #, python-format diff --git a/addons/google_calendar/google_calendar.py b/addons/google_calendar/google_calendar.py index 33acda6b82d..2d444c41b10 100644 --- a/addons/google_calendar/google_calendar.py +++ b/addons/google_calendar/google_calendar.py @@ -295,13 +295,13 @@ class google_calendar(osv.AbstractModel): st, content, ask_time = self.pool['google.service']._do_request(cr, uid, url, params, headers, type='GET', context=context) except urllib2.HTTPError, e: if e.code == 401: # Token invalid / Acces unauthorized - error_msg = "Your token is invalid or has been revoked !" + error_msg = _("Your token is invalid or has been revoked !") registry = openerp.modules.registry.RegistryManager.get(request.session.db) with registry.cursor() as cur: self.pool['res.users'].write(cur, SUPERUSER_ID, [uid], {'google_calendar_token': False, 'google_calendar_token_validity': False}, context=context) - raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context) + raise self.pool.get('res.config.settings').get_config_warning(cr, error_msg, context=context) raise return (status_response(st), content['id'] or False, ask_time) @@ -699,8 +699,8 @@ class google_calendar(osv.AbstractModel): self.pool['res.users'].write(cur, SUPERUSER_ID, [uid], {'google_calendar_last_sync_date': False}, context=context) error_key = json.loads(str(e)) error_key = error_key.get('error', {}).get('message', 'nc') - error_msg = "Google is lost... the next synchro will be a full synchro. \n\n %s" % error_key - raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context) + error_msg = _("Google is lost... the next synchro will be a full synchro. \n\n %s") % error_key + raise self.pool.get('res.config.settings').get_config_warning(cr, error_msg, context=context) my_google_att_ids = att_obj.search(cr, uid, [ ('partner_id', '=', myPartnerID), diff --git a/addons/sale/sale_analytic.py b/addons/sale/sale_analytic.py index cc7de3a1a98..9261c5c4208 100644 --- a/addons/sale/sale_analytic.py +++ b/addons/sale/sale_analytic.py @@ -52,7 +52,7 @@ class AccountAnalyticLine(models.Model): if not order: return False if order.state != 'sale': - raise UserError(_('The Sale Order %s linked to the Analytic Account must be validated before registering expenses.' % order.name)) + raise UserError(_('The Sale Order %s linked to the Analytic Account must be validated before registering expenses.') % order.name) last_so_line = self.env['sale.order.line'].search([('order_id', '=', order.id)], order='sequence desc', limit=1) last_sequence = last_so_line.sequence + 1 if last_so_line else 100 diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 270261e7ea7..193cf6bcef3 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -529,7 +529,7 @@ class stock_quant(osv.osv): elif removal_strategy == 'lifo': order = 'in_date desc, id desc' return self._quants_get_order(cr, uid, quantity, move, ops=ops, domain=domain, orderby=order, context=context) - raise UserError(_('Removal strategy %s not implemented.' % (removal_strategy,))) + raise UserError(_('Removal strategy %s not implemented.') % (removal_strategy,)) def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location_from=False, force_location_to=False, context=None): @@ -2952,7 +2952,7 @@ class stock_inventory(osv.osv): for inv in self.browse(cr, uid, ids, context=context): for inventory_line in inv.line_ids: if inventory_line.product_qty < 0 and inventory_line.product_qty != inventory_line.theoretical_qty: - raise UserError(_('You cannot set a negative product quantity in an inventory line:\n\t%s - qty: %s' % (inventory_line.product_id.name, inventory_line.product_qty))) + raise UserError(_('You cannot set a negative product quantity in an inventory line:\n\t%s - qty: %s') % (inventory_line.product_id.name, inventory_line.product_qty)) self.action_check(cr, uid, [inv.id], context=context) self.write(cr, uid, [inv.id], {'state': 'done'}, context=context) self.post_inventory(cr, uid, inv, context=context) diff --git a/addons/survey/wizard/survey_email_compose_message.py b/addons/survey/wizard/survey_email_compose_message.py index 0272ad0444c..55e326b3750 100644 --- a/addons/survey/wizard/survey_email_compose_message.py +++ b/addons/survey/wizard/survey_email_compose_message.py @@ -75,7 +75,7 @@ class survey_mail_compose_message(osv.TransientModel): else: emails_checked.append(email) if error_message: - raise UserError(_("One email at least is incorrect: %s" % error_message)) + raise UserError(_("One email at least is incorrect: %s") % error_message) emails_checked.sort() values = {'multi_email': '\n'.join(emails_checked)} diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 93d9080e4fd..4aa3deb1d4c 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -290,12 +290,12 @@ class website(osv.osv): for page in View.browse(cr, uid, pages, context=context): if page.page: dep[page_key].append({ - 'text': _('Page %s seems to have a link to this page !' % page.key), + 'text': _('Page %s seems to have a link to this page !') % page.key, 'link': '/page/%s' % page.key }) else: dep[page_key].append({ - 'text': _('Template %s (id:%s) seems to have a link to this page !' % (page.key, page.id)), + 'text': _('Template %s (id:%s) seems to have a link to this page !') % (page.key, page.id), 'link': '#' }) @@ -311,7 +311,7 @@ class website(osv.osv): dep[menu_key] = [] for menu in Menu.browse(cr, uid, menus, context=context): dep[menu_key].append({ - 'text': _('Menu %s seems to have a link to this page !' % menu.name), + 'text': _('Menu %s seems to have a link to this page !') % menu.name, 'link': False }) diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index cb2743b9652..d3d8569a3b1 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -289,7 +289,7 @@ class Website(osv.Model): dep[page_key] = [] for p in post_obj.browse(cr, uid, posts, context=context): dep[page_key].append({ - 'text': _('Blog Post %s seems to have a link to this page !' % p.name), + 'text': _('Blog Post %s seems to have a link to this page !') % p.name, 'link': p.website_url }) diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index eaf99a7811a..91569312d10 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -374,7 +374,7 @@ class Post(models.Model): if (self.post_type == 'question' and not self.forum_id.allow_question) \ or (self.post_type == 'discussion' and not self.forum_id.allow_discussion) \ or (self.post_type == 'link' and not self.forum_id.allow_link): - raise UserError(_('This forum does not allow %s' % self.post_type)) + raise UserError(_('This forum does not allow %s') % self.post_type) def _update_content(self, content, forum_id): forum = self.env['forum.forum'].browse(forum_id) @@ -473,26 +473,20 @@ class Post(models.Model): base_url = self.env['ir.config_parameter'].get_param('web.base.url') for post in self: if post.state == 'active' and post.parent_id: - body = _( - '

A new answer for %s has been posted. Click here to access the post.

' % - (post.parent_id.name, base_url, slug(post.parent_id.forum_id), slug(post.parent_id)) - ) + body = _('

A new answer for %s has been posted. Click here to access the post.

') % \ + (post.parent_id.name, base_url, slug(post.parent_id.forum_id), slug(post.parent_id)) post.parent_id.message_post(subject=_('Re: %s') % post.parent_id.name, body=body, subtype='website_forum.mt_answer_new') elif post.state == 'active' and not post.parent_id: - body = _( - '

A new question %s has been asked on %s. Click here to access the question.

' % - (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post)) - ) + body = _('

A new question %s has been asked on %s. Click here to access the question.

') % \ + (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post)) post.message_post(subject=post.name, body=body, subtype='website_forum.mt_question_new') elif post.state == 'pending' and not post.parent_id: # TDE FIXME: in master, you should probably use a subtype; # however here we remove subtype but set partner_ids partners = post.sudo().message_partner_ids.filtered(lambda partner: partner.user_ids and partner.user_ids.karma >= post.forum_id.karma_moderate) note_subtype = self.sudo().env.ref('mail.mt_note') - body = _( - '

A new question %s has been asked on %s and require your validation. Click here to access the question.

' % - (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post)) - ) + body = _('

A new question %s has been asked on %s and require your validation. Click here to access the question.

') % \ + (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post)) post.message_post(subject=post.name, body=body, subtype_id=note_subtype.id, partner_ids=partners.ids) return True diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 6190bbc675b..ecb6520b4d7 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -282,11 +282,11 @@ class website_slides(http.Controller): return preview existing_slide = Slide.search([('channel_id', '=', int(data['channel_id'])), ('document_id', '=', document_id)], limit=1) if existing_slide: - preview['error'] = _('This video already exists in this channel click here to view it ' % existing_slide.id) + preview['error'] = _('This video already exists in this channel click here to view it ') % existing_slide.id return preview values = Slide._parse_document_url(data['url'], only_preview_fields=True) if values.get('error'): - preview['error'] = _('Could not fetch data from url. Document or access right not available.\nHere is the received response: %s' % values['error']) + preview['error'] = _('Could not fetch data from url. Document or access right not available.\nHere is the received response: %s') % values['error'] return preview return values @@ -318,7 +318,7 @@ class website_slides(http.Controller): return {'error': e.name} except Exception as e: _logger.error(e) - return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s' % e.message)} + return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s') % e.message} return {'url': "/slides/slide/%s" % (slide_id.id)} # -------------------------------------------------- diff --git a/openerp/models.py b/openerp/models.py index ba42955eb42..679eb269672 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -673,7 +673,7 @@ class BaseModel(object): (fnct, fields2, order) = spec length = None else: - raise UserError(_('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority, time length)}.' % (fname, cls._name))) + raise UserError(_('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority, time length)}.') % (fname, cls._name)) pool._store_function.setdefault(model, []) t = (cls._name, fname, fnct, tuple(fields2) if fields2 else None, order, length) if t not in pool._store_function[model]: @@ -1266,7 +1266,7 @@ class BaseModel(object): res_msg = trans._get_source(self._name, 'constraint', self.env.lang, msg) if extra_error: res_msg += "\n\n%s\n%s" % (_('Error details:'), extra_error) - errors.append(_(res_msg)) + errors.append(res_msg) if errors: raise ValidationError('\n'.join(errors)) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 2ee09b12982..04022058318 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -664,7 +664,7 @@ def trans_export(lang, modules, buffer, format, cr): else: raise Exception(_('Unrecognized extension: must be one of ' - '.csv, .po, or .tgz (received .%s).' % format)) + '.csv, .po, or .tgz (received .%s).') % format) translations = trans_generate(lang, modules, cr) modules = set(t[0] for t in translations) From dbd02552284d0e947f881a60254f2fc988a1f615 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Wed, 13 Jan 2016 11:41:00 +0100 Subject: [PATCH 13/19] [FIX] website_theme_install: language dependant code The module did only work in english because the themes were found amongst the applications thanks to their categorie names. Solution is to search categories thanks to their xml_id : base.module_category_theme or base.module_category_theme_... and not base.module_category_hidden or base.module_category_theme_hidden --- .../models/ir_module_module.py | 5 +++-- addons/website_theme_install/views/views.xml | 13 +++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/addons/website_theme_install/models/ir_module_module.py b/addons/website_theme_install/models/ir_module_module.py index 93c62acee0f..09258d3385e 100644 --- a/addons/website_theme_install/models/ir_module_module.py +++ b/addons/website_theme_install/models/ir_module_module.py @@ -37,10 +37,11 @@ class IrModuleModule(models.Model): @api.multi def button_choose_theme(self, context): + theme_category_id = self.env.ref('base.module_category_theme').id self.search([ # Uninstall the theme(s) which is (are) installed ('state', '=', 'installed'), - '|', ('category_id', '!=', 'Hidden'), ('name', '=', 'theme_default'), - '|', ('category_id', '=', 'Theme'), ('category_id.parent_id', '=', 'Theme') + '|', ('category_id', 'not in', [self.env.ref('base.module_category_hidden').id, self.env.ref('base.module_category_theme_hidden').id]), ('name', '=', 'theme_default'), + '|', ('category_id', '=', theme_category_id), ('category_id.parent_id', '=', theme_category_id) ]).button_immediate_uninstall(context=context) next_action = self.button_immediate_install(context=context) # Then install the new chosen one diff --git a/addons/website_theme_install/views/views.xml b/addons/website_theme_install/views/views.xml index 6e89a39d7be..dc08870c9a8 100644 --- a/addons/website_theme_install/views/views.xml +++ b/addons/website_theme_install/views/views.xml @@ -40,6 +40,11 @@
+ + + Hidden + + Choose Your Theme @@ -47,10 +52,10 @@ kanban - [ - '|', ('category_id', '!=', 'Hidden'), ('name', '=', 'theme_default'), - '|', ('category_id', '=', 'Theme'), ('category_id.parent_id', '=', 'Theme') - ] + Choose Your Theme Todo Action From ce2d94207bfef121b1a11ac2b7b9528f431670da Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 15:38:37 +0100 Subject: [PATCH 14/19] [FIX] mail,web: : untranslated term in view _t(...) in xml qweb views do not work, not exported, not evaluted. No reason to use t-att-*, just using simple attribute is enough. --- addons/mail/i18n/mail.pot | 130 +++++++--- addons/mail/static/src/xml/client_action.xml | 18 +- addons/mail/static/src/xml/systray.xml | 2 +- addons/mail/static/src/xml/thread.xml | 6 +- addons/web/i18n/web.pot | 257 +++++++++++++++---- addons/web/static/src/xml/base.xml | 2 +- 6 files changed, 306 insertions(+), 109 deletions(-) diff --git a/addons/mail/i18n/mail.pot b/addons/mail/i18n/mail.pot index cf41fec77f9..69aaafebfb2 100644 --- a/addons/mail/i18n/mail.pot +++ b/addons/mail/i18n/mail.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-13 08:52+0000\n" -"PO-Revision-Date: 2016-01-13 08:52+0000\n" +"POT-Creation-Date: 2016-01-13 14:27+0000\n" +"PO-Revision-Date: 2016-01-13 14:27+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -305,6 +305,13 @@ msgstr "" msgid "Activity" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:78 +#, python-format +msgid "Add" +msgstr "" + #. module: mail #. openerp-web #: code:addons/mail/static/src/xml/chatter.xml:144 @@ -930,14 +937,21 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:107 +#: code:addons/mail/static/src/xml/client_action.xml:124 #, python-format msgid "Detach" msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:35 +#: code:addons/mail/static/src/xml/client_action.xml:124 +#, python-format +msgid "Detach the conversation" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:42 #, python-format msgid "Direct Messages" msgstr "" @@ -1598,6 +1612,13 @@ msgstr "" msgid "Last Updated on" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:97 +#, python-format +msgid "Leave this channel" +msgstr "" + #. module: mail #: model:ir.model.fields,help:mail.field_mail_wizard_invite_channel_ids msgid "List of channels that will be added as listeners of the current document." @@ -1678,11 +1699,33 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:108 +#: code:addons/mail/static/src/xml/client_action.xml:125 +#, python-format +msgid "Mark all as read" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:125 #, python-format msgid "Mark all read" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/thread.xml:105 +#, python-format +msgid "Mark as Read" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/thread.xml:68 +#: code:addons/mail/static/src/xml/thread.xml:102 +#, python-format +msgid "Mark as Todo" +msgstr "" + #. module: mail #: model:ir.model.fields,field_description:mail.field_mail_channel_image_medium msgid "Medium-sized photo" @@ -1790,14 +1833,6 @@ msgstr "" msgid "Messages Search" msgstr "" -#. module: mail -#: model:ir.model.fields,help:mail.field_mail_channel_message_ids -#: model:ir.model.fields,help:mail.field_mail_thread_message_ids -#: model:ir.model.fields,help:mail.field_res_partner_message_ids -#: model:ir.model.fields,help:mail.field_res_users_message_ids -msgid "Messages and communication history" -msgstr "" - #. module: mail #: model:ir.model.fields,help:mail.field_mail_message_subtype_internal msgid "Messages with internal subtypes will be visible only by employees, aka members of base_user group" @@ -1980,6 +2015,13 @@ msgstr "" msgid "Notification" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/systray.xml:12 +#, python-format +msgid "Notifications" +msgstr "" + #. module: mail #: model:ir.model.fields,field_description:mail.field_mail_compose_message_notify msgid "Notify followers" @@ -2096,7 +2138,14 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:36 +#: code:addons/mail/static/src/xml/client_action.xml:128 +#, python-format +msgid "Open channel settings" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:46 #, python-format msgid "Open chat" msgstr "" @@ -2581,7 +2630,7 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/js/client_action.js:159 +#: code:addons/mail/static/src/xml/client_action.xml:128 #, python-format msgid "Settings" msgstr "" @@ -2852,11 +2901,18 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/js/thread.js:119 +#: code:addons/mail/static/src/js/thread.js:117 #, python-format msgid "Today" msgstr "" +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:122 +#, python-format +msgid "Toggle Channels" +msgstr "" + #. module: mail #: model:ir.ui.view,arch_db:mail.mail_channel_view_form msgid "Topics discussed in this group..." @@ -2950,21 +3006,35 @@ msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:109 +#: code:addons/mail/static/src/xml/client_action.xml:126 #, python-format msgid "Unstar all" msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:110 +#: code:addons/mail/static/src/xml/client_action.xml:126 +#, python-format +msgid "Unstar all messages" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/client_action.xml:127 #, python-format msgid "Unsubscribe" msgstr "" #. module: mail #. openerp-web -#: code:addons/mail/static/src/js/client_action.js:402 +#: code:addons/mail/static/src/xml/client_action.xml:127 +#, python-format +msgid "Unsubscribe from channel" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/client_action.js:425 #, python-format msgid "Unsubscribed" msgstr "" @@ -3200,20 +3270,6 @@ msgstr "" msgid "on" msgstr "" -#. module: mail -#. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:39 -#, python-format -msgid "private" -msgstr "" - -#. module: mail -#. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:21 -#, python-format -msgid "public" -msgstr "" - #. module: mail #: model:ir.model,name:mail.model_publisher_warranty_contract msgid "publisher_warranty.contract" @@ -3241,11 +3297,3 @@ msgstr "" msgid "this document" msgstr "" -#. module: mail -#. openerp-web -#: code:addons/mail/static/src/xml/client_action.xml:34 -#: code:addons/mail/static/src/xml/client_action.xml:35 -#, python-format -msgid "true" -msgstr "" - diff --git a/addons/mail/static/src/xml/client_action.xml b/addons/mail/static/src/xml/client_action.xml index da2e29057e0..ac60afc3e58 100644 --- a/addons/mail/static/src/xml/client_action.xml +++ b/addons/mail/static/src/xml/client_action.xml @@ -75,7 +75,7 @@

- +
@@ -94,7 +94,7 @@ + title="Leave this channel" t-att-data-channel-id="channel.id"/>
@@ -119,13 +119,13 @@
- - - - - - - + + + + + + +
diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml index 58a735e80c5..5318f30b3dd 100644 --- a/addons/mail/static/src/xml/systray.xml +++ b/addons/mail/static/src/xml/systray.xml @@ -9,7 +9,7 @@ -
  • +
  • diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index 0952fcf0e7f..fb7c5fa35e8 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -65,7 +65,7 @@ + t-att-data-message-id="message.id" title="Mark as Todo"/>
  • @@ -99,10 +99,10 @@ + t-att-data-message-id="message.id" title="Mark as Todo"/> + t-att-data-message-id="message.id" title="Mark as Read"/>

    diff --git a/addons/web/i18n/web.pot b/addons/web/i18n/web.pot index b2bb27eface..0414d335633 100644 --- a/addons/web/i18n/web.pot +++ b/addons/web/i18n/web.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 14:29+0000\n" -"PO-Revision-Date: 2015-10-12 14:29+0000\n" +"POT-Creation-Date: 2016-01-13 14:43+0000\n" +"PO-Revision-Date: 2016-01-13 14:43+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -179,6 +179,13 @@ msgstr "" msgid "(%d records)" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:106 +#, python-format +msgid "(Community Edition)" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/xml/base_common.xml:100 @@ -217,6 +224,14 @@ msgstr "" msgid "Odoo" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/widgets/user_menu.js:81 +#: code:addons/web/static/src/xml/base.xml:84 +#, python-format +msgid "About" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/framework/crash_manager.js:25 @@ -231,6 +246,13 @@ msgstr "" msgid "Access Error" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:1503 +#, python-format +msgid "Access to all Enterprise Apps" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/widgets/sidebar.js:24 @@ -254,72 +276,79 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:666 +#: code:addons/web/static/src/js/views/form_widgets.js:660 #, python-format msgid "Activate" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:663 +#: code:addons/web/static/src/xml/base.xml:96 +#, python-format +msgid "Activate the developer mode" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/form_widgets.js:657 #, python-format msgid "Active" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_relational_widgets.js:1357 -#: code:addons/web/static/src/xml/base.xml:1059 -#: code:addons/web/static/src/xml/base.xml:1299 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:1367 +#: code:addons/web/static/src/xml/base.xml:1110 +#: code:addons/web/static/src/xml/base.xml:1343 #, python-format msgid "Add" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1172 +#: code:addons/web/static/src/xml/base.xml:1216 #, python-format msgid "Add Custom Filter" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1173 +#: code:addons/web/static/src/xml/base.xml:1217 #, python-format msgid "Add a condition" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_relational_widgets.js:1006 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:1016 #, python-format msgid "Add an item" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1183 +#: code:addons/web/static/src/xml/base.xml:1227 #, python-format msgid "Add custom group" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:272 +#: code:addons/web/static/src/xml/base.xml:323 #, python-format msgid "Add..." msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_relational_widgets.js:1298 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:1308 #, python-format msgid "Add: " msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1079 +#: code:addons/web/static/src/xml/base.xml:1123 #, python-format msgid "Advanced Search..." msgstr "" @@ -333,22 +362,29 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:513 +#: code:addons/web/static/src/xml/base.xml:564 #, python-format msgid "All users" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1173 -#: code:addons/web/static/src/xml/base.xml:1193 +#: code:addons/web/static/src/xml/base.xml:1508 +#, python-format +msgid "And more" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:1217 +#: code:addons/web/static/src/xml/base.xml:1237 #, python-format msgid "Apply" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:670 +#: code:addons/web/static/src/js/views/form_widgets.js:664 #: code:addons/web/static/src/js/views/list_view.js:308 #, python-format msgid "Archive" @@ -370,32 +406,39 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:244 +#: code:addons/web/static/src/xml/base.xml:295 #, python-format msgid "Attachment :" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1283 +#: code:addons/web/static/src/xml/base.xml:1327 #, python-format msgid "Available fields" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:565 +#: code:addons/web/static/src/xml/base.xml:616 #, python-format msgid "Bar Chart" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/list_view.js:1946 +#: code:addons/web/static/src/js/views/list_view.js:1955 #, python-format msgid "Binary file" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:1507 +#, python-format +msgid "Bugfixes guarantee" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/xml/base_common.xml:97 @@ -516,22 +559,23 @@ msgstr "" msgid "Context:" msgstr "" -#: code:addons/web/static/src/xml/base.xml:80 -#: code:addons/web/static/src/xml/base_common.xml:159 +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:116 #, python-format msgid "Copyright © 2004-2015 Odoo S.A." msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:1351 +#: code:addons/web/static/src/js/views/form_widgets.js:1347 #, python-format msgid "Could not display the selected image." msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/list_view.js:1101 +#: code:addons/web/static/src/js/views/list_view.js:1110 #, python-format msgid "Could not find id in dataset" msgstr "" @@ -626,21 +670,28 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:624 +#: code:addons/web/static/src/xml/base.xml:110 +#, python-format +msgid "Database expiration:" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:675 #, python-format msgid "Day" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:664 +#: code:addons/web/static/src/js/views/form_widgets.js:658 #, python-format msgid "Deactivate" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:470 +#: code:addons/web/static/src/xml/base.xml:521 #, python-format msgid "Default:" msgstr "" @@ -698,6 +749,13 @@ msgstr "" msgid "Do you really want to remove these records?" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:82 +#, python-format +msgid "Documentation" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/xml/base_common.xml:63 @@ -949,18 +1007,25 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:1169 +#: code:addons/web/static/src/xml/base.xml:1213 #, python-format msgid "Filters" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:598 +#: code:addons/web/static/src/xml/base.xml:649 #, python-format msgid "Flip axis" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:119 +#, python-format +msgid "For more information visit" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/views/form_view.js:34 @@ -969,6 +1034,20 @@ msgstr "" msgid "Form" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:118 +#, python-format +msgid "GNU Lesser General Public License" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:1500 +#, python-format +msgid "Get this feature and much more with Odoo Enterprise!" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/framework/crash_manager.js:24 @@ -1051,41 +1130,48 @@ msgstr "" #. module: web #. openerp-web #: code:addons/web/static/src/js/widgets/debug_manager.js:106 -#: code:addons/web/static/src/xml/base.xml:165 +#: code:addons/web/static/src/xml/base.xml:211 #, python-format msgid "JS Tests" msgstr "" #. module: web -#: code:addons/web/controllers/main.py:845 +#: code:addons/web/controllers/main.py:769 #, python-format msgid "Languages" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:208 +#: code:addons/web/static/src/xml/base.xml:254 #, python-format msgid "Latest Modification Date:" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:204 +#: code:addons/web/static/src/xml/base.xml:250 #, python-format msgid "Latest Modification by:" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:177 +#: code:addons/web/static/src/xml/base.xml:223 #, python-format msgid "Leave Debug Mode" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:566 +#: code:addons/web/static/src/xml/base.xml:118 +#, python-format +msgid "Licenced under the terms of" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:617 #, python-format msgid "Line Chart" msgstr "" @@ -1211,6 +1297,13 @@ msgstr "" msgid "Missing Record" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:1505 +#, python-format +msgid "Mobile support" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/widgets/debug_manager.js:129 @@ -1314,6 +1407,13 @@ msgstr "" msgid "New Password:" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:1504 +#, python-format +msgid "New design" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/views/search_inputs.js:330 @@ -1428,6 +1528,13 @@ msgstr "" msgid "Odoo" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:101 +#, python-format +msgid "Odoo (Formerly OpenERP)" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/apps.js:189 @@ -1437,11 +1544,18 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:1678 +#: code:addons/web/static/src/js/views/form_widgets.js:1675 #, python-format msgid "Odoo Enterprise" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:117 +#, python-format +msgid "Odoo S.A." +msgstr "" + #. module: web #: model:ir.ui.view,arch_db:web.qunit_suite msgid "Odoo Web Tests" @@ -1449,7 +1563,21 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:677 +#: code:addons/web/static/src/xml/base.xml:117 +#, python-format +msgid "Odoo is a trademark of" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:119 +#, python-format +msgid "Odoo.com" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/form_widgets.js:671 #, python-format msgid "Off" msgstr "" @@ -1487,24 +1615,31 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/widgets/progress_bar.js:76 +#: code:addons/web/static/src/js/widgets/progress_bar.js:79 #, python-format msgid "Only Integer Value should be valid." msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:506 +#: code:addons/web/static/src/xml/base.xml:557 #, python-format msgid "Only you" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:198 +#, python-format +msgid "Open Debug Menu" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/views/form_relational_widgets.js:153 -#: code:addons/web/static/src/js/views/form_relational_widgets.js:924 -#: code:addons/web/static/src/js/views/form_relational_widgets.js:1088 -#: code:addons/web/static/src/js/views/form_relational_widgets.js:1314 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:928 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:1098 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:1324 #, python-format msgid "Open: " msgstr "" @@ -1856,14 +1991,21 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:676 +#: code:addons/web/static/src/xml/base.xml:83 +#, python-format +msgid "Support" +msgstr "" + +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/form_widgets.js:670 #, python-format msgid "Switch Off" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:678 +#: code:addons/web/static/src/js/views/form_widgets.js:672 #, python-format msgid "Switch On" msgstr "" @@ -2105,36 +2247,36 @@ msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/framework/data.js:1113 +#: code:addons/web/static/src/js/framework/data.js:1120 #, python-format msgid "Unsupported operator %s in domain %s" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:1661 +#: code:addons/web/static/src/js/views/form_widgets.js:1658 #, python-format msgid "Upgrade now" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_widgets.js:1658 +#: code:addons/web/static/src/xml/base.xml:1506 #, python-format -msgid "Upgrade to Odoo Enterprise to activate this feature." +msgid "Upgrade to future versions" msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/xml/base.xml:919 -#: code:addons/web/static/src/xml/base.xml:980 +#: code:addons/web/static/src/xml/base.xml:970 +#: code:addons/web/static/src/xml/base.xml:1031 #, python-format msgid "Uploading ..." msgstr "" #. module: web #. openerp-web -#: code:addons/web/static/src/js/views/form_relational_widgets.js:1620 +#: code:addons/web/static/src/js/views/form_relational_widgets.js:1633 #: code:addons/web/static/src/js/widgets/sidebar.js:168 #, python-format msgid "Uploading Error" @@ -2161,6 +2303,13 @@ msgstr "" msgid "Validation Error" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/xml/base.xml:105 +#, python-format +msgid "Version" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/widgets/priority.js:51 diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 0f1afc033ad..db5d823590e 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -195,7 +195,7 @@
  • - + From a6badd25597e5e0930cb014fe94db754dae32c8f Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 13 Jan 2016 14:42:26 +0100 Subject: [PATCH 15/19] Revert "[FIX] product: sort pricelist items by sequence" This reverts commit 98e5673c908fe4d72e55a068a951700cc93ee33f. Sequence should not be taken into account since the default order is clear enough for the user. --- addons/product/pricelist.py | 4 ++-- addons/product/pricelist_view.xml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index bcd81241621..ab8c84f6433 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -148,7 +148,7 @@ class product_pricelist(osv.osv): 'AND (categ_id IS NULL OR categ_id = any(%s)) ' 'AND (pricelist_id = %s) ' 'AND ((i.date_start IS NULL OR i.date_start<=%s) AND (i.date_end IS NULL OR i.date_end>=%s))' - 'ORDER BY sequence, applied_on, min_quantity desc', + 'ORDER BY applied_on, min_quantity desc', (prod_tmpl_ids, prod_ids, categ_ids, pricelist.id, date, date)) item_ids = [x[0] for x in cr.fetchall()] @@ -251,7 +251,7 @@ class product_pricelist(osv.osv): class product_pricelist_item(osv.osv): _name = "product.pricelist.item" _description = "Pricelist item" - _order = "sequence, applied_on, min_quantity desc" + _order = "applied_on, min_quantity desc" def _check_recursion(self, cr, uid, ids, context=None): for obj_list in self.browse(cr, uid, ids, context=context): diff --git a/addons/product/pricelist_view.xml b/addons/product/pricelist_view.xml index 64f2a6d751e..db191649c61 100644 --- a/addons/product/pricelist_view.xml +++ b/addons/product/pricelist_view.xml @@ -134,7 +134,6 @@ - From 10efb0621fc553e25be80637f1580a7d9e191bd7 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 13 Jan 2016 13:20:23 +0100 Subject: [PATCH 16/19] [FIX] website: editor: enable/disable save/undo/redo button when resize snippet --- addons/web_editor/static/src/js/rte.summernote.js | 2 +- addons/website/static/src/js/website.snippets.editor.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/web_editor/static/src/js/rte.summernote.js b/addons/web_editor/static/src/js/rte.summernote.js index 01020a84c22..094d13340dc 100644 --- a/addons/web_editor/static/src/js/rte.summernote.js +++ b/addons/web_editor/static/src/js/rte.summernote.js @@ -764,7 +764,7 @@ eventHandler.attach = function (oLayoutInfo, options) { .add(oLayoutInfo.handle()) .add(oLayoutInfo.popover()) .add(custom_toolbar) - .on('click keyup', function () { + .on('click content_changed', function () { $('button[data-event="undo"]', $toolbar).attr('disabled', !oLayoutInfo.editable().data('NoteHistory').hasUndo()); $('button[data-event="redo"]', $toolbar).attr('disabled', !oLayoutInfo.editable().data('NoteHistory').hasRedo()); }); diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 6015f740301..0da262f145e 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -326,7 +326,9 @@ options.registry.marginAndResize = options.Class.extend({ $body.removeClass(cursor); setTimeout(function () { self.buildingBlock.editor_busy = false; - self.$target.closest(".o_editable").trigger("content_changed"); + if (begin !== current) { + self.buildingBlock.parent.rte.historyRecordUndo(self.$target, 'resize_' + XY); + } },0); self.$target.removeClass("resize_editor_busy"); }; @@ -336,8 +338,8 @@ options.registry.marginAndResize = options.Class.extend({ this.$overlay.find(".oe_handle.size .auto_size").on('click', function (event){ self.$target.css("height", ""); self.$target.css("overflow", ""); + self.buildingBlock.parent.rte.historyRecordUndo(self.$target, 'resize_Y'); self.buildingBlock.cover_target(self.$overlay, self.$target); - self.$target.closest(".o_editable").trigger("content_changed"); return false; }); }, From d26c85dc0a4346f3fbce3400ecb9796a811847b6 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 13 Jan 2016 16:08:07 +0100 Subject: [PATCH 17/19] [FIX] hr_expense: mark paid on reconciliation, precision When comparing floats, `float_compare` must always be used to avoid precision issues. e.g., percentages like 1.0000000000000002 must be considered as equal to 1. opw-666459 --- addons/hr_expense/models/account_move_line.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_expense/models/account_move_line.py b/addons/hr_expense/models/account_move_line.py index bf408105b5a..f7e24f65277 100644 --- a/addons/hr_expense/models/account_move_line.py +++ b/addons/hr_expense/models/account_move_line.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from openerp import api, models - +from openerp.tools import float_compare class AccountMoveLine(models.Model): _inherit = "account.move.line" @@ -10,7 +10,7 @@ class AccountMoveLine(models.Model): @api.multi def reconcile(self, writeoff_acc_id=False, writeoff_journal_id=False): res = super(AccountMoveLine, self).reconcile(writeoff_acc_id=writeoff_acc_id, writeoff_journal_id=writeoff_journal_id) - account_move_ids = [l.move_id.id for l in self if l.move_id.matched_percentage == 1] + account_move_ids = [l.move_id.id for l in self if float_compare(l.move_id.matched_percentage, 1, precision_digits=5) == 0] if account_move_ids: expenses = self.env['hr.expense'].search([('account_move_id', 'in', account_move_ids)]) expenses.paid_expenses() From 060cff9be31a70b096f7f12fec0c410fd6963758 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Wed, 13 Jan 2016 14:32:16 +0100 Subject: [PATCH 18/19] [FIX] web_editor: get unlink button working f3f7bd9 improved some link editing behaviour by adding contenteditable attribute on it. But if contenteditable is set on a link, using command "unlink" on the element for `document.execCommand` does not work. Hence this commit adds a code so the first click outside the link remove contenteditable. closes #10436 second-part-of: opw-659772 --- addons/web_editor/static/src/js/rte.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/addons/web_editor/static/src/js/rte.js b/addons/web_editor/static/src/js/rte.js index 85721ba0387..becaf978d17 100644 --- a/addons/web_editor/static/src/js/rte.js +++ b/addons/web_editor/static/src/js/rte.js @@ -513,13 +513,21 @@ var RTE = Widget.extend({ } if ($target.is('a')) { + // add contenteditable on link to improve its editing behaviour $target.attr('contenteditable', true); setTimeout(function () { $editable.attr('contenteditable', false); }); - } else if ($editable.attr('contenteditable') === 'false') { - $target.removeAttr('contenteditable'); - $editable.attr('contenteditable', true); + // once clicked outside, remove contenteditable on link + var reactive_editable = function(e){ + if($target.is(e.target)) { + return; + } + $target.removeAttr('contenteditable'); + $editable.attr('contenteditable', true); + $(document).off('mousedown', reactive_editable); + } + $(document).on('mousedown', reactive_editable); } if (this && this.$last && (!$editable.size() || this.$last[0] != $editable[0])) { From 3be9d911c0d50cbe6e4e5768d40011849cc43972 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 13 Jan 2016 16:47:06 +0100 Subject: [PATCH 19/19] [FIX] mass_mailing: translated stage in kanban view Missing _ in read_group call --- addons/mass_mailing/i18n/mass_mailing.pot | 12 ++++++++++-- addons/mass_mailing/models/mass_mailing.py | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/addons/mass_mailing/i18n/mass_mailing.pot b/addons/mass_mailing/i18n/mass_mailing.pot index 40e25c0bfa8..fee9a173eb7 100644 --- a/addons/mass_mailing/i18n/mass_mailing.pot +++ b/addons/mass_mailing/i18n/mass_mailing.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-06 07:17+0000\n" -"PO-Revision-Date: 2016-01-06 07:17+0000\n" +"POT-Creation-Date: 2016-01-13 15:46+0000\n" +"PO-Revision-Date: 2016-01-13 15:46+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -523,8 +523,10 @@ msgid "Domain" msgstr "" #. module: mass_mailing +#: code:addons/mass_mailing/models/mass_mailing.py:638 #: selection:mail.mass_mailing,state:0 #: selection:mail.statistics.report,state:0 +#, python-format msgid "Draft" msgstr "" @@ -702,7 +704,9 @@ msgid "If checked, recipients will be mailed only once, allowing to sendvarious msgstr "" #. module: mass_mailing +#: code:addons/mass_mailing/models/mass_mailing.py:638 #: selection:mail.mass_mailing,state:0 +#, python-format msgid "In Queue" msgstr "" @@ -1356,11 +1360,14 @@ msgid "Send to All" msgstr "" #. module: mass_mailing +#: code:addons/mass_mailing/models/mass_mailing.py:638 #: selection:mail.mass_mailing,state:0 +#, python-format msgid "Sending" msgstr "" #. module: mass_mailing +#: code:addons/mass_mailing/models/mass_mailing.py:638 #: model:ir.model.fields,field_description:mass_mailing.field_mail_mail_statistics_sent #: model:ir.model.fields,field_description:mass_mailing.field_mail_mass_mailing_sent #: model:ir.model.fields,field_description:mass_mailing.field_mail_statistics_report_sent @@ -1368,6 +1375,7 @@ msgstr "" #: selection:mail.mass_mailing,state:0 #: model:mail.mass_mailing.stage,name:mass_mailing.campaign_stage_3 #: selection:mail.statistics.report,state:0 +#, python-format msgid "Sent" msgstr "" diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py index e8b4c755508..417e3226040 100644 --- a/addons/mass_mailing/models/mass_mailing.py +++ b/addons/mass_mailing/models/mass_mailing.py @@ -635,7 +635,7 @@ class MassMailing(osv.Model): if groupby and groupby[0] == "state": # Default result structure # states = self._get_state_list(cr, uid, context=context) - states = [('draft', 'Draft'), ('in_queue', 'In Queue'), ('sending', 'Sending'), ('done', 'Sent')] + states = [('draft', _('Draft')), ('in_queue', _('In Queue')), ('sending', _('Sending')), ('done', _('Sent'))] read_group_all_states = [{ '__context': {'group_by': groupby[1:]}, '__domain': domain + [('state', '=', state_value)],