summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarshan Kalola <darshankalola@gmail.com>2013-08-13 16:27:20 +0530
committerDarshan Kalola <darshankalola@gmail.com>2013-08-13 16:27:20 +0530
commite379d94ededffaa0bee421f7565bbef7eb077523 (patch)
tree5644e1db1f2f5a9d57c75c07ad1b84b955163b97
parente2df39045f1b2532f6d9b25033c5ef9fa7ab9608 (diff)
parente8164c9a927ec8339252712bae3bf0a5ca1760e3 (diff)
[MERGE]merged with main addons
bzr revid: darshankalola@gmail.com-20130813105720-2x41lnuv6cs2xlyw
-rw-r--r--addons/account_accountant/i18n/ja.po10
-rw-r--r--addons/account_bank_statement_extensions/i18n/ru.po361
-rw-r--r--addons/account_budget/i18n/ja.po10
-rw-r--r--addons/account_cancel/i18n/uk.po23
-rw-r--r--addons/account_check_writing/i18n/bs.po246
-rw-r--r--addons/base_status/__init__.py1
-rw-r--r--addons/base_status/__openerp__.py5
-rw-r--r--addons/base_status/base_stage.py264
-rw-r--r--addons/base_status/i18n/bs.po80
-rw-r--r--addons/crm/__openerp__.py1
-rw-r--r--addons/crm/board_crm_view.xml11
-rw-r--r--addons/crm/crm.py18
-rw-r--r--addons/crm/crm_action_rule_demo.xml2
-rw-r--r--addons/crm/crm_lead.py134
-rw-r--r--addons/crm/crm_lead_data.xml74
-rw-r--r--addons/crm/crm_lead_demo.xml178
-rw-r--r--addons/crm/crm_lead_view.xml107
-rw-r--r--addons/crm/crm_view.xml2
-rw-r--r--addons/crm/doc/changelog.rst6
-rw-r--r--addons/crm/doc/index.rst5
-rw-r--r--addons/crm/doc/stage_status.rst61
-rw-r--r--addons/crm/i18n/es_AR.po201
-rw-r--r--addons/crm/i18n/zh_CN.po17
-rw-r--r--addons/crm/report/crm_lead_report.py27
-rw-r--r--addons/crm/report/crm_lead_report_view.xml19
-rw-r--r--addons/crm/report/crm_phonecall_report.py10
-rw-r--r--addons/crm/report/crm_phonecall_report_view.xml2
-rw-r--r--addons/crm/res_partner.py3
-rw-r--r--addons/crm/test/crm_lead_cancel.yml7
-rw-r--r--addons/crm/test/crm_lead_find_stage.yml43
-rw-r--r--addons/crm/test/crm_lead_merge.yml41
-rw-r--r--addons/crm/test/crm_lead_onchange.yml3
-rw-r--r--addons/crm/test/lead2opportunity2win.yml41
-rw-r--r--addons/crm/wizard/crm_lead_to_opportunity.py9
-rw-r--r--addons/crm/wizard/crm_merge_opportunities.py5
-rw-r--r--addons/crm_claim/crm_claim.py11
-rw-r--r--addons/crm_claim/crm_claim_data.xml7
-rw-r--r--addons/crm_claim/crm_claim_view.xml10
-rw-r--r--addons/crm_claim/report/crm_claim_report.py12
-rw-r--r--addons/crm_claim/report/crm_claim_report_view.xml9
-rw-r--r--addons/crm_helpdesk/crm_helpdesk.py10
-rw-r--r--addons/crm_partner_assign/crm_lead_view.xml6
-rw-r--r--addons/crm_partner_assign/crm_portal_view.xml6
-rw-r--r--addons/crm_partner_assign/report/crm_lead_report.py13
-rw-r--r--addons/crm_partner_assign/report/crm_lead_report_view.xml7
-rw-r--r--addons/crm_partner_assign/res_partner_view.xml234
-rw-r--r--addons/email_template/doc/changelog.rst1
-rw-r--r--addons/email_template/wizard/mail_compose_message.py12
-rw-r--r--addons/google_drive/i18n/es.po96
-rw-r--r--addons/google_spreadsheet/google_spreadsheet.py14
-rw-r--r--addons/hr_holidays/doc/changelog.rst13
-rw-r--r--addons/hr_holidays/doc/index.rst13
-rw-r--r--addons/hr_holidays/hr_holidays.py109
-rw-r--r--addons/hr_holidays/hr_holidays_data.xml2
-rw-r--r--addons/hr_holidays/hr_holidays_view.xml16
-rw-r--r--addons/hr_holidays/hr_holidays_workflow.xml40
-rw-r--r--addons/hr_holidays/security/ir.model.access.csv3
-rw-r--r--addons/hr_holidays/test/test_hr_holiday.yml2
-rw-r--r--addons/hr_holidays/tests/__init__.py28
-rw-r--r--addons/hr_holidays/tests/common.py98
-rw-r--r--addons/hr_holidays/tests/test_holidays_flow.py207
-rw-r--r--addons/mail/__openerp__.py1
-rw-r--r--addons/mail/doc/changelog.rst8
-rw-r--r--addons/mail/i18n/bs.po1687
-rw-r--r--addons/mail/mail_followers.py2
-rw-r--r--addons/mail/mail_mail.py11
-rw-r--r--addons/mail/mail_message.py17
-rw-r--r--addons/mail/mail_thread.py20
-rw-r--r--addons/mail/static/lib/jquery.expander/jquery.expander.js385
-rw-r--r--addons/mail/static/src/css/mail.css3
-rw-r--r--addons/mail/static/src/js/mail.js20
-rw-r--r--addons/mail/static/src/xml/mail.xml8
-rw-r--r--addons/mail/tests/test_mail_features.py33
-rw-r--r--addons/mail/tests/test_mail_gateway.py285
-rw-r--r--addons/mail/wizard/mail_compose_message.py18
-rw-r--r--addons/mail/wizard/mail_compose_message_view.xml3
-rw-r--r--addons/mrp/i18n/zh_CN.po55
-rw-r--r--addons/mrp_operations/mrp_operations.py1
-rw-r--r--addons/note/i18n/bs.po284
-rw-r--r--addons/point_of_sale/i18n/zh_CN.po271
-rw-r--r--addons/portal_crm/i18n/bs.po546
-rw-r--r--addons/product/i18n/zh_CN.po30
-rw-r--r--addons/project/i18n/zh_CN.po30
-rw-r--r--addons/project/project.py1
-rw-r--r--addons/project_issue/i18n/bs.po984
-rw-r--r--addons/project_issue/project_issue.py1
-rw-r--r--addons/sale_crm/sale_crm_view.xml4
-rw-r--r--addons/sale_crm/wizard/crm_make_sale.py2
-rw-r--r--addons/share/i18n/bs.po629
-rw-r--r--addons/stock/i18n/zh_CN.po459
90 files changed, 6880 insertions, 1924 deletions
diff --git a/addons/account_accountant/i18n/ja.po b/addons/account_accountant/i18n/ja.po
index 9e2208e06cd..1da9c374c7f 100644
--- a/addons/account_accountant/i18n/ja.po
+++ b/addons/account_accountant/i18n/ja.po
@@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-04-13 22:35+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2013-07-30 22:25+0000\n"
+"Last-Translator: Masaki Yamaya <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:47+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-07-31 05:16+0000\n"
+"X-Generator: Launchpad (build 16718)\n"
#. module: account_accountant
#: model:ir.actions.client,name:account_accountant.action_client_account_menu
msgid "Open Accounting Menu"
-msgstr ""
+msgstr "会計メニューを開く"
#~ msgid ""
#~ "\n"
diff --git a/addons/account_bank_statement_extensions/i18n/ru.po b/addons/account_bank_statement_extensions/i18n/ru.po
new file mode 100644
index 00000000000..61b054e7563
--- /dev/null
+++ b/addons/account_bank_statement_extensions/i18n/ru.po
@@ -0,0 +1,361 @@
+# Russian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-08-05 10:40+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Russian <ru@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-06 04:47+0000\n"
+"X-Generator: Launchpad (build 16718)\n"
+
+#. module: account_bank_statement_extensions
+#: help:account.bank.statement.line.global,name:0
+msgid "Originator to Beneficiary Information"
+msgstr "Информация от плательщика получателю"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+#: selection:account.bank.statement.line,state:0
+msgid "Confirmed"
+msgstr "Подтверждено"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement:0
+#: view:account.bank.statement.line:0
+msgid "Glob. Id"
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: selection:account.bank.statement.line.global,type:0
+msgid "CODA"
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,parent_id:0
+msgid "Parent Code"
+msgstr "Основной код"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Debit"
+msgstr "Дебет"
+
+#. module: account_bank_statement_extensions
+#: view:cancel.statement.line:0
+#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_cancel_statement_line
+#: model:ir.model,name:account_bank_statement_extensions.model_cancel_statement_line
+msgid "Cancel selected statement lines"
+msgstr "Отмена выбранных позиций выписки"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,val_date:0
+msgid "Value Date"
+msgstr "Дата зачисления"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Group By..."
+msgstr "Группировать по ..."
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+#: selection:account.bank.statement.line,state:0
+msgid "Draft"
+msgstr "Черновик"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Statement"
+msgstr "Выписка"
+
+#. module: account_bank_statement_extensions
+#: view:confirm.statement.line:0
+#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_confirm_statement_line
+#: model:ir.model,name:account_bank_statement_extensions.model_confirm_statement_line
+msgid "Confirm selected statement lines"
+msgstr "Подтверждение выбранных позиций выписки"
+
+#. module: account_bank_statement_extensions
+#: report:bank.statement.balance.report:0
+#: model:ir.actions.report.xml,name:account_bank_statement_extensions.bank_statement_balance_report
+msgid "Bank Statement Balances Report"
+msgstr "Отчет об остатках банковской выписки"
+
+#. module: account_bank_statement_extensions
+#: view:cancel.statement.line:0
+msgid "Cancel Lines"
+msgstr "Отменить позиции"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line.global:0
+#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement_line_global
+msgid "Batch Payment Info"
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,state:0
+msgid "Status"
+msgstr "Статус"
+
+#. module: account_bank_statement_extensions
+#: code:addons/account_bank_statement_extensions/account_bank_statement.py:129
+#, python-format
+msgid ""
+"Delete operation not allowed. Please go to the associated bank "
+"statement in order to delete and/or modify bank statement line."
+msgstr ""
+"Операция удаления запрещена. Пожалуйста, обратитесь к соответствующей "
+"банковской выписке для удаления/изменения позиции."
+
+#. module: account_bank_statement_extensions
+#: view:confirm.statement.line:0
+msgid "or"
+msgstr "или"
+
+#. module: account_bank_statement_extensions
+#: view:confirm.statement.line:0
+msgid "Confirm Lines"
+msgstr "Подтвердить позиции"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line.global:0
+msgid "Transactions"
+msgstr "Операции"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,type:0
+msgid "Type"
+msgstr "Тип"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+#: report:bank.statement.balance.report:0
+msgid "Journal"
+msgstr "Журнал"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Confirmed Statement Lines."
+msgstr "Подтвержденные позиции выписки."
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Credit Transactions."
+msgstr "Операции по кредиту"
+
+#. module: account_bank_statement_extensions
+#: model:ir.actions.act_window,help:account_bank_statement_extensions.action_cancel_statement_line
+msgid "cancel selected statement lines."
+msgstr "отменить выбранные позиции выписки"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,counterparty_number:0
+msgid "Counterparty Number"
+msgstr "Число контрагентов"
+
+#. module: account_bank_statement_extensions
+#: report:bank.statement.balance.report:0
+msgid "Closing Balance"
+msgstr "Итоговый баланс"
+
+#. module: account_bank_statement_extensions
+#: report:bank.statement.balance.report:0
+msgid "Date"
+msgstr "Дата"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+#: field:account.bank.statement.line,globalisation_amount:0
+msgid "Glob. Amount"
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Debit Transactions."
+msgstr "Операции по дебету"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Extended Filters..."
+msgstr "Расширенные фильтры..."
+
+#. module: account_bank_statement_extensions
+#: view:confirm.statement.line:0
+msgid "Confirmed lines cannot be changed anymore."
+msgstr "Нельзя изменить подтвержденные позиции."
+
+#. module: account_bank_statement_extensions
+#: view:cancel.statement.line:0
+msgid "Are you sure you want to cancel the selected Bank Statement lines ?"
+msgstr ""
+"Вы уверены, что хотите отменить выбранные позиции банковской выписки ?"
+
+#. module: account_bank_statement_extensions
+#: report:bank.statement.balance.report:0
+msgid "Name"
+msgstr "Название"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,name:0
+msgid "OBI"
+msgstr "Назначение"
+
+#. module: account_bank_statement_extensions
+#: selection:account.bank.statement.line.global,type:0
+msgid "ISO 20022"
+msgstr "ISO 20022"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Notes"
+msgstr "Примечания"
+
+#. module: account_bank_statement_extensions
+#: selection:account.bank.statement.line.global,type:0
+msgid "Manual"
+msgstr "Ручной"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Bank Transaction"
+msgstr "Банковские операции"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Credit"
+msgstr "Кредит"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,amount:0
+msgid "Amount"
+msgstr "Сумма"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Fin.Account"
+msgstr "Фин. Счет"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,counterparty_currency:0
+msgid "Counterparty Currency"
+msgstr "Валюта контрагента"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,counterparty_bic:0
+msgid "Counterparty BIC"
+msgstr "БИК контрагента"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,child_ids:0
+msgid "Child Codes"
+msgstr "Субкоды"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Search Bank Transactions"
+msgstr "Поиск банковских операций"
+
+#. module: account_bank_statement_extensions
+#: view:confirm.statement.line:0
+msgid "Are you sure you want to confirm the selected Bank Statement lines ?"
+msgstr ""
+"Вы уверены, что хотите, подтвердить выбранные позиции банковской выписки ?"
+
+#. module: account_bank_statement_extensions
+#: help:account.bank.statement.line,globalisation_id:0
+msgid ""
+"Code to identify transactions belonging to the same globalisation level "
+"within a batch payment"
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Draft Statement Lines."
+msgstr "Черновики позиций выписки."
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Glob. Am."
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement_line
+msgid "Bank Statement Line"
+msgstr "Позиция банковской выписки"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,code:0
+msgid "Code"
+msgstr "Код"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,counterparty_name:0
+msgid "Counterparty Name"
+msgstr "Название контрагента"
+
+#. module: account_bank_statement_extensions
+#: model:ir.model,name:account_bank_statement_extensions.model_res_partner_bank
+msgid "Bank Accounts"
+msgstr "Банковские счета"
+
+#. module: account_bank_statement_extensions
+#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement
+msgid "Bank Statement"
+msgstr "Банковская выписка"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Statement Line"
+msgstr "Позиция выписки"
+
+#. module: account_bank_statement_extensions
+#: sql_constraint:account.bank.statement.line.global:0
+msgid "The code must be unique !"
+msgstr "Код должен быть уникальным !"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line.global,bank_statement_line_ids:0
+#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_bank_statement_line
+#: model:ir.ui.menu,name:account_bank_statement_extensions.bank_statement_line
+msgid "Bank Statement Lines"
+msgstr "Позиции банковской выписки"
+
+#. module: account_bank_statement_extensions
+#: code:addons/account_bank_statement_extensions/account_bank_statement.py:129
+#, python-format
+msgid "Warning!"
+msgstr "Внимание!"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line.global:0
+msgid "Child Batch Payments"
+msgstr ""
+
+#. module: account_bank_statement_extensions
+#: view:confirm.statement.line:0
+msgid "Cancel"
+msgstr "Отмена"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Statement Lines"
+msgstr "Позиции выписки"
+
+#. module: account_bank_statement_extensions
+#: view:account.bank.statement.line:0
+msgid "Total Amount"
+msgstr "Итоговая сумма"
+
+#. module: account_bank_statement_extensions
+#: field:account.bank.statement.line,globalisation_id:0
+msgid "Globalisation ID"
+msgstr ""
diff --git a/addons/account_budget/i18n/ja.po b/addons/account_budget/i18n/ja.po
index f69a34b9a82..4dd1ba0298f 100644
--- a/addons/account_budget/i18n/ja.po
+++ b/addons/account_budget/i18n/ja.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-06-13 17:16+0000\n"
-"Last-Translator: Akira Hiyama <Unknown>\n"
+"PO-Revision-Date: 2013-07-30 22:29+0000\n"
+"Last-Translator: Masaki Yamaya <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:34+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-07-31 05:16+0000\n"
+"X-Generator: Launchpad (build 16718)\n"
#. module: account_budget
#: view:account.budget.analytic:0
@@ -418,7 +418,7 @@ msgstr "からの分析"
#. module: account_budget
#: view:crossovered.budget:0
msgid "Draft Budgets"
-msgstr "ドラフト予算"
+msgstr "予算案"
#, python-format
#~ msgid "The General Budget '%s' has no Accounts!"
diff --git a/addons/account_cancel/i18n/uk.po b/addons/account_cancel/i18n/uk.po
new file mode 100644
index 00000000000..5fbae627883
--- /dev/null
+++ b/addons/account_cancel/i18n/uk.po
@@ -0,0 +1,23 @@
+# Ukrainian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-08-01 11:11+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Ukrainian <uk@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-02 05:38+0000\n"
+"X-Generator: Launchpad (build 16718)\n"
+
+#. module: account_cancel
+#: view:account.invoice:0
+msgid "Cancel"
+msgstr ""
diff --git a/addons/account_check_writing/i18n/bs.po b/addons/account_check_writing/i18n/bs.po
new file mode 100644
index 00000000000..252798b016f
--- /dev/null
+++ b/addons/account_check_writing/i18n/bs.po
@@ -0,0 +1,246 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-08-08 22:05+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-09 05:06+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
+
+#. module: account_check_writing
+#: selection:res.company,check_layout:0
+msgid "Check on Top"
+msgstr "Ček na vrhu"
+
+#. module: account_check_writing
+#: report:account.print.check.top:0
+msgid "Open Balance"
+msgstr "Otvoreno saldo"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+#: view:account.voucher:0
+msgid "Print Check"
+msgstr "Štampaj ček"
+
+#. module: account_check_writing
+#: selection:res.company,check_layout:0
+msgid "Check in middle"
+msgstr "Ćek u sredini"
+
+#. module: account_check_writing
+#: help:res.company,check_layout:0
+msgid ""
+"Check on top is compatible with Quicken, QuickBooks and Microsoft Money. "
+"Check in middle is compatible with Peachtree, ACCPAC and DacEasy. Check on "
+"bottom is compatible with Peachtree, ACCPAC and DacEasy only"
+msgstr ""
+"Ček na vrhu je kompatibilan sa Quicken, QuickBooks i Microsoft Money. Ček u "
+"sredini je kompatibilan sa Peachtree, ACCPAC i DacEasy. Ček na dnu je "
+"kompatibilan sa Peachtree, ACCPAC i DacEasy samo"
+
+#. module: account_check_writing
+#: selection:res.company,check_layout:0
+msgid "Check on bottom"
+msgstr "Ćek na dnu"
+
+#. module: account_check_writing
+#: model:ir.actions.act_window,name:account_check_writing.action_account_check_write
+msgid "Print Check in Batch"
+msgstr "Štampaj čekove grupno"
+
+#. module: account_check_writing
+#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
+#, python-format
+msgid "One of the printed check already got a number."
+msgstr "Jedan od odštampanih čekova je već dobio broj."
+
+#. module: account_check_writing
+#: help:account.journal,allow_check_writing:0
+msgid "Check this if the journal is to be used for writing checks."
+msgstr ""
+"Označite ovo ako će se za pisanje čekova koristiti dnevnik knjiženja."
+
+#. module: account_check_writing
+#: field:account.journal,allow_check_writing:0
+msgid "Allow Check writing"
+msgstr "Dozvoli pisanje čekova"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Description"
+msgstr "Opis"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_journal
+msgid "Journal"
+msgstr "Dnevnik knjiženja"
+
+#. module: account_check_writing
+#: model:ir.actions.act_window,name:account_check_writing.action_write_check
+#: model:ir.ui.menu,name:account_check_writing.menu_action_write_check
+msgid "Write Checks"
+msgstr "Piši čekove"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Discount"
+msgstr "Popust"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Original Amount"
+msgstr "Originalni iznos"
+
+#. module: account_check_writing
+#: field:res.company,check_layout:0
+msgid "Check Layout"
+msgstr "Raspored čeka"
+
+#. module: account_check_writing
+#: field:account.voucher,allow_check:0
+msgid "Allow Check Writing"
+msgstr "Dozvoli pisanje čeka"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Payment"
+msgstr "Plaćanje"
+
+#. module: account_check_writing
+#: field:account.journal,use_preprint_check:0
+msgid "Use Preprinted Check"
+msgstr "Koristi pred-odštampane čekove"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_bottom
+msgid "Print Check (Bottom)"
+msgstr "Štampaj ček (donji)"
+
+#. module: account_check_writing
+#: model:ir.actions.act_window,help:account_check_writing.action_write_check
+msgid ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" Click to create a new check. \n"
+" </p><p>\n"
+" The check payment form allows you to track the payment you "
+"do\n"
+" to your suppliers using checks. When you select a supplier, "
+"the\n"
+" payment method and an amount for the payment, OpenERP will\n"
+" propose to reconcile your payment with the open supplier\n"
+" invoices or bills.\n"
+" </p>\n"
+" "
+msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" Kliknite da kreirate nove čekove. \n"
+" </p><p>\n"
+" Forma plaćanje čekom omogućava vam da pratite plaćanja koja "
+"izvršavate\n"
+" vašim dobavljačima koristeći čekove. Kada odaberete "
+"dobavljača,\n"
+" metodu plaćanja i iznos za plaćanje, OpenERP će predložiti "
+"da izravna\n"
+" vašu uplatu sa otvorenom fakturom ili računom dobavljača.\n"
+" </p>\n"
+" "
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Due Date"
+msgstr "Datum dospijeća"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
+msgid "Print Check (Middle)"
+msgstr "Štampaj ček (srednji)"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_res_company
+msgid "Companies"
+msgstr "Kompanije"
+
+#. module: account_check_writing
+#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
+#, python-format
+msgid "Error!"
+msgstr "Greška!"
+
+#. module: account_check_writing
+#: help:account.check.write,check_number:0
+msgid "The number of the next check number to be printed."
+msgstr "Broj sljedećeg čeka za štampanje."
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+msgid "Balance Due"
+msgstr "Saldo valute"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
+msgid "Print Check (Top)"
+msgstr "Štampaj ček (na vrhu)"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Check Amount"
+msgstr "Iznos čeka"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_voucher
+msgid "Accounting Voucher"
+msgstr "Računovodstveni vaučer"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "or"
+msgstr "ili"
+
+#. module: account_check_writing
+#: field:account.voucher,amount_in_word:0
+msgid "Amount in Word"
+msgstr "Pisani iznos"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_check_write
+msgid "Prin Check in Batch"
+msgstr "Štampaj čekove grupno"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "Cancel"
+msgstr "Otkaži"
+
+#. module: account_check_writing
+#: field:account.check.write,check_number:0
+msgid "Next Check Number"
+msgstr "Sljedeći broj čeka"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "Check"
+msgstr "Ček"
diff --git a/addons/base_status/__init__.py b/addons/base_status/__init__.py
index e4107f90a37..ea9d738e614 100644
--- a/addons/base_status/__init__.py
+++ b/addons/base_status/__init__.py
@@ -20,6 +20,5 @@
##############################################################################
import base_state
-import base_stage
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_status/__openerp__.py b/addons/base_status/__openerp__.py
index 79b6dd2016c..b3936ec10cb 100644
--- a/addons/base_status/__openerp__.py
+++ b/addons/base_status/__openerp__.py
@@ -24,11 +24,10 @@
'version': '1.0',
'category': 'Hidden',
'description': """
-This module handles state and stage. It is derived from the crm_base and crm_case classes from crm.
-===================================================================================================
+This module handles state. It is derived from the crm_base and crm_case classes from crm.
+==========================================================================================
* ``base_state``: state management
- * ``base_stage``: stage management
""",
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py
deleted file mode 100644
index edf9db166af..00000000000
--- a/addons/base_status/base_stage.py
+++ /dev/null
@@ -1,264 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-today OpenERP SA (<http://www.openerp.com>)
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from openerp.osv import fields, osv
-from openerp.tools.translate import _
-
-class base_stage(object):
- """ Base utility mixin class for objects willing to manage their stages.
- Object that inherit from this class should inherit from mailgate.thread
- to have access to the mail gateway, as well as Chatter. Objects
- subclassing this class should define the following colums:
- - ``date_open`` (datetime field)
- - ``date_closed`` (datetime field)
- - ``user_id`` (many2one to res.users)
- - ``partner_id`` (many2one to res.partner)
- - ``stage_id`` (many2one to a stage definition model)
- - ``state`` (selection field, related to the stage_id.state)
- """
-
- def _get_default_partner(self, cr, uid, context=None):
- """ Gives id of partner for current user
- :param context: if portal not in context returns False
- """
- if context is None:
- context = {}
- if context.get('portal'):
- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
- return user.partner_id.id
- return False
-
- def _get_default_email(self, cr, uid, context=None):
- """ Gives default email address for current user
- :param context: if portal not in context returns False
- """
- if context is None:
- context = {}
- if context.get('portal'):
- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
- return user.email
- return False
-
- def _get_default_user(self, cr, uid, context=None):
- """ Gives current user id
- :param context: if portal not in context returns False
- """
- if context is None:
- context = {}
- if not context or context.get('portal'):
- return False
- return uid
-
- def onchange_partner_address_id(self, cr, uid, ids, add, email=False, context=None):
- """ This function returns value of partner email based on Partner Address
- :param add: Id of Partner's address
- :param email: Partner's email ID
- """
- data = {'value': {'email_from': False, 'phone':False}}
- if add:
- address = self.pool.get('res.partner').browse(cr, uid, add)
- data['value'] = {'partner_name': address and address.name or False,
- 'email_from': address and address.email or False,
- 'phone': address and address.phone or False,
- 'street': address and address.street or False,
- 'street2': address and address.street2 or False,
- 'city': address and address.city or False,
- 'state_id': address.state_id and address.state_id.id or False,
- 'zip': address and address.zip or False,
- 'country_id': address.country_id and address.country_id.id or False,
- }
- fields = self.fields_get(cr, uid, context=context or {})
- for key in data['value'].keys():
- if key not in fields:
- del data['value'][key]
- return data
-
- def onchange_partner_id(self, cr, uid, ids, part, email=False):
- """ This function returns value of partner address based on partner
- :param part: Partner's id
- :param email: Partner's email ID
- """
- data={}
- if part:
- addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
- data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
- return {'value': data}
-
- def _get_default_section_id(self, cr, uid, context=None):
- """ Gives default section """
- return False
-
- def _get_default_stage_id(self, cr, uid, context=None):
- """ Gives default stage_id """
- return self.stage_find(cr, uid, [], None, [('state', '=', 'draft')], context=context)
-
- def stage_find(self, cr, uid, cases, section_id, domain=[], order='sequence', context=None):
- """ Find stage, with a given (optional) domain on the search,
- ordered by the order parameter. If several stages match the
- search criterions, the first one will be returned, according
- to the requested search order.
- This method is meant to be overriden by subclasses. That way
- specific behaviors can be achieved for every class inheriting
- from base_stage.
-
- :param cases: browse_record of cases
- :param section_id: section limitating the search, given for
- a generic search (for example default search).
- A section models concepts such as Sales team
- (for CRM), ou departments (for HR).
- :param domain: a domain on the search of stages
- :param order: order of the search
- """
- return False
-
- def stage_set_with_state_name(self, cr, uid, cases, state_name, context=None):
- """ Set a new stage, with a state_name instead of a stage_id
- :param cases: browse_record of cases
- """
- if isinstance(cases, (int, long)):
- cases = self.browse(cr, uid, cases, context=context)
- for case in cases:
- stage_id = self.stage_find(cr, uid, [case], None, [('state', '=', state_name)], context=context)
- if stage_id:
- self.stage_set(cr, uid, [case.id], stage_id, context=context)
- return True
-
- def stage_set(self, cr, uid, ids, stage_id, context=None):
- """ Set the new stage. This methods is the right method to call
- when changing states. It also checks whether an onchange is
- defined, and execute it.
- """
- value = {}
- if hasattr(self, 'onchange_stage_id'):
- value = self.onchange_stage_id(cr, uid, ids, stage_id, context=context)['value']
- value['stage_id'] = stage_id
- return self.write(cr, uid, ids, value, context=context)
-
- def stage_change(self, cr, uid, ids, op, order, context=None):
- """ Change the stage and take the next one, based on a condition
- writen for the 'sequence' field and an operator. This methods
- checks whether the case has a current stage, and takes its
- sequence. Otherwise, a default 0 sequence is chosen and this
- method will therefore choose the first available stage.
- For example if op is '>' and current stage has a sequence of
- 10, this will call stage_find, with [('sequence', '>', '10')].
- """
- for case in self.browse(cr, uid, ids, context=context):
- seq = 0
- if case.stage_id:
- seq = case.stage_id.sequence or 0
- section_id = None
- next_stage_id = self.stage_find(cr, uid, [case], None, [('sequence', op, seq)],order, context=context)
- if next_stage_id:
- return self.stage_set(cr, uid, [case.id], next_stage_id, context=context)
- return False
-
- def stage_next(self, cr, uid, ids, context=None):
- """ This function computes next stage for case from its current stage
- using available stage for that case type
- """
- return self.stage_change(cr, uid, ids, '>','sequence', context)
-
- def stage_previous(self, cr, uid, ids, context=None):
- """ This function computes previous stage for case from its current
- stage using available stage for that case type
- """
- return self.stage_change(cr, uid, ids, '<', 'sequence desc', context)
-
- def copy(self, cr, uid, id, default=None, context=None):
- """ Overrides orm copy method to avoid copying messages,
- as well as date_closed and date_open columns if they
- exist."""
- if default is None:
- default = {}
-
- if hasattr(self, '_columns'):
- if self._columns.get('date_closed'):
- default.update({ 'date_closed': False, })
- if self._columns.get('date_open'):
- default.update({ 'date_open': False })
- return super(base_stage, self).copy(cr, uid, id, default, context=context)
-
- def case_escalate(self, cr, uid, ids, context=None):
- """ Escalates case to parent level """
- for case in self.browse(cr, uid, ids, context=context):
- data = {'active': True}
- if case.section_id.parent_id:
- data['section_id'] = case.section_id.parent_id.id
- if case.section_id.parent_id.change_responsible:
- if case.section_id.parent_id.user_id:
- data['user_id'] = case.section_id.parent_id.user_id.id
- else:
- raise osv.except_osv(_('Error!'), _("You are already at the top level of your sales-team category.\nTherefore you cannot escalate furthermore."))
- self.write(cr, uid, [case.id], data, context=context)
- return True
-
- def case_open(self, cr, uid, ids, context=None):
- """ Opens case """
- cases = self.browse(cr, uid, ids, context=context)
- for case in cases:
- data = {'active': True}
- if not case.user_id:
- data['user_id'] = uid
- self.case_set(cr, uid, [case.id], 'open', data, context=context)
- return True
-
- def case_close(self, cr, uid, ids, context=None):
- """ Closes case """
- return self.case_set(cr, uid, ids, 'done', {'active': True, 'date_closed': fields.datetime.now()}, context=context)
-
- def case_cancel(self, cr, uid, ids, context=None):
- """ Cancels case """
- return self.case_set(cr, uid, ids, 'cancel', {'active': True}, context=context)
-
- def case_pending(self, cr, uid, ids, context=None):
- """ Set case as pending """
- return self.case_set(cr, uid, ids, 'pending', {'active': True}, context=context)
-
- def case_reset(self, cr, uid, ids, context=None):
- """ Resets case as draft """
- return self.case_set(cr, uid, ids, 'draft', {'active': True}, context=context)
-
- def case_set(self, cr, uid, ids, new_state_name=None, values_to_update=None, new_stage_id=None, context=None):
- """ Generic method for setting case. This methods wraps the update
- of the record.
-
- :params new_state_name: the new state of the record; this method
- will call ``stage_set_with_state_name``
- that will find the stage matching the
- new state, using the ``stage_find`` method.
- :params new_stage_id: alternatively, you may directly give the
- new stage of the record
- :params state_name: the new value of the state, such as
- 'draft' or 'close'.
- :params update_values: values that will be added with the state
- update when writing values to the record.
- """
- cases = self.browse(cr, uid, ids, context=context)
- # 1. update the stage
- if new_state_name:
- self.stage_set_with_state_name(cr, uid, cases, new_state_name, context=context)
- elif not (new_stage_id is None):
- self.stage_set(cr, uid, ids, new_stage_id, context=context)
- # 2. update values
- if values_to_update:
- self.write(cr, uid, ids, values_to_update, context=context)
- return True
diff --git a/addons/base_status/i18n/bs.po b/addons/base_status/i18n/bs.po
new file mode 100644
index 00000000000..0fdd8821dd2
--- /dev/null
+++ b/addons/base_status/i18n/bs.po
@@ -0,0 +1,80 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-08-08 22:20+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-09 05:06+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid "Error !"
+msgstr "Greška !"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:166
+#, python-format
+msgid "%s has been <b>opened</b>."
+msgstr "%s je bio <b>otvoren</b>."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:199
+#, python-format
+msgid "%s has been <b>renewed</b>."
+msgstr "%s je bio <b>obnovljen</b>."
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid "Error!"
+msgstr "Greška!"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid ""
+"You can not escalate, you are already at the top level regarding your sales-"
+"team category."
+msgstr ""
+"Ne možete eskalirati, već ste na najvišem nivou u odnosu na kategoriju "
+"prodajnog tima."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:193
+#, python-format
+msgid "%s is now <b>pending</b>."
+msgstr "%s je sad <b>Na čekanju</b>."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:187
+#, python-format
+msgid "%s has been <b>canceled</b>."
+msgstr "%s je bio <b>otkazan</b>."
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid ""
+"You are already at the top level of your sales-team category.\n"
+"Therefore you cannot escalate furthermore."
+msgstr ""
+"Već ste na najvišem nivou vaše kategorije prodajnog tima.\n"
+"Zato ne možete dalje eskalirati."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:181
+#, python-format
+msgid "%s has been <b>closed</b>."
+msgstr "%s je bio <b>zatvoren</b>."
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index e7ab7df27ea..3e6b55006fa 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -116,6 +116,7 @@ Dashboard for CRM will include:
'test/crm_lead_onchange.yml',
'test/crm_lead_copy.yml',
'test/crm_lead_unlink.yml',
+ 'test/crm_lead_find_stage.yml',
],
'css': [
'static/src/css/crm.css'
diff --git a/addons/crm/board_crm_view.xml b/addons/crm/board_crm_view.xml
index 19baa5a5709..6bbd450ca38 100644
--- a/addons/crm/board_crm_view.xml
+++ b/addons/crm/board_crm_view.xml
@@ -19,7 +19,11 @@
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_stage_graph"/>
- <field name="domain">[('state', 'not in', ('done', 'cancel')), ('type', '=', 'opportunity')]</field>
+ <!-- avoid done / cancelled -->
+ <field name="domain">['|',
+ '!', '&amp;', ('probability', '=', 100), ('stage_id.on_change', '=', 1),
+ '!', '&amp;', ('probability', '=', 0), ('stage_id.sequence', '!=', 1),
+ ('type', '=', 'opportunity')]</field>
<field name="context">{'search_default_Stage':1}</field>
</record>
@@ -43,8 +47,9 @@
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_user_stage_graph"/>
- <field name="domain">[('state','!=','cancel'),('opening_date','&gt;',context_today().strftime("%Y-%m-%d"))]</field>
- <field name="context">{'search_default_Stage':1}</field>
+ <!-- avoid cancelled -->
+ <field name="domain">['!', '&amp;', ('probability', '=', 0), ('stage_id.sequence', '!=', 1)]</field>
+ <field name="context">{'search_default_user': 1, 'search_default_Stage': 1}</field>
</record>
<record model="ir.ui.view" id="board_crm_statistical_form">
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index d1194508b71..04a17b9dbc0 100644
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -26,15 +26,6 @@ from openerp import tools
from openerp.osv import fields
from openerp.osv import osv
-MAX_LEVEL = 15
-AVAILABLE_STATES = [
- ('draft', 'New'),
- ('cancel', 'Cancelled'),
- ('open', 'In Progress'),
- ('pending', 'Pending'),
- ('done', 'Closed')
-]
-
AVAILABLE_PRIORITIES = [
('1', 'Highest'),
('2', 'High'),
@@ -72,16 +63,13 @@ class crm_case_stage(osv.osv):
'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"),
'on_change': fields.boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity."),
'requirements': fields.text('Requirements'),
- 'section_ids':fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', string='Sections',
+ 'section_ids': fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', string='Sections',
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
- 'state': fields.selection(AVAILABLE_STATES, 'Related Status', required=True,
- help="The status of your document will automatically change regarding the selected stage. " \
- "For example, if a stage is related to the status 'Close', when your document reaches this stage, it is automatically closed."),
'case_default': fields.boolean('Default to New Sales Team',
help="If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams."),
'fold': fields.boolean('Fold by Default',
help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
- 'type': fields.selection([ ('lead','Lead'),
+ 'type': fields.selection([('lead', 'Lead'),
('opportunity', 'Opportunity'),
('both', 'Both')],
string='Type', size=16, required=True,
@@ -91,7 +79,7 @@ class crm_case_stage(osv.osv):
_defaults = {
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
- 'state': 'open',
+ 'on_change': True,
'fold': False,
'type': 'both',
'case_default': True,
diff --git a/addons/crm/crm_action_rule_demo.xml b/addons/crm/crm_action_rule_demo.xml
index 569b2d676e0..8eac91c06e2 100644
--- a/addons/crm/crm_action_rule_demo.xml
+++ b/addons/crm/crm_action_rule_demo.xml
@@ -5,7 +5,7 @@
<record id="filter_draft_lead" model="ir.filters">
<field name="name">Draft Leads</field>
<field name="model_id">crm.lead</field>
- <field name="domain">[('state','=','draft')]</field>
+ <field name="domain">[('stage_id.sequence', '=', 1)]</field>
<field name="user_id" eval="False"/>
</record>
<record id="action_email_reminder_lead" model="ir.actions.server">
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index c0f003f9792..65d096c6a51 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -22,14 +22,13 @@
import crm
from datetime import datetime
from operator import itemgetter
-from openerp.osv import fields, osv, orm
-import time
+
from openerp import SUPERUSER_ID
from openerp import tools
-from openerp.tools.translate import _
-from openerp.tools import html2plaintext
-
from openerp.addons.base.res.res_partner import format_address
+from openerp.osv import fields, osv, orm
+from openerp.tools import html2plaintext
+from openerp.tools.translate import _
CRM_LEAD_FIELDS_TO_MERGE = ['name',
'partner_id',
@@ -61,11 +60,7 @@ CRM_LEAD_FIELDS_TO_MERGE = ['name',
'email_from',
'email_cc',
'partner_name']
-CRM_LEAD_PENDING_STATES = (
- crm.AVAILABLE_STATES[2][0], # Cancelled
- crm.AVAILABLE_STATES[3][0], # Done
- crm.AVAILABLE_STATES[4][0], # Pending
-)
+
class crm_lead(format_address, osv.osv):
""" CRM Lead Case """
@@ -75,13 +70,11 @@ class crm_lead(format_address, osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
- 'state': {
- 'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj.state in ['new', 'draft'],
- 'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.state == 'done',
- 'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.state == 'cancel',
- },
'stage_id': {
- 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj.state not in ['new', 'draft', 'cancel', 'done'],
+ 'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.sequence == 1,
+ 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: (obj.stage_id and obj.stage_id.sequence != 1) and obj.probability < 100,
+ 'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.probability == 100 and obj.stage_id and obj.stage_id.on_change,
+ 'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.sequence != 1,
},
}
@@ -99,7 +92,7 @@ class crm_lead(format_address, osv.osv):
def _get_default_stage_id(self, cr, uid, context=None):
""" Gives default stage_id """
section_id = self._get_default_section_id(cr, uid, context=context)
- return self.stage_find(cr, uid, [], section_id, [('state', '=', 'draft')], context=context)
+ return self.stage_find(cr, uid, [], section_id, [('sequence', '=', '1')], context=context)
def _resolve_section_id_from_context(self, cr, uid, context=None):
""" Returns ID of section based on the value of 'section_id'
@@ -150,7 +143,7 @@ class crm_lead(format_address, osv.osv):
stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context)
result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
# restore order of the search
- result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
+ result.sort(lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
fold = {}
for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context):
@@ -158,7 +151,7 @@ class crm_lead(format_address, osv.osv):
return result, fold
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
- res = super(crm_lead,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
+ res = super(crm_lead, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
if view_type == 'form':
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
return res
@@ -220,17 +213,6 @@ class crm_lead(format_address, osv.osv):
res[lead.id][field] = abs(int(duration))
return res
- def _history_search(self, cr, uid, obj, name, args, context=None):
- res = []
- msg_obj = self.pool.get('mail.message')
- message_ids = msg_obj.search(cr, uid, [('email_from','!=',False), ('subject', args[0][1], args[0][2])], context=context)
- lead_ids = self.search(cr, uid, [('message_ids', 'in', message_ids)], context=context)
-
- if lead_ids:
- return [('id', 'in', lead_ids)]
- else:
- return [('id', '=', '0')]
-
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange',
select=True, help="Linked partner (optional). Usually created when converting the lead."),
@@ -243,10 +225,10 @@ class crm_lead(format_address, osv.osv):
'email_from': fields.char('Email', size=128, help="Email address of the contact", select=1),
'section_id': fields.many2one('crm.case.section', 'Sales Team',
select=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the sales team.'),
- 'create_date': fields.datetime('Creation Date' , readonly=True),
- 'email_cc': fields.text('Global CC', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
+ 'create_date': fields.datetime('Creation Date', readonly=True),
+ 'email_cc': fields.text('Global CC', help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
'description': fields.text('Notes'),
- 'write_date': fields.datetime('Update Date' , readonly=True),
+ 'write_date': fields.datetime('Update Date', readonly=True),
'categ_ids': fields.many2many('crm.case.categ', 'crm_lead_category_rel', 'lead_id', 'category_id', 'Categories', \
domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]"),
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
@@ -264,17 +246,15 @@ class crm_lead(format_address, osv.osv):
domain="['&', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"),
'user_id': fields.many2one('res.users', 'Salesperson', select=True, track_visibility='onchange'),
'referred': fields.char('Referred By', size=64),
- 'date_open': fields.datetime('Opened', readonly=True),
+ 'date_open': fields.datetime('Assigned', readonly=True),
'day_open': fields.function(_compute_day, string='Days to Open', \
multi='day_open', type="float", store=True),
'day_close': fields.function(_compute_day, string='Days to Close', \
multi='day_close', type="float", store=True),
- 'state': fields.related('stage_id', 'state', type="selection", store=True,
- selection=crm.AVAILABLE_STATES, string="Status", readonly=True,
- help='The Status is set to \'Draft\', when a case is created. If the case is in progress the Status is set to \'Open\'. When the case is over, the Status is set to \'Done\'. If the case needs to be reviewed then the Status is set to \'Pending\'.'),
+ 'date_last_stage_update': fields.datetime('Last Stage Update', select=True),
# Only used for type opportunity
- 'probability': fields.float('Success Rate (%)',group_operator="avg"),
+ 'probability': fields.float('Success Rate (%)', group_operator="avg"),
'planned_revenue': fields.float('Expected Revenue', track_visibility='always'),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
@@ -316,6 +296,7 @@ class crm_lead(format_address, osv.osv):
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
'color': 0,
+ 'date_last_stage_update': fields.datetime.now(),
}
_sql_constraints = [
@@ -325,7 +306,7 @@ class crm_lead(format_address, osv.osv):
def onchange_stage_id(self, cr, uid, ids, stage_id, context=None):
if not stage_id:
return {'value': {}}
- stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context)
+ stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context=context)
if not stage.on_change:
return {'value': {}}
return {'value': {'probability': stage.probability}}
@@ -358,22 +339,6 @@ class crm_lead(format_address, osv.osv):
section_id = section_ids[0]
return {'value': {'section_id': section_id}}
- def _check(self, cr, uid, ids=False, context=None):
- """ Override of the base.stage method.
- Function called by the scheduler to process cases for date actions
- Only works on not done and cancelled cases
- """
- cr.execute('select * from crm_case \
- where (date_action_last<%s or date_action_last is null) \
- and (date_action_next<=%s or date_action_next is null) \
- and state not in (\'cancel\',\'done\')',
- (time.strftime("%Y-%m-%d %H:%M:%S"),
- time.strftime('%Y-%m-%d %H:%M:%S')))
-
- ids2 = map(lambda x: x[0], cr.fetchall() or [])
- cases = self.browse(cr, uid, ids2, context=context)
- return self._action(cr, uid, cases, False, context=context)
-
def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None):
""" Override of the base.stage method
Parameter of the stage search taken from the lead:
@@ -385,16 +350,16 @@ class crm_lead(format_address, osv.osv):
if isinstance(cases, (int, long)):
cases = self.browse(cr, uid, cases, context=context)
# collect all section_ids
- section_ids = []
+ section_ids = set()
types = ['both']
if not cases:
- type = context.get('default_type')
- types += [type]
+ ctx_type = context.get('default_type')
+ types += [ctx_type]
if section_id:
- section_ids.append(section_id)
+ section_ids.add(section_id)
for lead in cases:
if lead.section_id:
- section_ids.append(lead.section_id.id)
+ section_ids.add(lead.section_id.id)
if lead.type not in types:
types.append(lead.type)
# OR all section_ids and OR with case_default
@@ -403,8 +368,7 @@ class crm_lead(format_address, osv.osv):
search_domain += [('|')] * len(section_ids)
for section_id in section_ids:
search_domain.append(('section_ids', '=', section_id))
- else:
- search_domain.append(('case_default', '=', True))
+ search_domain.append(('case_default', '=', True))
# AND with cases types
search_domain.append(('type', 'in', types))
# AND with the domain in parameter
@@ -415,27 +379,29 @@ class crm_lead(format_address, osv.osv):
return stage_ids[0]
return False
- def stage_set(self, cr, uid, ids, stage_id, context=None):
- """ Set the new stage. Now just writes the stage.
- TDE TODO: remove me when removing state
- """
- return self.write(cr, uid, ids, {'stage_id': stage_id}, context=context)
-
def case_mark_lost(self, cr, uid, ids, context=None):
""" Mark the case as lost: state=cancel and probability=0 """
for lead in self.browse(cr, uid, ids):
- stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 0.0),('on_change','=',True)], context=context)
+ stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 0.0), ('on_change', '=', True), ('sequence', '>', 1)], context=context)
if stage_id:
- self.stage_set(cr, uid, [lead.id], stage_id, context=context)
- return True
+ return self.write(cr, uid, [lead.id], {'stage_id': stage_id}, context=context)
+ else:
+ raise osv.except_osv(_('Warning!'),
+ _('To relieve your sales pipe and group all Lost opportunities, configure one of your sales stage as follow:\n'
+ 'probability = 0 %, select "Change Probability Automatically".\n'
+ 'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
def case_mark_won(self, cr, uid, ids, context=None):
""" Mark the case as won: state=done and probability=100 """
for lead in self.browse(cr, uid, ids):
- stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 100.0),('on_change','=',True)], context=context)
+ stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 100.0), ('on_change', '=', True), ('sequence', '>', 1)], context=context)
if stage_id:
- self.stage_set(cr, uid, [lead.id], stage_id, context=context)
- return True
+ return self.write(cr, uid, [lead.id], {'stage_id': stage_id}, context=context)
+ else:
+ raise osv.except_osv(_('Warning!'),
+ _('To relieve your sales pipe and group all Won opportunities, configure one of your sales stage as follow:\n'
+ 'probability = 100 % and select "Change Probability Automatically".\n'
+ 'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
def case_escalate(self, cr, uid, ids, context=None):
""" Escalates case to parent level """
@@ -451,20 +417,20 @@ class crm_lead(format_address, osv.osv):
self.write(cr, uid, [case.id], data, context=context)
return True
- def set_priority(self, cr, uid, ids, priority):
+ def set_priority(self, cr, uid, ids, priority, context=None):
""" Set lead priority
"""
- return self.write(cr, uid, ids, {'priority' : priority})
+ return self.write(cr, uid, ids, {'priority': priority}, context=context)
def set_high_priority(self, cr, uid, ids, context=None):
""" Set lead priority to high
"""
- return self.set_priority(cr, uid, ids, '1')
+ return self.set_priority(cr, uid, ids, '1', context=context)
def set_normal_priority(self, cr, uid, ids, context=None):
""" Set lead priority to normal
"""
- return self.set_priority(cr, uid, ids, '3')
+ return self.set_priority(cr, uid, ids, '3', context=context)
def _merge_get_result_type(self, cr, uid, opps, context=None):
"""
@@ -640,7 +606,8 @@ class crm_lead(format_address, osv.osv):
sequenced_opps = []
for opportunity in opportunities:
sequence = -1
- if opportunity.stage_id and opportunity.stage_id.state != 'cancel':
+ # TDE: was "if opportunity.stage_id and opportunity.stage_id.state != 'cancel':"
+ if opportunity.probability == 0 and opportunity.stage_id and opportunity.stage_id.sequence != 1 and opportunity.stage_id.fold:
sequence = opportunity.stage_id.sequence
sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity))
@@ -701,7 +668,7 @@ class crm_lead(format_address, osv.osv):
'phone': customer and customer.phone or lead.phone,
}
if not lead.stage_id or lead.stage_id.type=='lead':
- val['stage_id'] = self.stage_find(cr, uid, [lead], section_id, [('state', '=', 'draft'),('type', 'in', ('opportunity','both'))], context=context)
+ val['stage_id'] = self.stage_find(cr, uid, [lead], section_id, [('sequence', '=', '1'), ('type', 'in', ('opportunity','both'))], context=context)
return val
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
@@ -710,7 +677,8 @@ class crm_lead(format_address, osv.osv):
partner = self.pool.get('res.partner')
customer = partner.browse(cr, uid, partner_id, context=context)
for lead in self.browse(cr, uid, ids, context=context):
- if lead.state in ('done', 'cancel'):
+ # TDE: was if lead.state in ('done', 'cancel'):
+ if (lead.probability == '100') or (lead.probability == '0' and lead.stage_id.sequence != '1'):
continue
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
self.write(cr, uid, [lead.id], vals, context=context)
@@ -940,6 +908,10 @@ class crm_lead(format_address, osv.osv):
return super(crm_lead, self).create(cr, uid, vals, context=create_context)
def write(self, cr, uid, ids, vals, context=None):
+ # stage change: update date_last_stage_update
+ if 'stage_id' in vals:
+ vals['date_last_stage_update'] = fields.datetime.now()
+ # stage change with new stage: update probability
if vals.get('stage_id') and not vals.get('probability'):
onchange_stage_values = self.onchange_stage_id(cr, uid, ids, vals.get('stage_id'), context=context)['value']
vals.update(onchange_stage_values)
diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml
index 219ff2cdeee..3c299fef704 100644
--- a/addons/crm/crm_lead_data.xml
+++ b/addons/crm/crm_lead_data.xml
@@ -5,71 +5,57 @@
<!-- Crm stages -->
<record model="crm.case.stage" id="stage_lead1">
<field name="name">New</field>
- <field eval="1" name="case_default"/>
- <field name="state">draft</field>
- <field eval="0" name="probability"/>
- <field eval="10" name="sequence"/>
+ <field name="case_default">1</field>
+ <field name="probability">0</field>
+ <field name="on_change">1</field>
+ <field name="sequence">1</field>
<field name="type">both</field>
</record>
<record model="crm.case.stage" id="stage_lead2">
- <field name="name">Opportunity</field>
- <field eval="1" name="case_default"/>
- <field name="state">open</field>
- <field eval="20" name="probability"/>
- <field eval="20" name="sequence"/>
- <field name="type">lead</field>
- </record>
- <record model="crm.case.stage" id="stage_lead7">
<field name="name">Dead</field>
- <field eval="1" name="case_default"/>
- <field eval="False" name="fold"/>
- <field name="state">cancel</field>
- <field eval="0" name="probability"/>
- <field eval="30" name="sequence"/>
+ <field name="case_default">1</field>
+ <field name="probability">0</field>
+ <field name="on_change">1</field>
+ <field name="sequence">30</field>
<field name="type">lead</field>
</record>
<record model="crm.case.stage" id="stage_lead3">
<field name="name">Qualification</field>
- <field eval="1" name="case_default"/>
- <field name="state">open</field>
- <field eval="20" name="probability"/>
- <field eval="100" name="sequence"/>
+ <field name="case_default">1</field>
+ <field name="probability">20</field>
+ <field name="on_change">1</field>
+ <field name="sequence">40</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead4">
<field name="name">Proposition</field>
- <field eval="1" name="case_default"/>
- <field name="state">open</field>
- <field eval="40" name="probability"/>
- <field eval="110" name="sequence"/>
+ <field name="case_default">1</field>
+ <field name="probability">40</field>
+ <field name="sequence">50</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead5">
<field name="name">Negotiation</field>
- <field eval="1" name="case_default"/>
- <field name="state">open</field>
- <field eval="60" name="probability"/>
- <field eval="120" name="sequence"/>
+ <field name="case_default">1</field>
+ <field name="probability">60</field>
+ <field name="sequence">60</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Won</field>
- <field eval="True" name="fold"/>
- <field eval="1" name="case_default"/>
- <field name="state">done</field>
- <field eval="100" name="probability"/>
- <field eval="130" name="sequence"/>
- <field eval="1" name="on_change"/>
+ <field name="case_default">1</field>
+ <field name="probability">100</field>
+ <field name="on_change">1</field>
+ <field name="sequence">70</field>
<field name="type">opportunity</field>
</record>
- <record model="crm.case.stage" id="stage_lead8">
+ <record model="crm.case.stage" id="stage_lead7">
<field name="name">Lost</field>
- <field eval="1" name="case_default"/>
- <field eval="True" name="fold"/>
- <field eval="1" name="on_change"/>
- <field name="state">cancel</field>
- <field eval="0" name="probability"/>
- <field eval="140" name="sequence"/>
+ <field name="case_default">1</field>
+ <field name="fold">1</field>
+ <field name="probability">0</field>
+ <field name="on_change">1</field>
+ <field name="sequence">80</field>
<field name="type">opportunity</field>
</record>
@@ -77,7 +63,7 @@
<field name="stage_ids" eval="[ (4, ref('stage_lead1')), (4, ref('stage_lead2')),
(4, ref('stage_lead3')), (4, ref('stage_lead4')),
(4, ref('stage_lead5')), (4, ref('stage_lead6')),
- (4, ref('stage_lead7')), (4, ref('stage_lead8'))]"/>
+ (4, ref('stage_lead7'))]"/>
</record>
<!-- Crm campain -->
@@ -161,7 +147,7 @@
<field name="name">Lead Created</field>
<field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
- <field name="description">Opportunity created</field>
+ <field name="description">Lead created</field>
</record>
<record id="mt_lead_stage" model="mail.message.subtype">
<field name="name">Stage Changed</field>
diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml
index 3917fadbd32..dab17888d7a 100644
--- a/addons/crm/crm_lead_demo.xml
+++ b/addons/crm/crm_lead_demo.xml
@@ -6,9 +6,9 @@
<record id="crm_case_1" model="crm.lead">
<field name="type">lead</field>
<field name="name">Plan to Attend a Training</field>
- <field name="contact_name">Jason Dunagan</field>
+ <field name="contact_name">Jacques Dunagan</field>
<field name="partner_name">Le Club SARL</field>
- <field name="email_from">jason@leclub.fr</field>
+ <field name="email_from">jdunagan@leclub.fr</field>
<field name="partner_id" ref=""/>
<field name="function">Training Manager</field>
<field name="street">73, rue Léon Dierx</field>
@@ -20,14 +20,25 @@
<field name="categ_ids" eval="[(6, 0, [categ_oppor6])]"/>
<field name="channel_id" ref="crm_case_channel_email"/>
<field name="priority">1</field>
- <field name="section_id" ref="crm_case_section_2"/>
+ <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description">Hello,
-I am Jason from Le Club SARL.
-I am intertested to attend a training organized in your company.
-Can you send me the details ?</field>
- <field eval="1" name="active"/>
+I am Jacques from Le Club SARL.
+I am interested to attend a training organized in your company.
+Could you please send me the details ?</field>
+ </record>
+ <record id="crm_case_1" model="crm.lead">
+ <field name="create_date" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
+ </record>
+ <record id="msg_case1_1" model="mail.message">
+ <field name="subject">Inquiry</field>
+ <field name="model">crm.lead</field>
+ <field name="res_id" ref="crm_case_1"/>
+ <field name="body"><![CDATA[<p>Hello,<br />
+ I am Jacques from Le Club SARL. I am interested to attend a training organized in your company.<br />
+ Can you send me the details ?</p>]]></field>
+ <field name="type">email</field>
</record>
<record id="crm_case_2" model="crm.lead">
@@ -44,10 +55,20 @@ Can you send me the details ?</field>
<field name="categ_ids" eval="[(6, 0, [categ_oppor2])]"/>
<field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">4</field>
- <field name="section_id" ref="crm_case_section_2"/>
+ <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
- <field eval="1" name="active"/>
+ </record>
+ <record id="crm_case_2" model="crm.lead">
+ <field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
+ </record>
+ <record id="msg_case2_1" model="mail.message">
+ <field name="subject">Need Details</field>
+ <field name="model">crm.lead</field>
+ <field name="author_id" ref="base.partner_demo"/>
+ <field name="res_id" ref="crm_case_2"/>
+ <field name="body">Want to know features and benefits to use the new software.</field>
+ <field name="type">comment</field>
</record>
<record id="crm_case_3" model="crm.lead">
@@ -65,8 +86,10 @@ Can you send me the details ?</field>
<field name="priority">2</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="stage_lead2"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="stage_lead1"/>
+ </record>
+ <record id="crm_case_2" model="crm.lead">
+ <field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="crm_case_4" model="crm.lead">
@@ -82,10 +105,12 @@ Can you send me the details ?</field>
<field name="categ_ids" eval="[(6, 0, [categ_oppor5])]"/>
<field name="channel_id" ref=""/>
<field name="priority">3</field>
- <field name="section_id" ref="crm_case_section_1"/>
- <field name="user_id" ref=""/>
- <field name="stage_id" ref="stage_lead7"/>
- <field eval="1" name="active"/>
+ <field name="section_id" ref="crm_case_section_2"/>
+ <field name="user_id" ref="base.user_demo"/>
+ <field name="stage_id" ref="stage_lead6"/>
+ </record>
+ <record id="crm_case_2" model="crm.lead">
+ <field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="crm_case_5" model="crm.lead">
@@ -105,8 +130,8 @@ Can you send me the details ?</field>
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
<field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">3</field>
- <field name="section_id" ref="section_sales_department"/>
- <field name="user_id" ref="base.user_root"/>
+ <field name="section_id" ref="crm_case_section_1"/>
+ <field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description">Hi,
Can you send me a quotation for 20 computers with speakers?
@@ -116,7 +141,6 @@ Purchase Manager
Stonage IT,
Franklinville
Contact: +1 813 494 5005</field>
- <field eval="1" name="active"/>
</record>
<record id="crm_case_6" model="crm.lead">
@@ -134,9 +158,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref=""/>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/>
- <field name="user_id" ref="base.user_root"/>
+ <field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
- <field eval="1" name="active"/>
</record>
<record id="crm_case_7" model="crm.lead">
@@ -153,9 +176,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref=""/>
<field name="priority">5</field>
<field name="section_id" ref="crm_case_section_2"/>
- <field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="stage_lead7"/>
- <field eval="1" name="active"/>
+ <field name="user_id" ref="base.user_root"/>
+ <field name="stage_id" ref="stage_lead1"/>
</record>
<record id="crm_case_8" model="crm.lead">
@@ -173,9 +195,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref=""/>
<field name="priority">4</field>
<field name="section_id" ref="section_sales_department"/>
- <field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="stage_lead7"/>
- <field eval="1" name="active"/>
+ <field name="user_id" ref="base.user_root"/>
+ <field name="stage_id" ref="stage_lead1"/>
</record>
<record id="crm_case_9" model="crm.lead">
@@ -193,12 +214,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref="crm_case_channel_phone"/>
<field name="priority">2</field>
<field name="section_id" ref="section_sales_department"/>
- <field name="user_id" ref="base.user_root"/>
+ <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead1"/>
- <field eval="1" name="active"/>
- </record>
- <record id="crm_case_9" model="crm.lead">
- <field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="crm_case_10" model="crm.lead">
@@ -215,14 +232,13 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref="crm_case_channel_email"/>
<field name="priority">2</field>
<field name="section_id" ref="crm_case_section_2"/>
- <field name="user_id" ref=""/>
+ <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description">Hi,
I would like to know more about specification and cost of laptops of your company.
Thanks,
Andrew</field>
- <field eval="1" name="active"/>
</record>
<record id="crm_case_11" model="crm.lead">
@@ -239,9 +255,8 @@ Andrew</field>
<field name="channel_id" ref="crm_case_channel_direct"/>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_1"/>
- <field name="user_id" ref="base.user_demo"/>
+ <field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
- <field eval="1" name="active"/>
</record>
<record id="crm_case_12" model="crm.lead">
@@ -258,15 +273,23 @@ Andrew</field>
<field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">2</field>
<field name="section_id" ref="section_sales_department"/>
- <field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="stage_lead2"/>
- <field eval="1" name="active"/>
+ <field name="user_id" ref=""/>
+ <field name="stage_id" ref="stage_lead1"/>
</record>
+ <!-- Call Function to Cancel the leads (set as Dead) -->
+ <function model="crm.lead" name="write"
+ eval="[ ref('crm_case_7'), ref('crm_case_8'),
+ ref('crm_case_9'), ref('crm_case_10'),
+ ref('crm_case_11'), ref('crm_case_12')],
+ {'stage_id': ref('stage_lead2')},
+ {'install_mode': True}"
+ />
+
<!-- Call Function to set the leads as Unread -->
<function model="crm.lead" name="message_mark_as_unread"
eval="[ ref('crm_case_1'), ref('crm_case_2'),
- ref('crm_case_5'), ref('crm_case_11')], {}"
+ ref('crm_case_5'), ref('crm_case_6')], {}"
/>
<!-- Demo Opportunities -->
@@ -289,8 +312,7 @@ Andrew</field>
<field name="title_action">Meeting for pricing information.</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
- <field name="stage_id" ref="crm.stage_lead3"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead1"/>
</record>
<record id="crm_case_14" model="crm.lead">
@@ -316,7 +338,6 @@ Andrew</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/>
- <field eval="1" name="active"/>
</record>
<record id="crm_case_15" model="crm.lead">
@@ -337,10 +358,12 @@ Andrew</field>
<field name="title_action">Call to ask system requirement</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead3"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
</record>
+ <record id="crm_case_15" model="crm.lead">
+ <field name="message_follower_ids" eval="[(3, ref('base.partner_root')), (4, ref('base.partner_demo'))]"/>
+ </record>
<record id="crm_case_16" model="crm.lead">
<field name="type">opportunity</field>
@@ -362,8 +385,7 @@ Andrew</field>
<field name="title_action">Convert to quote</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead3"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
@@ -388,10 +410,12 @@ Andrew</field>
<field name="title_action">Send price list regarding our interventions</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead4"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
+ <record id="crm_case_17" model="crm.lead">
+ <field name="message_follower_ids" eval="[(3, ref('base.partner_root')), (4, ref('base.partner_demo'))]"/>
+ </record>
<record id="crm_case_18" model="crm.lead">
<field name="type">opportunity</field>
@@ -413,9 +437,12 @@ Andrew</field>
<field name="title_action">Call to define real needs about training</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead3"/>
+ <field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/>
</record>
+ <record id="crm_case_18" model="crm.lead">
+ <field name="message_follower_ids" eval="[(4, ref('base.partner_demo'))]"/>
+ </record>
<record id="crm_case_19" model="crm.lead">
<field name="type">opportunity</field>
@@ -437,8 +464,7 @@ Andrew</field>
<field name="title_action">Ask for the good receprion of the proposition</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead4"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=3)).strftime('%Y-%m-%d %H:%M')"/>
</record>
@@ -455,8 +481,7 @@ Andrew</field>
<field name="priority">2</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead1"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead4"/>
</record>
<record id="crm_case_21" model="crm.lead">
@@ -470,8 +495,7 @@ Andrew</field>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead4"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
@@ -489,8 +513,7 @@ Andrew</field>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/>
- <field name="stage_id" ref="crm.stage_lead8"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead5"/>
</record>
<record id="crm_case_23" model="crm.lead">
@@ -505,8 +528,7 @@ Andrew</field>
<field name="priority">5</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead5"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
@@ -525,8 +547,7 @@ Andrew</field>
<field eval="time.strftime('%Y-%m-6')" name="date_deadline"/>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead5"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(month=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
@@ -549,8 +570,7 @@ Andrew</field>
<field name="title_action">Conf call with technical service</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/>
- <field name="stage_id" ref="crm.stage_lead4"/>
- <field eval="1" name="active"/>
+ <field name="stage_id" ref="crm.stage_lead5"/>
</record>
<record id="crm_case_26" model="crm.lead">
@@ -574,21 +594,10 @@ Andrew</field>
<field name="title_action">Send Catalogue by Email</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_demo"/>
- <field name="stage_id" ref="crm.stage_lead6"/>
- <field eval="1" name="active"/>
- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
+ <field name="stage_id" ref="crm.stage_lead5"/>
+ <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
- <!-- Unsubscribe Admin from case15, subscribe Demo -->
- <record id="crm_case_15" model="crm.lead">
- <field name="message_follower_ids" eval="[(3, ref('base.partner_root')), (4, ref('base.partner_demo'))]"/>
- </record>
- <record id="crm_case_17" model="crm.lead">
- <field name="message_follower_ids" eval="[(3, ref('base.partner_root')), (4, ref('base.partner_demo'))]"/>
- </record>
- <record id="crm_case_18" model="crm.lead">
- <field name="message_follower_ids" eval="[(4, ref('base.partner_demo'))]"/>
- </record>
<!-- Some messages linked to the previous opportunities -->
<record id="msg_case15_attach1" model="ir.attachment">
<field name="datas">bWlncmF0aW9uIHRlc3Q=</field>
@@ -682,26 +691,9 @@ Andrew</field>
<field name="parent_id" ref="msg_case18_1"/>
<field name="author_id" ref="base.partner_demo"/>
</record>
- <record id="msg_case1_1" model="mail.message">
- <field name="subject">Inquiry</field>
- <field name="model">crm.lead</field>
- <field name="res_id" ref="crm_case_1"/>
- <field name="body"><![CDATA[<p>Hello,<br />
- I am Jason from Le Club SARL. I am interested to attend a training organized in your company.<br />
- Can you send me the details ?</p>]]></field>
- <field name="type">email</field>
- </record>
- <record id="msg_case2_1" model="mail.message">
- <field name="subject">Need Details</field>
- <field name="model">crm.lead</field>
- <field name="res_id" ref="crm_case_2"/>
- <field name="body">Want to know features and benefits to use the new software.</field>
- <field name="type">comment</field>
- </record>
<function model="mail.message" name="set_message_starred"
eval="[ ref('msg_case18_1'), ref('msg_case18_2')], True, {}"
/>
-
</data>
</openerp>
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index aa5aac76b9d..849cecaac85 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -12,9 +12,10 @@
<field name="model">crm.case.stage</field>
<field name="arch" type="xml">
<search string="Stage Search">
- <field name="name" string="Stage Name"/>
- <field name="state"/>
+ <field name="name"/>
<field name="type"/>
+ <field name="sequence"/>
+ <field name="probability"/>
</search>
</field>
</record>
@@ -94,7 +95,8 @@
<form string="Leads Form" version="7.0">
<header>
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action"
- states="draft,open,pending" help="Convert to Opportunity" class="oe_highlight"/>
+ attrs="{'invisible': [('probability', '=', 100)]}"
+ help="Convert to Opportunity" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"
on_change="onchange_stage_id(stage_id)"/>
@@ -140,12 +142,6 @@
<field name="phone"/>
<field name="mobile"/>
<field name="fax"/>
- <!--
- This should be integrated in Open Chatter
- <button string="Mail"
- name="%(mail.action_email_compose_message_wizard)d"
- icon="terp-mail-message-new" type="action" colspan="1"/>
- -->
</group>
<group>
<field name="user_id" on_change="on_change_user(user_id, context)"
@@ -155,7 +151,7 @@
<field name="section_id"/>
<button name="case_escalate" string="Escalate"
type="object" class="oe_link"
- attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
+ attrs="{'invisible': ['|', ('section_id','=',False), ('probability', '=', 100)]}"/>
</div>
<field name="type" invisible="1"/>
</group>
@@ -173,20 +169,24 @@
<field name="description"/>
</page>
<page string="Extra Info">
- <group>
- <group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
- <field name="company_id"
- groups="base.group_multi_company"
- widget="selection" colspan="2"/>
- <field name="state" groups="base.group_no_one"/>
- </group>
- <group string="Mailings">
- <field name="opt_out"/>
- </group>
- <group string="Misc">
+ <group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
+ <field name="company_id"
+ groups="base.group_multi_company"
+ widget="selection" colspan="2"/>
+ </group>
+ <group string="Mailings">
+ <field name="opt_out"/>
+ </group>
+ <group string="Misc">
+ <group>
+ <field name="probability" groups="base.group_no_one"/>
<field name="active"/>
<field name="referred"/>
</group>
+ <group>
+ <field name="date_open" groups="base.group_no_one"/>
+ <field name="date_closed" groups="base.group_no_one"/>
+ </group>
</group>
</page>
</notebook>
@@ -216,7 +216,7 @@
<field name="name">Leads</field>
<field name="model">crm.lead</field>
<field name="arch" type="xml">
- <tree string="Leads" fonts="bold:message_unread==True" colors="grey:state in ('cancel', 'done')">
+ <tree string="Leads" fonts="bold:message_unread==True" colors="grey:probability == 100">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name"/>
@@ -228,7 +228,7 @@
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="section_id" invisible="context.get('invisible_section', True)" groups="base.group_multi_salesteams"/>
- <field name="state" invisible="1"/>
+ <field name="probability" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="referred" invisible="1"/>
<field name="channel_id" invisible="1"/>
@@ -258,7 +258,6 @@
<field name="model">crm.lead</field>
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
- <field name="state" groups="base.group_no_one"/>
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
@@ -331,16 +330,17 @@
<field name="create_date"/>
<field name="country_id" context="{'invisible_country': False}"/>
<separator/>
- <filter string="Open" name="open" domain="[('state','!=','cancel')]" help="Open Leads"/>
- <filter string="Dead" name="dead" domain="[('state','=','cancel')]"/>
- <filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
- <filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
+ <filter string="Unassigned" name="unassigned"
+ domain="[('user_id','=', False)]"
+ help="No salesperson"/>
<filter string="Assigned to Me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
help="Leads that are assigned to me"/>
- <filter string="Assigned to My Team(s)"
+ <filter string="Assigned to My Team(s)" groups="base.group_multi_salesteams"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}"
- help="Leads that are assigned to any sales teams I am member of" groups="base.group_multi_salesteams"/>
+ help="Leads that are assigned to any sales teams I am member of"/>
+ <filter string="Dead" name="dead"
+ domain="[('probability', '=', '0'), ('stage_id.sequence', '!=', 1)]"/>
<separator />
<filter string="Available for mass mailing"
name='not_opt_out' domain="[('opt_out', '=', False)]"
@@ -378,20 +378,19 @@
<field name="arch" type="xml">
<form string="Opportunities" version="7.0">
<header>
- <button name="case_mark_won" string="Mark Won" type="object"
- states="draft,open,pending" class="oe_highlight"/>
- <button name="case_mark_lost" string="Mark Lost" type="object"
- states="draft,open" class="oe_highlight"/>
- <field name="stage_id" widget="statusbar" clickable="True"/>
+ <button name="case_mark_won" string="Mark Won" type="object" class="oe_highlight"
+ attrs="{'invisible': [('probability', '=', 100)]}"/>
+ <button name="case_mark_lost" string="Mark Lost" type="object" class="oe_highlight"
+ attrs="{'invisible': ['|', ('probability', '=', 0), ('probability', '=', 100)]}"/>
+ <field name="stage_id" widget="statusbar" clickable="True"
+ domain="['&amp;', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
</header>
<sheet>
<div class="oe_right oe_button_box">
- <button string="Schedule/Log Call"
- name="%(opportunity2phonecall_act)d"
- type="action"/>
- <button string="Meeting"
+ <button string="Schedule/Log Call" type="action"
+ name="%(opportunity2phonecall_act)d"/>
+ <button string="Meeting" type="object"
name="action_makeMeeting"
- type="object"
context="{'search_default_attendee_id': active_id, 'default_attendee_id' : active_id}"/>
</div>
<div class="oe_title">
@@ -430,7 +429,8 @@
<label for="section_id" groups="base.group_multi_salesteams"/>
<div groups="base.group_multi_salesteams">
<field name="section_id" widget="selection"/>
- <button name="case_escalate" string="Escalate" type="object" class="oe_link" attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
+ <button name="case_escalate" string="Escalate" type="object" class="oe_link"
+ attrs="{'invisible': ['|', ('section_id','=',False), ('probability', '=', 100)]}"/>
</div>
</group>
<group>
@@ -481,7 +481,6 @@
<field name="day_open" groups="base.group_no_one"/>
<field name="day_close" groups="base.group_no_one"/>
<field name="referred"/>
- <field name="state" invisible="1"/>
<field name="type" invisible="1"/>
</group>
<group string="References">
@@ -511,7 +510,7 @@
<field name="name">Opportunities Tree</field>
<field name="model">crm.lead</field>
<field name="arch" type="xml">
- <tree string="Opportunities" fonts="bold:message_unread==True" colors="gray:state in ('cancel', 'done');red:date_deadline and (date_deadline &lt; current_date)">
+ <tree string="Opportunities" fonts="bold:message_unread==True" colors="gray:probability == 100;red:date_deadline and (date_deadline &lt; current_date)">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name" string="Opportunity"/>
@@ -529,7 +528,8 @@
<field name="referred" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="message_unread" invisible="1"/>
- <field name="state" invisible="1"/>
+ <field name="probability" invisible="1"/>
+ <field name="write_date" invisible="1"/>
</tree>
</field>
</record>
@@ -546,15 +546,19 @@
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
+ <field name="stage_id" domain="[]"/>
+ <field name="probability"/>
<separator/>
- <filter string="New" name="new" domain="[('state','=','draft')]" help="New Opportunities"/>
- <filter string="In Progress" name="open" domain="[('state','=','open')]" help="Open Opportunities"/>
- <filter string="Won" name="won" domain="[('state','=','done')]"/>
- <filter string="Lost" name="lost" domain="[('state','=','cancel')]"/>
- <filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
- <filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
+ <filter string="New" name="new"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
+ <filter string="Won" name="won"
+ domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
+ <filter string="Lost" name="lost"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
+ <filter string="Unassigned" name="unassigned"
+ domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="My Opportunities" name="assigned_to_me"
- domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
+ domain="[('user_id', '=', uid)]" context="{'invisible_section': False}"
help="Opportunities that are assigned to me"/>
<filter string="Assigned to My Team(s)"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}"
@@ -572,6 +576,7 @@
<filter string="Campaign" domain="[]" context="{'group_by':'type_id'}"/>
<filter string="Channel" domain="[]" context="{'group_by':'channel_id'}"/>
<filter string="Creation" domain="[]" context="{'group_by':'create_date'}"/>
+ <filter string="Last Update Month" domain="[]" context="{'group_by':'write_date'}"/>
</group>
<group string="Display">
<filter string="Show Sales Team" context="{'invisible_section': False}" domain="[]" help="Show Sales Team" groups="base.group_multi_salesteams"/>
diff --git a/addons/crm/crm_view.xml b/addons/crm/crm_view.xml
index a84ae553b4a..d0dcc07fcb0 100644
--- a/addons/crm/crm_view.xml
+++ b/addons/crm/crm_view.xml
@@ -80,7 +80,6 @@
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="probability"/>
- <field name="state"/>
<field name="type"/>
</tree>
</field>
@@ -96,7 +95,6 @@
<form string="Stage" version="7.0">
<group col="4">
<field name="name"/>
- <field name="state"/>
<field name="probability"/>
<field name="type"/>
<field name="on_change"/>
diff --git a/addons/crm/doc/changelog.rst b/addons/crm/doc/changelog.rst
index cb1602a8d39..e9bd1980956 100644
--- a/addons/crm/doc/changelog.rst
+++ b/addons/crm/doc/changelog.rst
@@ -6,6 +6,12 @@ Changelog
`trunk (saas-2)`
----------------
+- Stage/state update
+
+ - ``crm.lead``: removed ``state`` field. Added ``date_last_stage_update`` field
+ holding last stage_id modification. Updated reports.
+ - ``crm.case.stage``: removed ``state`` field.
+
- ``crm``, ``crm_claim``: removed inheritance from ``base_stage`` class. Missing
methods have been added into ``crm`` and ``crm_claim``. Also removed inheritance
in ``crm_helpdesk`` because it uses states, not stages. \ No newline at end of file
diff --git a/addons/crm/doc/index.rst b/addons/crm/doc/index.rst
index d70e045befe..f98ca145a56 100644
--- a/addons/crm/doc/index.rst
+++ b/addons/crm/doc/index.rst
@@ -4,6 +4,11 @@ CRM module documentation
CRM documentation topics
'''''''''''''''''''''''''
+.. toctree::
+ :maxdepth: 1
+
+ stage_status.rst
+
Changelog
'''''''''
diff --git a/addons/crm/doc/stage_status.rst b/addons/crm/doc/stage_status.rst
new file mode 100644
index 00000000000..ca5d3d3d6e1
--- /dev/null
+++ b/addons/crm/doc/stage_status.rst
@@ -0,0 +1,61 @@
+.. _stage_status:
+
+Stage and Status
+================
+
+.. versionchanged:: 8.0 saas-2 state/stage cleaning
+
+Stage
++++++
+
+This revision removed the concept of state on crm.lead objects. The ``state``
+field has been totally removed and replaced by stages, using ``stage_id``. The
+following models are impacted:
+
+ - ``crm.lead`` now use only stages. However conventions still exist about
+ 'New', 'Won' and 'Lost' stages. Those conventions are:
+
+ - ``new``: ``stage_id and stage_id.sequence = 1``
+ - ``won``: ``stage_id and stage_id.probability = 100 and stage_id.on_change = True``
+ - ``lost``: ``stage_id and stage_id.probability = 0 and stage_id.on_change = True
+ and stage_id.sequence != 1``
+
+ - ``crm.case.stage`` do not have any ``state`` field anymore.
+ - ``crm.lead.report`` do not have any ``state`` field anymore.
+
+By default a newly created lead is in a new stage. It means that it will
+fetch the stage having ``sequence = 1``. Stage mangement is done using the
+kanban view or the clikable statusbar. It is not done using buttons anymore.
+
+Stage analysis
+++++++++++++++
+
+Stage analysis can be performed using the newly introduced ``date_last_stage_update``
+datetime field. This field is updated everytime ``stage_id`` is updated.
+
+``crm.lead.report`` model also uses the ``date_last_stage_update`` field.
+This allows to group and analyse the time spend in the various stages.
+
+Open / Assignation date
++++++++++++++++++++++++
+
+The ``date_open`` field meaning has been updated. It is now set when the ``user_id``
+(responsible) is set. It is therefore the assignation date.
+
+Subtypes
+++++++++
+
+The following subtypes are triggered on ``crm.lead``:
+
+ - ``mt_lead_create``: new leads. Condition: ``obj.probability == 0 and obj.stage_id
+ and obj.stage_id.sequence == 1``
+ - ``mt_lead_stage``: stage changed. Condition: ``(obj.stage_id and obj.stage_id.sequence != 1)
+ and obj.probability < 100``
+ - ``mt_lead_won``: lead/oportunity is won. condition: `` obj.probability == 100
+ and obj.stage_id and obj.stage_id.on_change``
+ - ``mt_lead_lost``: lead/opportunity is lost. Condition: ``obj.probability == 0
+ and obj.stage_id and obj.stage_id.sequence != 1'``
+
+
+Those subtypes are also available on the ``crm.case.section`` model and are used
+for the auto subscription.
diff --git a/addons/crm/i18n/es_AR.po b/addons/crm/i18n/es_AR.po
index 7b09f194742..818abeae08a 100644
--- a/addons/crm/i18n/es_AR.po
+++ b/addons/crm/i18n/es_AR.po
@@ -1,25 +1,26 @@
-# Translation of OpenERP Server.
-# This file contains the translation of the following modules:
-# * crm
+# Spanish (Argentina) translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
-"Project-Id-Version: OpenERP Server 5.0.0\n"
-"Report-Msgid-Bugs-To: support@openerp.com\n"
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2009-09-15 15:45+0000\n"
-"Last-Translator: Silvana Herrera <sherrera@thymbra.com>\n"
-"Language-Team: \n"
+"PO-Revision-Date: 2013-08-13 02:17+0000\n"
+"Last-Translator: Laureano Kloss <Unknown>\n"
+"Language-Team: Spanish (Argentina) <es_AR@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:09+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-08-13 05:00+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
#. module: crm
#: view:crm.lead.report:0
msgid "# Leads"
-msgstr ""
+msgstr "# Iniciativas"
#. module: crm
#: help:sale.config.settings,fetchmail_lead:0
@@ -27,9 +28,11 @@ msgid ""
"Allows you to configure your incoming mail server, and create leads from "
"incoming emails."
msgstr ""
+"Le permite configurar su servidor de correo entrante y crear iniciativas "
+"desde los correos entrantes."
#. module: crm
-#: code:addons/crm/crm_lead.py:881
+#: code:addons/crm/crm_lead.py:898
#: selection:crm.case.stage,type:0
#: view:crm.lead:0
#: selection:crm.lead,type:0
@@ -37,13 +40,13 @@ msgstr ""
#: selection:crm.lead.report,type:0
#, python-format
msgid "Lead"
-msgstr ""
+msgstr "Iniciativa"
#. module: crm
#: view:crm.lead:0
#: field:crm.lead,title:0
msgid "Title"
-msgstr ""
+msgstr "Denominación"
#. module: crm
#: model:ir.actions.server,message:crm.action_email_reminder_lead
@@ -54,40 +57,45 @@ msgid ""
"Description: [[object.description]]\n"
" "
msgstr ""
+"Advertencia: Una iniciativa entrante está sin procesar más de 5 días.\n"
+"Nombre: [[object.name ]]\n"
+"ID: [[object.id ]]\n"
+"Descripción: [[object.description]]\n"
+" "
#. module: crm
#: field:crm.opportunity2phonecall,action:0
#: field:crm.phonecall2phonecall,action:0
msgid "Action"
-msgstr ""
+msgstr "Acción"
#. module: crm
#: model:ir.actions.server,name:crm.action_set_team_sales_department
msgid "Set team to Sales Department"
-msgstr ""
+msgstr "Establecer como equipo al Departamento de ventas"
#. module: crm
#: view:crm.lead2opportunity.partner.mass:0
msgid "Select Opportunities"
-msgstr ""
+msgstr "Seleccionar oportunidades"
#. module: crm
#: model:res.groups,name:crm.group_fund_raising
#: field:sale.config.settings,group_fund_raising:0
msgid "Manage Fund Raising"
-msgstr ""
+msgstr "Administrar recaudación de fondos"
#. module: crm
#: view:crm.lead.report:0
#: field:crm.phonecall.report,delay_close:0
msgid "Delay to close"
-msgstr ""
+msgstr "Demora para cerrar"
#. module: crm
#: view:crm.case.stage:0
#: field:crm.case.stage,name:0
msgid "Stage Name"
-msgstr ""
+msgstr "Nombre de etapa"
#. module: crm
#: view:crm.lead:0
@@ -95,52 +103,52 @@ msgstr ""
#: view:crm.lead.report:0
#: view:crm.phonecall.report:0
msgid "Salesperson"
-msgstr ""
+msgstr "Comercial"
#. module: crm
#: model:ir.model,name:crm.model_crm_lead_report
msgid "CRM Lead Analysis"
-msgstr ""
+msgstr "Análisis Iniciativas CRM"
#. module: crm
#: view:crm.lead.report:0
#: view:crm.phonecall.report:0
#: field:crm.phonecall.report,day:0
msgid "Day"
-msgstr ""
+msgstr "Día"
#. module: crm
#: view:crm.lead:0
msgid "Company Name"
-msgstr ""
+msgstr "Nombre de la compañía"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor6
msgid "Training"
-msgstr ""
+msgstr "Formación"
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_lead_categ_action
#: model:ir.ui.menu,name:crm.menu_crm_lead_categ
msgid "Sales Tags"
-msgstr ""
+msgstr "Etiquetas de ventas"
#. module: crm
#: view:crm.lead.report:0
msgid "Exp. Closing"
-msgstr ""
+msgstr "Cierre Esperado"
#. module: crm
#: help:crm.case.section,message_unread:0
#: help:crm.lead,message_unread:0
#: help:crm.phonecall,message_unread:0
msgid "If checked new messages require your attention."
-msgstr ""
+msgstr "Si está marcado, los nuevos mensajes requerirán su atención"
#. module: crm
#: help:crm.lead.report,creation_day:0
msgid "Creation day"
-msgstr ""
+msgstr "Fecha creación"
#. module: crm
#: field:crm.segmentation.line,name:0
@@ -151,7 +159,7 @@ msgstr "Nombre de regla"
#: code:addons/crm/crm_phonecall.py:280
#, python-format
msgid "It's only possible to convert one phonecall at a time."
-msgstr ""
+msgstr "Sólo es posible convertir una llamada telefónica cada vez."
#. module: crm
#: view:crm.case.resource.type:0
@@ -161,17 +169,17 @@ msgstr ""
#: field:crm.lead.report,type_id:0
#: model:ir.model,name:crm.model_crm_case_resource_type
msgid "Campaign"
-msgstr ""
+msgstr "Campaña"
#. module: crm
#: view:crm.lead:0
msgid "Search Opportunities"
-msgstr ""
+msgstr "Busqueda de oportunidades"
#. module: crm
#: help:crm.lead.report,deadline_month:0
msgid "Expected closing month"
-msgstr ""
+msgstr "Mes esperado de cierre"
#. module: crm
#: help:crm.case.section,message_summary:0
@@ -181,14 +189,17 @@ msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
msgstr ""
+"Contiene el resumen del chatter (nº de mensajes, ...). Este resumen está "
+"generado directamente en formato HTML para poder ser insertado en las vistas "
+"kanban."
#. module: crm
-#: code:addons/crm/crm_lead.py:624
-#: code:addons/crm/crm_lead.py:744
+#: code:addons/crm/crm_lead.py:640
+#: code:addons/crm/crm_lead.py:761
#: code:addons/crm/crm_phonecall.py:280
#, python-format
msgid "Warning!"
-msgstr ""
+msgstr "Alerta!"
#. module: crm
#: view:crm.lead:0
@@ -203,46 +214,46 @@ msgstr ""
#: model:ir.model,name:crm.model_res_partner
#: model:process.node,name:crm.process_node_partner0
msgid "Partner"
-msgstr "Partner"
+msgstr "Empresa"
#. module: crm
#: view:crm.phonecall:0
#: model:ir.actions.act_window,name:crm.phonecall_to_phonecall_act
msgid "Schedule Other Call"
-msgstr ""
+msgstr "Planificar otra llamada"
#. module: crm
#: code:addons/crm/crm_phonecall.py:209
#: view:crm.phonecall:0
#, python-format
msgid "Phone Call"
-msgstr ""
+msgstr "Llamada de teléfono"
#. module: crm
#: field:crm.lead,opt_out:0
msgid "Opt-Out"
-msgstr ""
+msgstr "No acepta recibir mensajes"
#. module: crm
#: view:crm.lead:0
#: field:crm.lead,state_id:0
msgid "State"
-msgstr ""
+msgstr "Estado"
#. module: crm
#: field:res.partner,meeting_count:0
msgid "# Meetings"
-msgstr ""
+msgstr "Nº reuniones"
#. module: crm
#: model:ir.actions.server,name:crm.action_email_reminder_lead
msgid "Reminder to User"
-msgstr ""
+msgstr "Recordatorio al usuario"
#. module: crm
#: field:crm.segmentation,segmentation_line:0
msgid "Criteria"
-msgstr "Criterios"
+msgstr "Criterio"
#. module: crm
#: view:crm.segmentation:0
@@ -252,26 +263,28 @@ msgstr "Respuestas excluidas:"
#. module: crm
#: model:ir.model,name:crm.model_crm_merge_opportunity
msgid "Merge opportunities"
-msgstr ""
+msgstr "Fusionar oportunidades"
#. module: crm
#: view:crm.lead.report:0
#: model:ir.actions.act_window,name:crm.action_report_crm_lead
#: model:ir.ui.menu,name:crm.menu_report_crm_leads_tree
msgid "Leads Analysis"
-msgstr ""
+msgstr "Análisis de iniciativas"
#. module: crm
#: code:addons/crm/crm_lead.py:1010
#, python-format
msgid "<b>%s a call</b> for the <em>%s</em>."
msgstr ""
+"Copy text \t\r\n"
+"<b>%s una llamada</b> para el <em>%s</em>."
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_case_resource_type_act
#: model:ir.ui.menu,name:crm.menu_crm_case_resource_type_act
msgid "Campaigns"
-msgstr ""
+msgstr "Campañas"
#. module: crm
#: view:crm.lead:0
@@ -286,6 +299,9 @@ msgid ""
"If opt-out is checked, this contact has refused to receive emails or "
"unsubscribed to a campaign."
msgstr ""
+"Si se marca la casilla 'No acepta recibir mensajes', este contacto ha "
+"rehusado recibir correos electrónicos o ha eliminado su suscripción a una "
+"campaña."
#. module: crm
#: model:process.transition,name:crm.process_transition_leadpartner0
@@ -293,15 +309,15 @@ msgid "Prospect Partner"
msgstr ""
#. module: crm
-#: code:addons/crm/crm_lead.py:982
+#: code:addons/crm/crm_lead.py:1002
#, python-format
msgid "No Subject"
-msgstr ""
+msgstr "Sin título"
#. module: crm
#: field:crm.lead,contact_name:0
msgid "Contact Name"
-msgstr ""
+msgstr "Nombre del contacto"
#. module: crm
#: help:crm.segmentation,categ_id:0
@@ -309,7 +325,7 @@ msgid ""
"The partner category that will be added to partners that match the "
"segmentation criterions after computation."
msgstr ""
-"La categoría del partner que será añadida a las empresas que cumplan los "
+"La categoría del partner será añadida a las empresas que cumplan los "
"criterios de segmentación después del cálculo."
#. module: crm
@@ -325,40 +341,50 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+"Pulse para definir una nueva segmentación de clientes.\n"
+"</p><p>\n"
+"Cree categorías específicas que puede asignar a sus contactos para "
+"administrar mejor sus interacciones con ellos. La herramienta de "
+"segmentación es capaz de asignar categorías a los contactos de acuerdo a los "
+"criterios que establezca.\n"
+"</p>\n"
+" "
#. module: crm
#: field:crm.opportunity2phonecall,contact_name:0
#: field:crm.phonecall,partner_id:0
#: field:crm.phonecall2phonecall,contact_name:0
msgid "Contact"
-msgstr ""
+msgstr "Contacto"
#. module: crm
#: help:crm.case.section,change_responsible:0
msgid ""
"When escalating to this team override the salesman with the team leader."
msgstr ""
+"Al escalar a este equipo sobreescribir al comercial con el jefe de equipo."
#. module: crm
#: model:process.transition,name:crm.process_transition_opportunitymeeting0
msgid "Opportunity Meeting"
-msgstr ""
+msgstr "Reunión de oportunidad"
#. module: crm
#: help:crm.lead.report,delay_close:0
#: help:crm.phonecall.report,delay_close:0
msgid "Number of Days to close the case"
-msgstr ""
+msgstr "Número de días para cerrar el caso"
#. module: crm
#: model:process.node,note:crm.process_node_opportunities0
msgid "When a real project/opportunity is detected"
-msgstr ""
+msgstr "Cuando un proyecto/oportunidad es detectado"
#. module: crm
#: field:res.partner,opportunity_ids:0
msgid "Leads and Opportunities"
-msgstr ""
+msgstr "Iniciativas y oportunidades"
#. module: crm
#: model:ir.actions.act_window,help:crm.relate_partner_opportunities
@@ -377,12 +403,23 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+"Pulse para crear una oportunidad relacionada con este cliente.\n"
+"</p><p>\n"
+"Use las oportunidades para seguir la pista al flujo de sus ventas, seguir "
+"una venta potencial y prever mejor sus futuros ingresos.\n"
+"</p><p>\n"
+"Podrá planificar reuniones y llamadas telefónicas desde las oportunidades, "
+"convertirlas en ofertas, adjuntar documentos relacionados, rastrear todas "
+"las discusiones, y mucho más.\n"
+"</p>\n"
+" "
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead7
#: view:crm.lead:0
msgid "Dead"
-msgstr ""
+msgstr "Muerta"
#. module: crm
#: field:crm.case.section,message_unread:0
@@ -390,7 +427,7 @@ msgstr ""
#: field:crm.lead,message_unread:0
#: field:crm.phonecall,message_unread:0
msgid "Unread Messages"
-msgstr ""
+msgstr "Mensajes no leídos"
#. module: crm
#: view:crm.segmentation:0
@@ -404,17 +441,17 @@ msgstr "Segmentación"
#: selection:crm.lead2opportunity.partner.mass,action:0
#: selection:crm.partner.binding,action:0
msgid "Link to an existing customer"
-msgstr ""
+msgstr "Enlace a cliente existente"
#. module: crm
#: field:crm.lead,write_date:0
msgid "Update Date"
-msgstr ""
+msgstr "Actualizar fecha"
#. module: crm
#: field:crm.case.section,user_id:0
msgid "Team Leader"
-msgstr ""
+msgstr "Jefe de equipo"
#. module: crm
#: help:crm.case.stage,probability:0
@@ -422,6 +459,8 @@ msgid ""
"This percentage depicts the default/average probability of the Case for this "
"stage to be a success"
msgstr ""
+"Este porcentaje representa la probabilidad por defecto / media para que los "
+"casos de esta etapa tengan éxito."
#. module: crm
#: view:crm.lead:0
@@ -436,24 +475,27 @@ msgstr "Categoría"
#. module: crm
#: view:crm.lead.report:0
msgid "#Opportunities"
-msgstr ""
+msgstr "# Oportunidades"
#. module: crm
-#: code:addons/crm/crm_lead.py:624
+#: code:addons/crm/crm_lead.py:640
#, python-format
msgid ""
"Please select more than one element (lead or opportunity) from the list view."
msgstr ""
+"Seleccione más de un elemento (iniciativa u oportunidad) desde la vista "
+"lista."
#. module: crm
#: view:crm.lead:0
msgid "Leads that are assigned to one of the sale teams I manage, or to me"
msgstr ""
+"Iniciativas asignadas a uno de los equipos que gestiono, o a mí mismo"
#. module: crm
#: field:crm.lead,partner_address_email:0
msgid "Partner Contact Email"
-msgstr ""
+msgstr "Dirección de correo del contacto de la empresa"
#. module: crm
#: model:ir.actions.act_window,help:crm.crm_case_section_act
@@ -467,11 +509,19 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+"Pulse para definir un nuevo equipo de ventas.\n"
+"</p><p>\n"
+"Use los equipos de venta para organizar a los diferentes comerciales o "
+"departamentos en equipos separados. Cada equipo trabajará en su propia lista "
+"de oportunidades.\n"
+"</p>\n"
+" "
#. module: crm
#: model:process.transition,note:crm.process_transition_opportunitymeeting0
msgid "Normal or phone meeting for opportunity"
-msgstr ""
+msgstr "Reunión o conferencia telefónica para oportunidad"
#. module: crm
#: field:crm.lead,state:0
@@ -480,12 +530,12 @@ msgstr ""
#: view:crm.phonecall.report:0
#: field:crm.phonecall.report,state:0
msgid "Status"
-msgstr ""
+msgstr "Estado"
#. module: crm
#: view:crm.lead2opportunity.partner:0
msgid "Create Opportunity"
-msgstr ""
+msgstr "Crear oportunidad"
#. module: crm
#: view:sale.config.settings:0
@@ -706,7 +756,7 @@ msgid "Statistics Dashboard"
msgstr ""
#. module: crm
-#: code:addons/crm/crm_lead.py:861
+#: code:addons/crm/crm_lead.py:878
#: model:crm.case.stage,name:crm.stage_lead2
#: selection:crm.case.stage,type:0
#: view:crm.lead:0
@@ -766,7 +816,7 @@ msgid "Exclusive"
msgstr "Exclusivo"
#. module: crm
-#: code:addons/crm/crm_lead.py:584
+#: code:addons/crm/crm_lead.py:600
#, python-format
msgid "From %s : %s"
msgstr ""
@@ -934,7 +984,7 @@ msgid "Next Action"
msgstr "Próxima acción"
#. module: crm
-#: code:addons/crm/crm_lead.py:763
+#: code:addons/crm/crm_lead.py:780
#, python-format
msgid "<b>Partner</b> set to <em>%s</em>."
msgstr ""
@@ -1024,7 +1074,7 @@ msgid "Creation Date"
msgstr "Fecha de creación"
#. module: crm
-#: code:addons/crm/crm_lead.py:698
+#: code:addons/crm/crm_lead.py:715
#, python-format
msgid "Lead <b>converted into an Opportunity</b>"
msgstr ""
@@ -1213,7 +1263,9 @@ msgid "Days to Close"
msgstr ""
#. module: crm
+#: code:addons/crm/crm_lead.py:1057
#: field:crm.case.section,complete_name:0
+#, python-format
msgid "unknown"
msgstr ""
@@ -1296,7 +1348,7 @@ msgid "Lead Description"
msgstr ""
#. module: crm
-#: code:addons/crm/crm_lead.py:565
+#: code:addons/crm/crm_lead.py:581
#, python-format
msgid "Merged opportunities"
msgstr ""
@@ -1856,7 +1908,7 @@ msgid "Leads"
msgstr ""
#. module: crm
-#: code:addons/crm/crm_lead.py:563
+#: code:addons/crm/crm_lead.py:579
#, python-format
msgid "Merged leads"
msgstr ""
@@ -1950,7 +2002,6 @@ msgid "Global CC"
msgstr ""
#. module: crm
-#: view:crm.lead:0
#: view:crm.phonecall:0
#: model:ir.actions.act_window,name:crm.crm_case_categ_phone0
#: model:ir.ui.menu,name:crm.menu_crm_case_phone
@@ -2878,7 +2929,7 @@ msgid "Working Hours"
msgstr ""
#. module: crm
-#: code:addons/crm/crm_lead.py:968
+#: code:addons/crm/crm_lead.py:986
#: view:crm.lead:0
#: field:crm.lead2opportunity.partner,partner_id:0
#: field:crm.lead2opportunity.partner.mass,partner_id:0
diff --git a/addons/crm/i18n/zh_CN.po b/addons/crm/i18n/zh_CN.po
index 9064502ba33..aaac89319a8 100644
--- a/addons/crm/i18n/zh_CN.po
+++ b/addons/crm/i18n/zh_CN.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-07-23 03:21+0000\n"
+"PO-Revision-Date: 2013-08-06 09:41+0000\n"
"Last-Translator: fanvil <fanvil@hotmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-07-24 05:31+0000\n"
-"X-Generator: Launchpad (build 16700)\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
#. module: crm
#: view:crm.lead.report:0
@@ -185,7 +185,7 @@ msgstr "预计结束月份"
msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
-msgstr "保留复杂的摘要(消息数量,……等)。为了插入到看板视图,这一摘要直接是是HTML格式。"
+msgstr "保留复杂的摘要(消息数量,……等)。这一摘要直接是是HTML格式,以便插入到看板视图。"
#. module: crm
#: code:addons/crm/crm_lead.py:640
@@ -583,6 +583,7 @@ msgid ""
" If the call needs to be done then the status is set "
"to 'Not Held'."
msgstr ""
+"当一个案子新建时,状态被设为‘待处理’,当案子进行中,状态被设为‘打开’,当电话结束,状态被设为‘挂起’。如果需要电话,状态设为‘未挂起’"
#. module: crm
#: field:crm.case.section,message_summary:0
@@ -843,7 +844,7 @@ msgstr "参考2"
msgid ""
"Link between stages and sales teams. When set, this limitate the current "
"stage to the selected sales teams."
-msgstr ""
+msgstr "在阶段和销售团队之间建立链接。设置后将限制此阶段只能用于被选中的销售团队。"
#. module: crm
#: view:crm.case.stage:0
@@ -979,7 +980,7 @@ msgstr "下一动作"
#: code:addons/crm/crm_lead.py:780
#, python-format
msgid "<b>Partner</b> set to <em>%s</em>."
-msgstr ""
+msgstr "<b>业务伙伴</b> 设给 <em>%s</em>."
#. module: crm
#: selection:crm.lead.report,state:0
@@ -1338,7 +1339,7 @@ msgstr "发送邮件的时候,默认的邮件地址来自销售团队。"
msgid ""
"Phone Calls Assigned to the current user or with a team having the current "
"user as team leader"
-msgstr ""
+msgstr "被分配给当前用户或者当前用户领导的销售团队的电话沟通任务。"
#. module: crm
#: view:crm.segmentation:0
@@ -2884,7 +2885,7 @@ msgstr "发现日期"
#. module: crm
#: view:crm.lead:0
msgid "at"
-msgstr ""
+msgstr "在"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead1
diff --git a/addons/crm/report/crm_lead_report.py b/addons/crm/report/crm_lead_report.py
index d12facd66a0..ac1e10a84c6 100644
--- a/addons/crm/report/crm_lead_report.py
+++ b/addons/crm/report/crm_lead_report.py
@@ -19,17 +19,9 @@
#
##############################################################################
-from openerp.osv import fields,osv
+from openerp.osv import fields, osv
from openerp import tools
-from .. import crm
-
-AVAILABLE_STATES = [
- ('draft','Draft'),
- ('open','Open'),
- ('cancel', 'Cancelled'),
- ('done', 'Closed'),
- ('pending','Pending')
-]
+from openerp.addons.crm import crm
MONTHS = [
('01', 'January'),
@@ -66,11 +58,12 @@ class crm_lead_report(osv.osv):
# other date fields
'create_date': fields.datetime('Create Date', readonly=True),
- 'opening_date': fields.date('Opening Date', readonly=True),
+ 'opening_date': fields.date('Assignation Date', readonly=True),
'date_closed': fields.date('Close Date', readonly=True),
+ 'date_last_stage_update': fields.datetime('Last Stage Update', readonly=True),
# durations
- 'delay_open': fields.float('Delay to Open',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
+ 'delay_open': fields.float('Delay to Assign',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
'delay_close': fields.float('Delay to Close',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
@@ -79,7 +72,6 @@ class crm_lead_report(osv.osv):
'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
'channel_id':fields.many2one('crm.case.channel', 'Channel', readonly=True),
'type_id':fields.many2one('crm.case.resource.type', 'Campaign', readonly=True),
- 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
'planned_revenue': fields.float('Planned Revenue',digits=(16,2),readonly=True),
@@ -94,10 +86,7 @@ class crm_lead_report(osv.osv):
('opportunity','Opportunity'),
],'Type', help="Type is used to separate Leads and Opportunities"),
}
-
-
-
-
+
def init(self, cr):
"""
@@ -109,7 +98,6 @@ class crm_lead_report(osv.osv):
CREATE OR REPLACE VIEW crm_lead_report AS (
SELECT
id,
-
to_char(c.date_deadline, 'YYYY') as deadline_year,
to_char(c.date_deadline, 'MM') as deadline_month,
to_char(c.date_deadline, 'YYYY-MM-DD') as deadline_day,
@@ -121,7 +109,8 @@ class crm_lead_report(osv.osv):
to_char(c.date_open, 'YYYY-MM-DD') as opening_date,
to_char(c.date_closed, 'YYYY-mm-dd') as date_closed,
- c.state,
+ date_trunc('day',c.date_last_stage_update) as date_last_stage_update,
+
c.user_id,
c.probability,
c.stage_id,
diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml
index 09853c6379e..95cf1d4b7b0 100644
--- a/addons/crm/report/crm_lead_report_view.xml
+++ b/addons/crm/report/crm_lead_report_view.xml
@@ -13,7 +13,7 @@
<field name="creation_month" invisible="1"/>
<field name="creation_day" invisible="1"/>
<field name="deadline_month" invisible="1"/>
- <field name="state" invisible="1"/>
+ <field name="date_last_stage_update" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="channel_id" invisible="1"/>
@@ -69,10 +69,12 @@
<filter icon="terp-personal" name="lead" string="Lead" domain="[('type','=', 'lead')]" help="Show only lead"/>
<filter icon="terp-personal+" string="Opportunity" name="opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
<separator/>
- <filter icon="terp-check" string="New" domain="[('state','=','draft')]" help="Leads/Opportunities which are in New state"/>
- <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Leads/Opportunities which are in open state"/>
- <filter icon="gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Leads/Opportunities which are in pending state"/>
- <filter icon="terp-dialog-close" string="Closed" domain="[('state','=','done')]" help="Leads/Opportunities which are in done state"/>
+ <filter string="New" name="new"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
+ <filter string="Won" name="won"
+ domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
+ <filter string="Lost" name="lost"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
<separator/>
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]"
help="Leads/Opportunities that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
@@ -120,6 +122,7 @@
<separator orientation="vertical" />
<filter string="Exp. Closing" icon="terp-go-month"
domain="[]" context="{'group_by':'deadline_month'}"/>
+ <filter string="Last Stage Update" context="{'group_by':'date_last_stage_update'}" />
</group>
</search>
</field>
@@ -131,7 +134,7 @@
<field name="name">crm.lead.report.tree</field>
<field name="model">crm.lead.report</field>
<field name="arch" type="xml">
- <tree colors="blue:state == 'draft';black:state in ('open','pending','done');gray:state == 'cancel' " create="false" string="Opportunities Analysis">
+ <tree create="false" string="Opportunities Analysis">
<field name="creation_year" invisible="1"/>
<field name="creation_month" invisible="1"/>
<field name="creation_day" invisible="1"/>
@@ -141,7 +144,6 @@
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/>
- <field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="type_id" invisible="1"/>
@@ -150,8 +152,9 @@
<field name="company_id" invisible="1" groups="base.group_multi_company"/>
<field name="nbr" string="#Opportunities" sum="#Opportunities"/>
<field name="planned_revenue" sum="Planned Revenues"/>
- <field name="delay_open" sum='Delay to open'/>
+ <field name="delay_open" sum='Delay to Assign'/>
<field name="delay_close" sum='Delay to close'/>
+ <field name="date_last_stage_update"/>
<field name="delay_expected"/>
<field name="probability" widget="progressbar"/>
<field name="probable_revenue"/>
diff --git a/addons/crm/report/crm_phonecall_report.py b/addons/crm/report/crm_phonecall_report.py
index 77195097965..fba095f1174 100644
--- a/addons/crm/report/crm_phonecall_report.py
+++ b/addons/crm/report/crm_phonecall_report.py
@@ -19,16 +19,16 @@
#
##############################################################################
-from openerp.osv import fields,osv
from openerp import tools
-from .. import crm
+from openerp.addons.crm import crm
+from openerp.osv import fields, osv
AVAILABLE_STATES = [
- ('draft','Draft'),
- ('open','Todo'),
+ ('draft', 'Draft'),
+ ('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Held'),
- ('pending','Pending')
+ ('pending', 'Pending')
]
diff --git a/addons/crm/report/crm_phonecall_report_view.xml b/addons/crm/report/crm_phonecall_report_view.xml
index aa2162d163a..52ecd2d13b3 100644
--- a/addons/crm/report/crm_phonecall_report_view.xml
+++ b/addons/crm/report/crm_phonecall_report_view.xml
@@ -23,7 +23,7 @@
<field name="nbr" string="#Phone calls" sum="#Phone calls"/>
<field name="duration" avg="Duration"/>
<field name="delay_close" avg="Avg Closing Delay"/>
- <field name="delay_open" sum='Delay to open'/>
+ <field name="delay_open" sum='Delay to Assign'/>
</tree>
</field>
</record>
diff --git a/addons/crm/res_partner.py b/addons/crm/res_partner.py
index fca9222082d..9cf2dc2088f 100644
--- a/addons/crm/res_partner.py
+++ b/addons/crm/res_partner.py
@@ -41,7 +41,7 @@ class res_partner(osv.osv):
_columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'opportunity_ids': fields.one2many('crm.lead', 'partner_id',\
- 'Leads and Opportunities', domain=[('state','in', ('draft','open','pending'))]),
+ 'Leads and Opportunities', domain=[('probability' 'not in', ['0', '100'])]),
'meeting_ids': fields.many2many('crm.meeting', 'crm_meeting_partner_rel','partner_id', 'meeting_id',
'Meetings'),
'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\
@@ -87,7 +87,6 @@ class res_partner(osv.osv):
'probability' : probability,
'partner_id' : partner_id,
'categ_ids' : categ_ids and categ_ids[0:1] or [],
- 'state' :'draft',
'type': 'opportunity'
}, context=context)
opportunity_ids[partner_id] = opportunity_id
diff --git a/addons/crm/test/crm_lead_cancel.yml b/addons/crm/test/crm_lead_cancel.yml
index 0f8d9ba1df9..127fe4d6726 100644
--- a/addons/crm/test/crm_lead_cancel.yml
+++ b/addons/crm/test/crm_lead_cancel.yml
@@ -1,10 +1,15 @@
-
- I set a new sale team (with Marketing at parent) and I cancel unqualified lead .
+ I set a new sale team (with Marketing at parent) .
-
!python {model: crm.lead}: |
section_id = self.pool.get('crm.case.section').create(cr, uid, {'name': "Phone Marketing", 'parent_id': ref("crm.crm_case_section_2")})
self.write(cr, uid, [ref("crm_case_1")], {'section_id': section_id})
-
+ I check unqualified lead .
+-
+ !assert {model: crm.lead, id: crm.crm_case_1, string: Lead is in new stage}:
+ - stage_id.sequence == 1
+-
I escalate the lead to parent team.
-
!python {model: crm.lead}: |
diff --git a/addons/crm/test/crm_lead_find_stage.yml b/addons/crm/test/crm_lead_find_stage.yml
new file mode 100644
index 00000000000..b8a11a4af9e
--- /dev/null
+++ b/addons/crm/test/crm_lead_find_stage.yml
@@ -0,0 +1,43 @@
+-
+ I create a new lead.
+-
+ !record {model: crm.lead, id: test_crm_lead_new}:
+ type: 'lead'
+ name: 'Test lead new'
+ partner_id: base.res_partner_1
+ description: This is the description of the test new lead.
+ section_id: crm.section_sales_department
+-
+ I check default stage of lead.
+-
+ !python {model: crm.lead}: |
+ stage = self.pool.get('crm.case.stage').search_read(cr,uid,[('sequence','=',1)],['id'],context)[0]
+ lead = self.browse(cr, uid, ref('test_crm_lead_new'))
+ stage_id = self.stage_find(cr, uid , [lead], lead.section_id.id or False,[], context)
+ assert stage_id == stage['id'], "Default stage of lead is incorrect!"
+-
+ I change type from lead to opportunity.
+-
+ !python {model: crm.lead}: |
+ self.convert_opportunity(cr, uid ,[ref("test_crm_lead_new")], ref("base.res_partner_2"))
+-
+ Now I check default stage after change type.
+-
+ !python {model: crm.lead}: |
+ stage = self.pool.get('crm.case.stage').search_read(cr,uid,[('sequence','=',1)],['id'],context)[0]
+ opp = self.browse(cr, uid, ref('test_crm_lead_new'))
+ stage_id = self.stage_find(cr, uid , [opp], opp.section_id.id or False,[], context)
+ assert stage_id == stage['id'], "Default stage of opportunity is incorrect!"
+-
+ Now I change the stage of opportunity to won.
+-
+ !python {model: crm.lead}: |
+ self.case_mark_won(cr, uid, [ref("test_crm_lead_new")])
+-
+ I check statge of opp should won, after change stage.
+-
+ !python {model: crm.lead}: |
+ opp = self.browse(cr, uid, ref('test_crm_lead_new'))
+ stage_id = self.stage_find(cr, uid , [opp], opp.section_id.id or False,[('probability','=',100.0)], context)
+ assert stage_id == opp.stage_id.id, "Stage of opportunity is incorrect!"
+
diff --git a/addons/crm/test/crm_lead_merge.yml b/addons/crm/test/crm_lead_merge.yml
index b14f9272df9..fb166e0486f 100644
--- a/addons/crm/test/crm_lead_merge.yml
+++ b/addons/crm/test/crm_lead_merge.yml
@@ -2,29 +2,29 @@
-
During a mixed merge (involving leads and opps), data should be handled a certain way following their type (m2o, m2m, text, ...) Start by creating two leads and an opp.
-
- !record {model: crm.lead, id: test_crm_lead_01}:
- type: 'lead'
- name: 'Test lead 1'
- partner_id: base.res_partner_1
+ !record {model: crm.lead, id: test_crm_opp_1}:
+ type: 'opportunity'
+ name: 'Test opportunity 1'
+ partner_id: base.res_partner_5
stage_id: stage_lead1
- description: This is the description of the test lead 1.
+ description: This is the description of the test opp 1.
-
- !record {model: crm.lead, id: test_crm_lead_02}:
+ !record {model: crm.lead, id: test_crm_lead_first}:
type: 'lead'
- name: 'Test lead 2'
- partner_id: base.res_partner_3
+ name: 'Test lead first'
+ partner_id: base.res_partner_1
stage_id: stage_lead1
- description: This is the description of the test lead 2.
+ description: This is the description of the test lead first.
-
- !record {model: crm.lead, id: test_crm_opp_01}:
- type: 'opportunity'
- name: 'Test opportunity 1'
- partner_id: base.res_partner_5
+ !record {model: crm.lead, id: test_crm_lead_second}:
+ type: 'lead'
+ name: 'Test lead second'
+ partner_id: base.res_partner_1
stage_id: stage_lead1
- description: This is the description of the test opp 1.
+ description: This is the description of the test lead second.
-
!python {model: crm.lead}: |
- lead_ids = [ref('test_crm_lead_01'), ref('test_crm_lead_02'), ref('test_crm_opp_01')]
+ lead_ids = [ref('test_crm_opp_1'), ref('test_crm_lead_first'), ref('test_crm_lead_second')]
context.update({'active_model': 'crm.lead', 'active_ids': lead_ids, 'active_id': lead_ids[0]})
-
I create a merge wizard and merge the leads and opp together in the first item of the list.
@@ -38,18 +38,19 @@
-
!python {model: crm.lead}: |
merge_id = self.search(cr, uid, [('name', '=', 'Test opportunity 1'), ('partner_id','=', ref("base.res_partner_5"))])
+
assert merge_id, 'Fail to create merge opportunity wizard'
merge_result = self.browse(cr, uid, merge_id)[0]
- assert merge_result.description == 'This is the description of the test opp 1.\n\nThis is the description of the test lead 1.\n\nThis is the description of the test lead 2.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns'
+ assert merge_result.description == 'This is the description of the test opp 1.\n\nThis is the description of the test lead first.\n\nThis is the description of the test lead second.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns'
assert merge_result.type == 'opportunity', 'Type mismatch: when at least one opp in involved in the merge, the result should be a new opp (instead of %s)' % merge_result.type
-
The other (tailing) leads/opps shouldn't exist anymore.
-
!python {model: crm.lead}: |
- tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_01'))])
- assert not tailing_lead, 'This tailing lead (id %s) should not exist anymore' % ref('test_crm_lead_02')
+ tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_first'))])
+ assert not tailing_lead, 'This tailing lead (id %s) should not exist anymore' % ref('test_crm_lead_second')
- tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_lead_02'))])
+ tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_lead_second'))])
assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_01')
-
I want to test leads merge. Start by creating two leads (with the same partner).
@@ -122,4 +123,4 @@
assert merge_result.partner_id.id == ref("base.res_partner_5"), 'Partner mismatch'
assert merge_result.type == 'opportunity', 'Type mismatch: when opps get merged together, the result should be a new opp (instead of %s)' % merge_result.type
tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_opp_03'))])
- assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_03') \ No newline at end of file
+ assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_03')
diff --git a/addons/crm/test/crm_lead_onchange.yml b/addons/crm/test/crm_lead_onchange.yml
index 45e140e890e..d4843ec57e4 100644
--- a/addons/crm/test/crm_lead_onchange.yml
+++ b/addons/crm/test/crm_lead_onchange.yml
@@ -6,14 +6,13 @@
partner_id: base.res_partner_2
type: opportunity
stage_id: crm.stage_lead1
- state: draft
-
I create a lead record to call a mailing opt-out onchange method.
-
!record {model: crm.lead, id: crm_case_18}:
name: 'Need 20 Days of Consultancy'
type: opportunity
- state: draft
+ stage_id: crm.stage_lead1
opt_out: True
-
I create a phonecall record to call a partner onchange method.
diff --git a/addons/crm/test/lead2opportunity2win.yml b/addons/crm/test/lead2opportunity2win.yml
index 23545c61bc1..003848c6ee7 100644
--- a/addons/crm/test/lead2opportunity2win.yml
+++ b/addons/crm/test/lead2opportunity2win.yml
@@ -1,15 +1,25 @@
-
In order to test the conversion of a lead into a opportunity,
-
+ I set lead to open stage.
+-
+ !python {model: crm.lead}: |
+ self.write(cr, uid, [ref("crm_case_3")],{'stage_id':ref("stage_lead1")})
+-
+ I check if the lead stage is "Open".
+-
+ !assert {model: crm.lead, id: crm.crm_case_3, string: Lead stage is Open}:
+ - stage_id.sequence == 1
+-
I convert lead into opportunity for exiting customer.
-
!python {model: crm.lead}: |
- self.convert_opportunity(cr, uid ,[ref("crm_case_1")], ref("base.res_partner_2"))
+ self.convert_opportunity(cr, uid ,[ref("crm_case_3")], ref("base.res_partner_2"))
-
I check details of converted opportunity.
-
!python {model: crm.lead}: |
- lead = self.browse(cr, uid, ref('crm_case_1'))
+ lead = self.browse(cr, uid, ref('crm_case_3'))
assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
assert lead.partner_id.id == ref("base.res_partner_2"), 'Partner mismatch!'
assert lead.stage_id.id == ref("stage_lead1"), 'Stage of opportunity is incorrect!'
@@ -18,7 +28,7 @@
-
!python {model: crm.opportunity2phonecall}: |
import time
- context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_1')]})
+ context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_3')]})
call_id = self.create(cr, uid, {'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'name': "Bonjour M. Jean, Comment allez-vous? J'ai bien reçu votre demande, pourrions-nous en parler quelques minutes?"}, context=context)
self.action_schedule(cr, uid, [call_id], context=context)
@@ -26,46 +36,46 @@
I check that phonecall is scheduled for that opportunity.
-
!python {model: crm.phonecall}: |
- ids = self.search(cr, uid, [('opportunity_id', '=', ref('crm_case_1'))])
+ ids = self.search(cr, uid, [('opportunity_id', '=', ref('crm_case_3'))])
assert len(ids), 'Phonecall is not scheduled'
-
Now I schedule meeting with customer.
-
!python {model: crm.lead}: |
- self.action_makeMeeting(cr, uid, [ref('crm_case_1')])
+ self.action_makeMeeting(cr, uid, [ref('crm_case_3')])
-
After communicated with customer, I put some notes with contract details.
-
!python {model: crm.lead}: |
- self.message_post(cr, uid, [ref('crm_case_1')], subject='Test note', body='Détails envoyés par le client sur ​​le FAX pour la qualité')
+ self.message_post(cr, uid, [ref('crm_case_3')], subject='Test note', body='Détails envoyés par le client sur ​​le FAX pour la qualité')
-
I win this opportunity
-
!python {model: crm.lead}: |
- self.case_mark_won(cr, uid, [ref("crm_case_1")])
+ self.case_mark_won(cr, uid, [ref("crm_case_3")])
-
I check details of the opportunity after having won the opportunity.
-
!python {model: crm.lead}: |
- lead = self.browse(cr, uid, ref('crm_case_1'))
+ lead = self.browse(cr, uid, ref('crm_case_3'))
assert lead.stage_id.id == ref('crm.stage_lead6'), "Opportunity stage should be 'Won'."
- assert lead.state == 'done', "Opportunity is not in 'done' state!"
+ assert lead.stage_id.probability == 100.0, "Opportunity is not 'done'"
assert lead.probability == 100.0, "Revenue probability should be 100.0!"
-
I convert mass lead into opportunity customer.
-
!python {model: crm.lead2opportunity.partner.mass}: |
- context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_11"), ref("crm_case_2")], 'active_id': ref("crm_case_11")})
+ context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_13"), ref("crm_case_2")], 'active_id': ref("crm_case_13")})
id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('base.user_root')])], 'section_id': ref('crm.section_sales_department')}, context=context)
self.mass_convert(cr, uid, [id], context=context)
-
Now I check first lead converted on opportunity.
-
!python {model: crm.lead}: |
- opp = self.browse(cr, uid, ref('crm_case_11'))
- assert opp.name == "Need estimated cost for new project", "Opportunity name not correct"
+ opp = self.browse(cr, uid, ref('crm_case_13'))
+ assert opp.name == "Plan to buy 60 keyboards and mouses", "Opportunity name not correct"
assert opp.type == 'opportunity', 'Lead is not converted to opportunity!'
- expected_partner = "Thomas Passot"
+ expected_partner = "Will McEncroe"
assert opp.partner_id.name == expected_partner, 'Partner mismatch! %s vs %s' % (opp.partner_id.name, expected_partner)
assert opp.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'
-
@@ -86,14 +96,15 @@
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_2'))
- assert lead.stage_id.id == ref('crm.stage_lead8'), "Opportunity stage should be 'Lost'."
- assert lead.state == 'cancel', "Lost opportunity is not in 'cancel' state!"
+ assert lead.stage_id.id == ref('crm.stage_lead7'), "Opportunity stage should be 'Lost'."
+ assert lead.stage_id.sequence != 1 and lead.stage_id.probability == 0.0, "Lost opportunity is not in 'cancel' state!"
assert lead.probability == 0.0, "Revenue probability should be 0.0!"
-
I confirm review needs meeting.
-
!python {model: crm.meeting}: |
context.update({'active_model': 'crm.meeting'})
+ self.case_open(cr, uid, [ref('base_calendar.crm_meeting_4')])
-
I invite a user for meeting.
-
diff --git a/addons/crm/wizard/crm_lead_to_opportunity.py b/addons/crm/wizard/crm_lead_to_opportunity.py
index 342ef13f17e..d954e0486cc 100644
--- a/addons/crm/wizard/crm_lead_to_opportunity.py
+++ b/addons/crm/wizard/crm_lead_to_opportunity.py
@@ -21,7 +21,6 @@
from openerp.osv import fields, osv
from openerp.tools.translate import _
-from openerp import tools
import re
class crm_lead2opportunity_partner(osv.osv_memory):
@@ -60,11 +59,11 @@ class crm_lead2opportunity_partner(osv.osv_memory):
if partner_id:
# Search for opportunities that have the same partner and that arent done or cancelled
- ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('state', '!=', 'done')])
+ ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('probability', '<', '100')])
for id in ids:
tomerge.add(id)
if email:
- ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0]), ('state', '!=', 'done')])
+ ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0]), ('probability', '<', '100')])
for id in ids:
tomerge.add(id)
@@ -105,8 +104,8 @@ class crm_lead2opportunity_partner(osv.osv_memory):
context = {}
lead_obj = self.pool.get('crm.lead')
for lead in lead_obj.browse(cr, uid, context.get('active_ids', []), context=context):
- if lead.state in ['done', 'cancel']:
- raise osv.except_osv(_("Warning!"), _("Closed/Cancelled leads cannot be converted into opportunities."))
+ if lead.probability == 100:
+ raise osv.except_osv(_("Warning!"), _("Closed/Dead leads cannot be converted into opportunities."))
return False
def _convert_opportunity(self, cr, uid, ids, vals, context=None):
diff --git a/addons/crm/wizard/crm_merge_opportunities.py b/addons/crm/wizard/crm_merge_opportunities.py
index 43fbaa786ea..289266bfad3 100644
--- a/addons/crm/wizard/crm_merge_opportunities.py
+++ b/addons/crm/wizard/crm_merge_opportunities.py
@@ -62,8 +62,7 @@ class crm_merge_opportunity(osv.osv_memory):
def default_get(self, cr, uid, fields, context=None):
"""
Use active_ids from the context to fetch the leads/opps to merge.
- In order to get merged, these leads/opps can't be in 'Done' or
- 'Cancel' state.
+ In order to get merged, these leads/opps can't be in 'Dead' or 'Closed'
"""
if context is None:
context = {}
@@ -74,7 +73,7 @@ class crm_merge_opportunity(osv.osv_memory):
opp_ids = []
opps = self.pool.get('crm.lead').browse(cr, uid, record_ids, context=context)
for opp in opps:
- if opp.state not in ('done', 'cancel'):
+ if opp.probability < 100:
opp_ids.append(opp.id)
if 'opportunity_ids' in fields:
res.update({'opportunity_ids': opp_ids})
diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py
index 1e3ed2faad1..c655ce2c12b 100644
--- a/addons/crm_claim/crm_claim.py
+++ b/addons/crm_claim/crm_claim.py
@@ -42,7 +42,6 @@ class crm_claim_stage(osv.osv):
'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."),
'section_ids':fields.many2many('crm.case.section', 'section_claim_stage_rel', 'stage_id', 'section_id', string='Sections',
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
- 'state': fields.selection(crm.AVAILABLE_STATES, 'Status', required=True, help="The related status for the stage. The status of your document will automatically change regarding the selected stage. For example, if a stage is related to the status 'Close', when your document reaches this stage, it will be automatically have the 'closed' status."),
'case_default': fields.boolean('Common to All Teams',
help="If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams."),
'fold': fields.boolean('Hide in Views when Empty',
@@ -51,7 +50,6 @@ class crm_claim_stage(osv.osv):
_defaults = {
'sequence': lambda *args: 1,
- 'state': 'draft',
'fold': False,
}
@@ -70,7 +68,7 @@ class crm_claim(osv.osv):
def _get_default_stage_id(self, cr, uid, context=None):
""" Gives default stage_id """
section_id = self._get_default_section_id(cr, uid, context=context)
- return self.stage_find(cr, uid, [], section_id, [('state', '=', 'draft')], context=context)
+ return self.stage_find(cr, uid, [], section_id, [('sequence', '=', '1')], context=context)
_columns = {
'id': fields.integer('ID', readonly=True),
@@ -105,13 +103,6 @@ class crm_claim(osv.osv):
'stage_id': fields.many2one ('crm.claim.stage', 'Stage', track_visibility='onchange',
domain="['|', ('section_ids', '=', section_id), ('case_default', '=', True)]"),
'cause': fields.text('Root Cause'),
- 'state': fields.related('stage_id', 'state', type="selection", store=True,
- selection=crm.AVAILABLE_STATES, string="Status", readonly=True,
- help='The status is set to \'Draft\', when a case is created.\
- If the case is in progress the status is set to \'Open\'.\
- When the case is over, the status is set to \'Done\'.\
- If the case needs to be reviewed then the status is \
- set to \'Pending\'.'),
}
_defaults = {
diff --git a/addons/crm_claim/crm_claim_data.xml b/addons/crm_claim/crm_claim_data.xml
index ed0558f72e9..d897fe2bcb3 100644
--- a/addons/crm_claim/crm_claim_data.xml
+++ b/addons/crm_claim/crm_claim_data.xml
@@ -44,28 +44,23 @@
<record model="crm.claim.stage" id="stage_claim1">
<field name="name">New</field>
- <field name="state">draft</field>
- <field name="sequence">26</field>
+ <field name="sequence">1</field>
<field name="case_default" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim5">
<field name="name">In Progress</field>
- <field name="state">open</field>
<field name="sequence">27</field>
<field name="case_default" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim2">
<field name="name">Settled</field>
- <field name="state">done</field>
<field name="sequence">28</field>
<field name="case_default" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim3">
<field name="name">Rejected</field>
- <field name="state">cancel</field>
<field name="sequence">29</field>
<field name="case_default" eval="True"/>
- <field name="case_refused" eval="True"/>
<field name="fold" eval="True"/>
</record>
diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml
index 28d0f7c731c..5b7e924c205 100644
--- a/addons/crm_claim/crm_claim_view.xml
+++ b/addons/crm_claim/crm_claim_view.xml
@@ -38,7 +38,6 @@
<tree string="Claim Stages">
<field name="sequence"/>
<field name="name"/>
- <field name="state"/>
</tree>
</field>
</record>
@@ -51,7 +50,6 @@
<field name="name"/>
<field name="case_default"/>
<field name="sequence"/>
- <field name="state"/>
<field name="fold"/>
</form>
</field>
@@ -79,7 +77,7 @@
<field name="name">CRM - Claims Tree</field>
<field name="model">crm.claim</field>
<field name="arch" type="xml">
- <tree string="Claims" colors="blue:state=='pending' and not(date_deadline and (date_deadline &lt; current_date));gray:state in ('close', 'cancel');red:date_deadline and (date_deadline &lt; current_date)">
+ <tree string="Claims">
<field name="name"/>
<field name="partner_id"/>
<field name="user_id"/>
@@ -90,7 +88,6 @@
<field name="categ_id" string="Type"/>
<field name="date_deadline" invisible="1"/>
<field name="date_closed" invisible="1"/>
- <field name="state" groups="base.group_no_one"/>
</tree>
</field>
</record>
@@ -113,7 +110,6 @@
<field name="priority"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="date_deadline"/>
- <field name="state" groups="base.group_no_one"/>
</group>
<group colspan="4" col="4">
<notebook>
@@ -191,9 +187,6 @@
<field name="arch" type="xml">
<search string="Search Claims">
<field name="name" string="Claims"/>
- <filter icon="terp-check" string="New" name="current" domain="[('state','=','draft')]" help="New Claims"/>
- <filter icon="terp-camera_test" string="In Progress" domain="[('state','=','open')]" help="In Progress Claims"/>
- <filter icon="terp-gtk-media-pause" string="Pending" domain="[('state','=','pending')]"/>
<separator/>
<filter string="Unassigned Claims" icon="terp-personal-" domain="[('user_id','=', False)]" help="Unassigned Claims" />
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
@@ -203,7 +196,6 @@
<filter string="Responsible" icon="terp-personal" domain="[]" help="Responsible User" context="{'group_by':'user_id'}"/>
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'categ_id'}"/>
- <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}" groups="base.group_no_one"/>
<filter string="Claim Date" icon="terp-go-month" domain="[]" help="Claim Date" context="{'group_by':'date'}"/>
<filter string="Deadline" icon="terp-go-month" domain="[]" context="{'group_by':'date_deadline'}"/>
<filter string="Closure" icon="terp-go-month" domain="[]" help="Date Closed" context="{'group_by':'date_closed'}" groups="base.group_no_one"/>
diff --git a/addons/crm_claim/report/crm_claim_report.py b/addons/crm_claim/report/crm_claim_report.py
index 2ed87505d9c..d389f690fb4 100644
--- a/addons/crm_claim/report/crm_claim_report.py
+++ b/addons/crm_claim/report/crm_claim_report.py
@@ -22,14 +22,6 @@
from openerp.osv import fields,osv
from openerp import tools
-AVAILABLE_STATES = [
- ('draft','Draft'),
- ('open','Open'),
- ('cancel', 'Cancelled'),
- ('done', 'Closed'),
- ('pending','Pending')
-]
-
AVAILABLE_PRIORITIES = [
('5', 'Lowest'),
('4', 'Low'),
@@ -51,7 +43,6 @@ class crm_claim_report(osv.osv):
'user_id':fields.many2one('res.users', 'User', readonly=True),
'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
'nbr': fields.integer('# of Cases', readonly=True),
- 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
'month':fields.selection([('01', 'January'), ('02', 'February'), \
('03', 'March'), ('04', 'April'),\
('05', 'May'), ('06', 'June'), \
@@ -92,7 +83,6 @@ class crm_claim_report(osv.osv):
to_char(c.date, 'YYYY-MM-DD') as day,
to_char(c.date_closed, 'YYYY-MM-DD') as date_closed,
to_char(c.date_deadline, 'YYYY-MM-DD') as date_deadline,
- c.state,
c.user_id,
c.stage_id,
c.section_id,
@@ -109,7 +99,7 @@ class crm_claim_report(osv.osv):
from
crm_claim c
group by to_char(c.date, 'YYYY'), to_char(c.date, 'MM'),to_char(c.date, 'YYYY-MM-DD'),\
- c.state, c.user_id,c.section_id, c.stage_id,\
+ c.user_id,c.section_id, c.stage_id,\
c.categ_id,c.partner_id,c.company_id,c.create_date,
c.priority,c.type_action,c.date_deadline,c.date_closed,c.id
)""")
diff --git a/addons/crm_claim/report/crm_claim_report_view.xml b/addons/crm_claim/report/crm_claim_report_view.xml
index bae02ef8c0c..2d0787ca527 100644
--- a/addons/crm_claim/report/crm_claim_report_view.xml
+++ b/addons/crm_claim/report/crm_claim_report_view.xml
@@ -21,7 +21,6 @@
<field name="email" sum="# Mails"/>
<field name="delay_close" avg="Avg Closing Delay"/>
<field name="delay_expected"/>
- <field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="categ_id" invisible="1"/>
<field name="priority" invisible="1"/>
@@ -37,7 +36,6 @@
<field name="model">crm.claim.report</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Claims" type="bar">
- <field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="user_id"/>
</graph>
@@ -51,10 +49,6 @@
<field name="model">crm.claim.report</field>
<field name="arch" type="xml">
<search string="Search">
- <filter icon="terp-document-new" string="New" domain="[('state','=','draft')]"/>
- <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]"/>
- <filter icon="terp-gtk-media-pause" string="Pending" domain="[('state','=','pending')]"/>
- <separator/>
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]" help="My Sales Team(s)" groups="base.group_multi_salesteams"/>
<separator/>
<filter string="My Company" icon="terp-go-home" context="{'invisible_section': False}" domain="[('section_id.user_id.company_id','=',uid)]" help="My company"/>
@@ -73,8 +67,6 @@
<field name="create_date" />
<field name="date_closed" />
<field name="date_deadline" />
- <filter icon="terp-dialog-close" string="Done" domain="[('state','=','done')]"/>
- <filter icon="gtk-cancel" string="Cancel" domain="[('state','=','cancel')]"/>
</group>
<group expand="1" string="Group By...">
<filter string="Salesperson" name="Salesperson" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}" />
@@ -84,7 +76,6 @@
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'categ_id'}" />
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type_action'}" help="Action Type"/>
- <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}" />
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Day" icon="terp-go-today" domain="[]" context="{'group_by':'day'}" help="Date of claim"/>
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'month'}" help="Month of claim"/>
diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py
index ea58016b4c1..deab9f19a20 100644
--- a/addons/crm_helpdesk/crm_helpdesk.py
+++ b/addons/crm_helpdesk/crm_helpdesk.py
@@ -26,6 +26,14 @@ from openerp import tools
from openerp.tools.translate import _
from openerp.tools import html2plaintext
+AVAILABLE_STATES = [
+ ('draft', 'New'),
+ ('cancel', 'Cancelled'),
+ ('open', 'In Progress'),
+ ('pending', 'Pending'),
+ ('done', 'Closed')
+]
+
class crm_helpdesk(base_state, osv.osv):
""" Helpdesk Cases """
@@ -65,7 +73,7 @@ class crm_helpdesk(base_state, osv.osv):
domain="['|',('section_id','=',False),('section_id','=',section_id),\
('object_id.model', '=', 'crm.helpdesk')]"),
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
- 'state': fields.selection(crm.AVAILABLE_STATES, 'Status', size=16, readonly=True,
+ 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True,
help='The status is set to \'Draft\', when a case is created.\
\nIf the case is in progress the status is set to \'Open\'.\
\nWhen the case is over, the status is set to \'Done\'.\
diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml
index 5c14680ee78..3b253b1c3d4 100644
--- a/addons/crm_partner_assign/crm_lead_view.xml
+++ b/addons/crm_partner_assign/crm_lead_view.xml
@@ -49,7 +49,8 @@
<field name="arch" type="xml">
<field name="partner_id" position="after">
<field name="partner_assigned_id"/>
- </field>
+ <field name="date_assign" invisible="1"/>
+ </field>
</field>
</record>
@@ -60,6 +61,9 @@
<field name="arch" type="xml">
<filter string="Team" position="after">
<filter string="Assigned Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_assigned_id'}"/>
+ <filter string="Assigned Month" icon="terp-go-month"
+ domain="[]" context="{'group_by':'date_assign'}"/>
+
</filter>
<field name="partner_id" position="after">
<field name="partner_assigned_id"/>
diff --git a/addons/crm_partner_assign/crm_portal_view.xml b/addons/crm_partner_assign/crm_portal_view.xml
index a8d342ebb94..ab4cf8868db 100644
--- a/addons/crm_partner_assign/crm_portal_view.xml
+++ b/addons/crm_partner_assign/crm_portal_view.xml
@@ -6,7 +6,7 @@
<field name="model">crm.lead</field>
<field name="priority" eval="32"/>
<field name="arch" type="xml">
- <tree string="Leads" colors="blue:state=='pending';grey:state in ('cancel', 'done');red:stage_id[1]=='Disinterested';black:stage_id[1]=='Interested'">
+ <tree string="Leads" colors="red:stage_id[1]=='Disinterested';black:stage_id[1]=='Interested'">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name" string="Subject"/>
@@ -18,7 +18,6 @@
<field name="type_id" invisible="1"/>
<field name="referred" invisible="1"/>
<field name="channel_id" invisible="1"/>
- <field name="state" invisible="1"/>
<field name="section_id" invisible="context.get('invisible_section', True)" />
<button string="I'm interested" name="case_interested" icon="gtk-index" type="object"/>
@@ -69,7 +68,7 @@
<field name="model">crm.lead</field>
<field name="priority" eval="32"/>
<field name="arch" type="xml">
- <tree string="Leads" colors="blue:state=='pending';grey:state in ('cancel', 'done')">
+ <tree string="Leads">
<field name="date_deadline" invisible="1"/>
<field name="create_date" groups="base.group_no_one"/>
<field name="name" string="Opportunity"/>
@@ -83,7 +82,6 @@
<field name="probability" widget="progressbar" avg="Avg. of Probability"/>
<field name="section_id" invisible="context.get('invisible_section', True)" />
<field name="priority" invisible="1"/>
- <field name="state" invisible="1"/>
</tree>
</field>
</record>
diff --git a/addons/crm_partner_assign/report/crm_lead_report.py b/addons/crm_partner_assign/report/crm_lead_report.py
index 676a8536b74..c7a6b76ee44 100644
--- a/addons/crm_partner_assign/report/crm_lead_report.py
+++ b/addons/crm_partner_assign/report/crm_lead_report.py
@@ -23,13 +23,6 @@ from openerp.osv import fields,osv
from openerp import tools
from openerp.addons.crm import crm
-AVAILABLE_STATES = [
- ('draft','Draft'),
- ('open','Open'),
- ('cancel', 'Cancelled'),
- ('done', 'Closed'),
- ('pending','Pending')
-]
class crm_lead_report_assign(osv.osv):
""" CRM Lead Report """
@@ -43,7 +36,6 @@ class crm_lead_report_assign(osv.osv):
'user_id':fields.many2one('res.users', 'User', readonly=True),
'country_id':fields.many2one('res.country', 'Country', readonly=True),
'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
- 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
'month':fields.selection([('01', 'January'), ('02', 'February'), \
('03', 'March'), ('04', 'April'),\
('05', 'May'), ('06', 'June'), \
@@ -54,7 +46,7 @@ class crm_lead_report_assign(osv.osv):
'date_assign': fields.date('Partner Date', readonly=True),
'create_date': fields.datetime('Create Date', readonly=True),
'day': fields.char('Day', size=128, readonly=True),
- 'delay_open': fields.float('Delay to Open',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
+ 'delay_open': fields.float('Delay to Assign',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
'delay_close': fields.float('Delay to Close',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
'probability': fields.float('Avg Probability',digits=(16,2),readonly=True, group_operator="avg"),
@@ -91,7 +83,6 @@ class crm_lead_report_assign(osv.osv):
to_char(c.create_date, 'YYYY-MM-DD') as creation_date,
to_char(c.date_open, 'YYYY-MM-DD') as opening_date,
to_char(c.date_closed, 'YYYY-mm-dd') as date_closed,
- c.state,
c.date_assign,
c.user_id,
c.probability,
@@ -110,7 +101,7 @@ class crm_lead_report_assign(osv.osv):
c.planned_revenue*(c.probability/100) as probable_revenue,
1 as nbr,
date_trunc('day',c.create_date) as create_date,
- extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
+ extract('epoch' from (c.write_date-c.create_date))/(3600*24) as delay_close,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected,
extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open
FROM
diff --git a/addons/crm_partner_assign/report/crm_lead_report_view.xml b/addons/crm_partner_assign/report/crm_lead_report_view.xml
index fbc46302fd7..7984c2cc3b1 100644
--- a/addons/crm_partner_assign/report/crm_lead_report_view.xml
+++ b/addons/crm_partner_assign/report/crm_lead_report_view.xml
@@ -8,8 +8,6 @@
<field name="model">crm.lead.report.assign</field>
<field name="arch" type="xml">
<search string="Leads Analysis">
- <filter icon="terp-check" string="Current" domain="[('state','in',('draft','open'))]"/>
- <filter icon="terp-dialog-close" string="Closed" domain="[('state','=','done')]"/>
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="grade_id"/>
<field name="user_id"/>
@@ -36,7 +34,6 @@
domain="[]" context="{'group_by':'grade_id'}" />
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
- <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}" />
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" />
<filter string="Assign Date" icon="terp-go-today" domain="[]" name="group_partner_date" context="{'group_by':'date_assign'}"/>
<filter string="Day" icon="terp-go-today" domain="[]" context="{'group_by':'day'}"/>
@@ -54,7 +51,6 @@
<field name="model">crm.lead.report.assign</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Lead Assign" type="bar">
- <field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="user_id"/>
</graph>
@@ -76,14 +72,13 @@
<field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/>
<field name="day" invisible="1"/>
- <field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="type" invisible="1"/>
<field name="company_id" invisible="1" groups="base.group_multi_company"/>
<field name="nbr" string="#Opportunities" sum="#Opportunities"/>
<field name="planned_revenue" sum="Planned Revenues"/>
- <field name="delay_open" sum='Delay to open'/>
+ <field name="delay_open" sum='Delay to Assign'/>
<field name="delay_close" sum='Delay to close'/>
<field name="delay_expected"/>
<field name="probability" widget="progressbar"/>
diff --git a/addons/crm_partner_assign/res_partner_view.xml b/addons/crm_partner_assign/res_partner_view.xml
index 874d2a9f053..6823c262f02 100644
--- a/addons/crm_partner_assign/res_partner_view.xml
+++ b/addons/crm_partner_assign/res_partner_view.xml
@@ -33,134 +33,130 @@
<field name="view_mode">tree,form</field>
</record>
- <menuitem id="res_partner_activation_config_mi" parent="base.menu_config_address_book" action="res_partner_activation_act" groups="base.group_no_one" />
+ <menuitem id="res_partner_activation_config_mi" parent="base.menu_config_address_book" action="res_partner_activation_act" groups="base.group_no_one"/>
- <!--Partner Grade -->
+ <!--Partner Grade -->
- <record id="view_partner_grade_tree" model="ir.ui.view">
- <field name="name">res.partner.grade.tree</field>
- <field name="model">res.partner.grade</field>
- <field name="arch" type="xml">
- <tree string="Partner Grade">
- <field name="sequence" invisible="1" />
- <field name="name" />
- </tree>
- </field>
- </record>
- <record id="view_partner_grade_form" model="ir.ui.view">
- <field name="name">res.partner.grade.form</field>
- <field name="model">res.partner.grade</field>
- <field name="arch" type="xml">
- <form string="Partner Grade" version="7.0">
- <group col="4">
- <group>
- <field name="name" />
- <field name="partner_weight" />
- <div>
- <p class="oe_grey">
- Define a weight to this grade. The weight will be used as default in the partner form to compute the chance for this partner to get leads. For instance, for business purpose, you can define a target revenue for each grade. To give the same chance to each partner to get leads, keep 1 in this field.
- </p>
- </div>
- </group>
- <group>
- <field name="sequence" />
- <field name="active" />
- </group>
- </group>
- </form>
- </field>
- </record>
- <record id="res_partner_grade_action" model="ir.actions.act_window">
- <field name="name">Partner Grade</field>
- <field name="res_model">res.partner.grade</field>
- <field name="view_type">form</field>
- </record>
- <menuitem action="res_partner_grade_action" id="menu_res_partner_grade_action" groups="base.group_no_one" parent="base.menu_crm_config_lead" />
- <!-- Partner form -->
- <record id="view_res_partner_filter_assign_tree" model="ir.ui.view">
- <field name="name">res.partner.geo.inherit.tree</field>
- <field name="model">res.partner</field>
- <field name="inherit_id" ref="base.view_partner_tree" />
- <field name="arch" type="xml">
- <field name="user_id" position="after">
- <field name="date_review_next" />
- <field name="grade_id" />
- <field name="activation" />
- </field>
+ <record id="view_partner_grade_tree" model="ir.ui.view">
+ <field name="name">res.partner.grade.tree</field>
+ <field name="model">res.partner.grade</field>
+ <field name="arch" type="xml">
+ <tree string="Partner Grade">
+ <field name="sequence" invisible="1"/>
+ <field name="name"/>
+ </tree>
+ </field>
+ </record>
+ <record id="view_partner_grade_form" model="ir.ui.view">
+ <field name="name">res.partner.grade.form</field>
+ <field name="model">res.partner.grade</field>
+ <field name="arch" type="xml">
+ <form string="Partner Grade" version="7.0">
+ <group col="4">
+ <field name="name"/>
+ <field name="sequence"/>
+ <field name="active"/>
+ </group>
+ </form>
+ </field>
+ </record>
+ <record id="res_partner_grade_action" model="ir.actions.act_window">
+ <field name="name">Partner Grade</field>
+ <field name="res_model">res.partner.grade</field>
+ <field name="view_type">form</field>
+ </record>
+ <menuitem action="res_partner_grade_action" id="menu_res_partner_grade_action"
+ groups="base.group_no_one"
+ parent="base.menu_crm_config_lead" />
+
+ <!-- Partner form -->
+ <record id="view_res_partner_filter_assign_tree" model="ir.ui.view">
+ <field name="name">res.partner.geo.inherit.tree</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_partner_tree"/>
+ <field name="arch" type="xml">
+ <field name="user_id" position="after">
+ <field name="date_review_next"/>
+ <field name="grade_id"/>
+ <field name="activation"/>
</field>
- </record>
+ </field>
+ </record>
- <record id="view_res_partner_filter_assign" model="ir.ui.view">
- <field name="name">res.partner.geo.inherit.search</field>
- <field name="model">res.partner</field>
- <field name="inherit_id" ref="base.view_res_partner_filter" />
- <field name="arch" type="xml">
- <filter string="Salesperson" position="after">
- <filter string="Activation" context="{'group_by' : 'activation'}" domain="[]" icon="terp-personal" />
- </filter>
- <field name="category_id" position="after">
- <field name="grade_id" />
- </field>
+ <record id="view_res_partner_filter_assign" model="ir.ui.view">
+ <field name="name">res.partner.geo.inherit.search</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_res_partner_filter"/>
+ <field name="arch" type="xml">
+ <filter string="Salesperson" position="after">
+ <filter string="Activation" context="{'group_by' : 'activation'}" domain="[]" icon="terp-personal" />
+ </filter>
+ <field name="category_id" position="after">
+ <field name="grade_id"/>
</field>
- </record>
+ </field>
+ </record>
- <record id="view_crm_partner_geo_form" model="ir.ui.view">
- <field name="name">res.partner.geo.inherit</field>
- <field name="model">res.partner</field>
- <field name="inherit_id" ref="base.view_partner_form" />
- <field name="arch" type="xml">
- <xpath expr="//notebook[last()]" position="inside">
- <page string="Forwarded Leads">
+ <record id="view_crm_partner_geo_form" model="ir.ui.view">
+ <field name="name">res.partner.geo.inherit</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_partner_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//notebook[last()]" position="inside">
+ <page string="Geo Localization">
+ <group>
<group>
- <group string="Partner Activation">
- <label for="partner_latitude" string="Geolocalisation" />
- <div class="oe_title oe_inline">
- <h3 class="oe_inline">
- <span class="oe_grey">( </span>
- <field name="partner_latitude" nolabel="1" readonly="1" class="oe_inline" />
- <span class="oe_grey oe_inline" attrs="{'invisible':[('partner_latitude','&lt;=',0)]}">N </span>
- <span class="oe_grey oe_inline" attrs="{'invisible':[('partner_latitude','&gt;=',0)]}">S </span>
- <field name="partner_longitude" class="oe_inline" readonly="1" nolabel="1" />
- <span class="oe_grey oe_inline" attrs="{'invisible':[('partner_longitude','&lt;=',0)]}">E </span>
- <span class="oe_grey oe_inline" attrs="{'invisible':[('partner_longitude','&gt;=',0)]}">W </span>
- <span class="oe_grey">) </span>
- </h3>
- <button string="Geolocalize" name="geo_localize" class="oe_inline" type="object" />
- </div>
- <field name="grade_id" widget="selection" on_change="onchange_grade_id(grade_id)" />
- <field name="partner_weight" class="oe_inline" />
- <div colspan="2">
- <p class="oe_grey">
- Higher is the value, higher is the probability for this partner to get more leads.
- </p>
- </div>
- </group>
- <group>
- <separator string="Partner Review" colspan="2" />
- <field name="date_review" />
- <field name="date_review_next" />
- <field name="date_partnership" />
- </group>
- <group>
- </group>
+ <separator string="Partner Activation" colspan="2"/>
+ <field name="grade_id" widget="selection"/>
+ <field name="activation" widget="selection"/>
+ <field name="partner_weight"/>
</group>
- <newline />
- <separator string="Forwarded Leads" colspan="2" />
- <field name="opportunity_assigned_ids" colspan="4" nolabel="1">
- <tree string="Assigned Opportunities" colors="blue:state=='pending';gray:state=='cancel'">
- <field name="name" />
- <field name="contact_name" />
- <field name="email_from" />
- <field name="phone" />
- <field name="stage_id" />
- <field name="state" invisible="1" />
- </tree>
- </field>
- </page>
- </xpath>
- </field>
- </record>
+ <group>
+ <separator string="Partner Review" colspan="2"/>
+ <field name="date_review"/>
+ <field name="date_review_next"/>
+ <field name="date_partnership"/>
+ </group>
+ </group>
+ <group colspan="2" col="2">
+ <separator string="Geo Localization" colspan="2"/>
+ <button
+ string="Geo Localize"
+ name="geo_localize"
+ colspan="2"
+ icon="gtk-apply"
+ type="object"/>
+ <field name="partner_latitude"/>
+ <field name="partner_longitude"/>
+ <field name="date_localization"/>
+ </group>
+ <newline/>
+
+ <field name="opportunity_assigned_ids" colspan="4" nolabel="1">
+ <tree string="Assigned Opportunities">
+ <field name="create_date"/>
+ <field name="name"/>
+ <field name="type"/>
+ <field name="stage_id"/>
+ <field name="section_id"
+ invisible="context.get('invisible_section', True)"
+ groups="base.group_multi_salesteams"/>
+ <field name="user_id" />
+ <button string="Convert to Opportunity"
+ name="convert_opportunity"
+ type="object"
+ attrs="{'invisible':[('type','=','opportunity'),('probability', '=', 100)]}" />
+ <button name="case_escalate" string="Escalate"
+ type="object"
+ icon="gtk-go-up"
+ attrs="{'invisible':[('probability', '=', 100)]}" />
+ </tree>
+ </field>
+ </page>
+ </xpath>
+ </field>
+ </record>
</data>
</openerp>
diff --git a/addons/email_template/doc/changelog.rst b/addons/email_template/doc/changelog.rst
index 2581175fe0b..77e342c920a 100644
--- a/addons/email_template/doc/changelog.rst
+++ b/addons/email_template/doc/changelog.rst
@@ -6,6 +6,7 @@ Changelog
`trunk (saas-2)`
----------------
+ - ``mail.compose.message``: added support of ``mail_server_id`` from template
- Server action update
- added `email` server action type, now entirely based on email templates. \ No newline at end of file
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index 746c2cc55f6..92bf7c3aedf 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -22,6 +22,7 @@
from openerp import tools
from openerp.osv import osv, fields
+
def _reopen(self, res_id, model):
return {'type': 'ir.actions.act_window',
'view_mode': 'form',
@@ -34,7 +35,8 @@ def _reopen(self, res_id, model):
'context': {
'default_model': model,
},
- }
+ }
+
class mail_compose_message(osv.TransientModel):
_inherit = 'mail.compose.message'
@@ -58,7 +60,7 @@ class mail_compose_message(osv.TransientModel):
context = {}
wizard_context = dict(context)
for wizard in self.browse(cr, uid, ids, context=context):
- if wizard.template_id and not wizard.template_id.user_signature:
+ if wizard.template_id:
wizard_context['mail_notify_user_signature'] = False # template user_signature is added when generating body_html
if not wizard.attachment_ids or wizard.composition_mode == 'mass_mail' or not wizard.template_id:
continue
@@ -75,7 +77,7 @@ class mail_compose_message(osv.TransientModel):
""" - mass_mailing: we cannot render, so return the template values
- normal mode: return rendered values """
if template_id and composition_mode == 'mass_mail':
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'mail_server_id']
template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
elif template_id:
@@ -95,7 +97,7 @@ class mail_compose_message(osv.TransientModel):
}
values['attachment_ids'].append(ir_attach_obj.create(cr, uid, data_attach, context=context))
else:
- values = self.default_get(cr, uid, ['subject', 'body', 'email_from', 'email_to', 'email_cc', 'partner_to', 'reply_to', 'attachment_ids'], context=context)
+ values = self.default_get(cr, uid, ['subject', 'body', 'email_from', 'email_to', 'email_cc', 'partner_to', 'reply_to', 'attachment_ids', 'mail_server_id'], context=context)
if values.get('body_html'):
values['body'] = values.pop('body_html')
@@ -150,7 +152,7 @@ class mail_compose_message(osv.TransientModel):
mail.compose.message, transform email_cc and email_to into partner_ids """
template_values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
# filter template values
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments']
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments', 'mail_server_id']
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
values['body'] = values.pop('body_html', '')
diff --git a/addons/google_drive/i18n/es.po b/addons/google_drive/i18n/es.po
index 65d28726ba4..8e7770930e0 100644
--- a/addons/google_drive/i18n/es.po
+++ b/addons/google_drive/i18n/es.po
@@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2013-06-27 16:03+0000\n"
-"PO-Revision-Date: 2012-12-12 12:51+0000\n"
-"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
+"PO-Revision-Date: 2013-08-07 02:00+0000\n"
+"Last-Translator: Alejandro Santana <alejandrosantana@anubia.es>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-06-28 05:42+0000\n"
-"X-Generator: Launchpad (build 16681)\n"
+"X-Launchpad-Export-Date: 2013-08-08 04:39+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
#. module: google_drive
#: model:ir.ui.menu,name:google_drive.menu_google_drive_config
msgid "Google Drive configuration"
-msgstr ""
+msgstr "Configuración de Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:48
@@ -39,6 +39,11 @@ msgid ""
"in your Google Drive and in OpenERP attachment will be named\n"
" 'Agrolait_SO0001_Sales'."
msgstr ""
+"El nombre del documento adjunto puede contener información fija o variable. "
+"Para distinguir documentos en Google Drive, use palabras y campos fijos. "
+"Así, en el ejemplo anterior, si se escribió 'Agrolait_%(name)s_Sales' en el "
+"campo de nombre de GoogleDrive, el documento en su Google Drive y en los "
+"adjuntos de OpenERP se llamarán 'Agrolait_SO0001_Sales'."
#. module: google_drive
#: view:google.drive.config:0
@@ -46,16 +51,18 @@ msgid ""
"- If filter is not specified, link of google document will appear in "
"\"More\" option for all users for all opportunities."
msgstr ""
+"- Si no especifica un filtro, el enlace del documento de Google aparecerá en "
+"la opción \"Más\" para todos los usuarios para todas las oportunidades."
#. module: google_drive
#: view:google.drive.config:0
msgid "To create a new filter:"
-msgstr ""
+msgstr "Para crear un nuevo filtro:"
#. module: google_drive
#: model:ir.model,name:google_drive.model_base_config_settings
msgid "base.config.settings"
-msgstr ""
+msgstr "base.config.settings"
#. module: google_drive
#: model:ir.actions.act_window,help:google_drive.action_google_drive_users_config
@@ -73,17 +80,29 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" Pulse para añadir una plantilla.\n"
+" </p>\n"
+" <p>\n"
+" Enlace sus propias plantillas de Google Drive a "
+"cualquier registro de OpenERP. Si tiene documentos realmente específicos que "
+"quiere que su colaborador rellene (como usar una hoja de cálculo para "
+"controlar la calidad de su producto o revisar los detalles de entrega de "
+"cada pedido en un país extranjero,...) es muy sencillo gestionarlo. "
+"Enlácelos en OpenERP y úselos para colaborar con sus empleados.\n"
+" </p>\n"
+" "
#. module: google_drive
#: code:addons/google_drive/google_drive.py:150
#, python-format
msgid "Incorrect URL!"
-msgstr ""
+msgstr "¡URL incorrecta!"
#. module: google_drive
#: view:base.config.settings:0
msgid "Configure your templates"
-msgstr ""
+msgstr "Configure sus plantillas"
#. module: google_drive
#: help:google.drive.config,name_template:0
@@ -91,6 +110,8 @@ msgid ""
"Choose how the new google drive will be named, on google side. Eg. "
"gdoc_%(field_name)s"
msgstr ""
+"Elija el nombre de la nueva unidad de Google Drive, en el lado de Google. "
+"P.ej.: gdoc_%(field_name)s"
#. module: google_drive
#: view:google.drive.config:0
@@ -98,6 +119,8 @@ msgid ""
"- Go to the OpenERP document you want to filter. For instance, go to "
"Opportunities and search on Sales Department."
msgstr ""
+"- Vaya al documento de OpenERP que quiera filtrar. Por ejemplo, vaya a "
+"Oportunidades y busque en el Departamento de ventas."
#. module: google_drive
#: view:google.drive.config:0
@@ -105,6 +128,8 @@ msgid ""
"- In this \"Search\" view, select the option \"Save Current Filter\", enter "
"the name (Ex: Sales Department)"
msgstr ""
+"- En esta vista de \"Búsqueda\", seleccione la opción \"Guardar filtro "
+"actual\" e introduzca el nombre (p.ej.: Departamento de ventas)"
#. module: google_drive
#: view:google.drive.config:0
@@ -113,6 +138,9 @@ msgid ""
"\"More\" options will appear for all users in opportunities of Sales "
"Department."
msgstr ""
+"- Si selecciona \"Compartir con todos los usuarios\", el enlace al documento "
+"de Google en la opción \"Más\" aparecerá para todos los usuarios en las "
+"oportunidades del Departamento de ventas."
#. module: google_drive
#: view:google.drive.config:0
@@ -121,23 +149,28 @@ msgid ""
"\"More\" options will not appear for other users in opportunities of Sales "
"Department."
msgstr ""
+"- Si no selecciona \"Compartir con todos los usuarios\", el enlace al "
+"documento de Google en la opción \"Más\" no aparecerá para otros usuarios en "
+"las oportunidades del Departamento de ventas."
#. module: google_drive
#: code:addons/google_drive/google_drive.py:48
#, python-format
msgid "At least one key cannot be found in your Google Drive name pattern"
msgstr ""
+"No se ha podido encontrar al menos una clave de su patrón de nombres de "
+"Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:150
#, python-format
msgid "Please enter a valid Google Document URL."
-msgstr ""
+msgstr "Por favor, introduzca una URL de documento de Google válida."
#. module: google_drive
#: field:google.drive.config,google_drive_client_id:0
msgid "Google Client "
-msgstr ""
+msgstr "Cliente de Google "
#. module: google_drive
#: view:google.drive.config:0
@@ -145,43 +178,45 @@ msgid ""
"https://docs.google.com/document/d/1vOtpJK9scIQz6taD9tJRIETWbEw3fSiaQHArsJYcu"
"a4/edit"
msgstr ""
+"https://docs.google.com/document/d/1vOtpJK9scIQz6taD9tJRIETWbEw3fSiaQHArsJYcu"
+"a4/edit"
#. module: google_drive
#: field:google.drive.config,filter_id:0
msgid "Filter"
-msgstr ""
+msgstr "Filtro"
#. module: google_drive
#: field:google.drive.config,name_template:0
msgid "Google Drive Name Pattern"
-msgstr ""
+msgstr "Patrón de nombres de Google Drive"
#. module: google_drive
#: help:base.config.settings,google_drive_uri:0
msgid "The URL to generate the authorization code from Google"
-msgstr ""
+msgstr "La URL para generar el código de autorización de Google"
#. module: google_drive
#: model:ir.filters,name:google_drive.filter_partner
msgid "Customer"
-msgstr ""
+msgstr "Cliente"
#. module: google_drive
#: field:google.drive.config,google_drive_resource_id:0
msgid "Resource Id"
-msgstr ""
+msgstr "ID del recurso"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:91
#, python-format
msgid "The Google Template cannot be found. Maybe it has been deleted."
-msgstr ""
+msgstr "No se encuentra la plantilla de Google. Tal vez se haya eliminado."
#. module: google_drive
#: model:ir.actions.act_window,name:google_drive.action_google_drive_users_config
#: model:ir.ui.menu,name:google_drive.menu_google_drive_model_config
msgid "Google Drive Templates"
-msgstr ""
+msgstr "Plantillas de Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:81
@@ -190,23 +225,27 @@ msgid ""
"Something went wrong during the token generation. Please request again an "
"authorization code in %(menu:base_setup.menu_general_configuration)s."
msgstr ""
+"Algo ha ido mal durante la creación del testigo. Por favor, solicite un "
+"código de autorización otra vez en "
+"%(menu:base_setup.menu_general_configuration)s."
#. module: google_drive
#: code:addons/google_drive/google_drive.py:124
#, python-format
msgid "Google Drive Error!"
-msgstr ""
+msgstr "¡Error de Google Drive!"
#. module: google_drive
#: field:base.config.settings,google_drive_uri:0
msgid "URI"
-msgstr ""
+msgstr "URI"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:124
#, python-format
msgid "Creating google drive may only be done by one at a time."
msgstr ""
+"Es posible que la creación de Google Drive sólo se pueda hacer de una en una."
#. module: google_drive
#: field:google.drive.config,model:0
@@ -217,38 +256,40 @@ msgstr "Modelo"
#. module: google_drive
#: view:google.drive.config:0
msgid "Google Drive Configuration"
-msgstr ""
+msgstr "Configuración de Google Drive"
#. module: google_drive
#: field:google.drive.config,name:0
msgid "Template Name"
-msgstr ""
+msgstr "Nombre de la plantilla"
#. module: google_drive
#: constraint:google.drive.config:0
msgid ""
"Model of selected filter is not matching with model of current template."
msgstr ""
+"El modelo del filtro seleccionado no coincide con el modelo de la plantilla "
+"actual."
#. module: google_drive
#: field:google.drive.config,google_drive_template_url:0
msgid "Template URL"
-msgstr ""
+msgstr "URL de la plantilla"
#. module: google_drive
#: view:base.config.settings:0
msgid "and paste it here"
-msgstr ""
+msgstr "y péguela aquí"
#. module: google_drive
#: field:base.config.settings,google_drive_authorization_code:0
msgid "Authorization Code"
-msgstr ""
+msgstr "Cídigo de autorización"
#. module: google_drive
#: model:ir.model,name:google_drive.model_google_drive_config
msgid "Google Drive templates config"
-msgstr ""
+msgstr "Configuración de plantillas de Google Drive"
#. module: google_drive
#: code:addons/google_drive/google_drive.py:64
@@ -257,3 +298,6 @@ msgid ""
"You haven't configured 'Authorization Code' generated from google, Please "
"generate and configure it in %(menu:base_setup.menu_general_configuration)s."
msgstr ""
+"No ha configurado el 'código de autorización' generado por Google. Por "
+"favor, genérelo y configúrelo en "
+"%(menu:base_setup.menu_general_configuration)s."
diff --git a/addons/google_spreadsheet/google_spreadsheet.py b/addons/google_spreadsheet/google_spreadsheet.py
index 2333adf6751..693300904d0 100644
--- a/addons/google_spreadsheet/google_spreadsheet.py
+++ b/addons/google_spreadsheet/google_spreadsheet.py
@@ -19,13 +19,16 @@
##############################################################################
import simplejson
+import logging
from lxml import etree
import re
-import requests
+import urllib
+import urllib2
from openerp.osv import osv
from openerp import SUPERUSER_ID
+_logger = logging.getLogger(__name__)
class config(osv.osv):
_inherit = 'google.drive.config'
@@ -83,7 +86,14 @@ class config(osv.osv):
</entry>
</feed>''' % (spreadsheet_key, spreadsheet_key, spreadsheet_key, formula.replace('"', '&quot;'), spreadsheet_key, spreadsheet_key, config_formula.replace('"', '&quot;'))
- requests.post('https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/batch?v=3&access_token=%s' % (spreadsheet_key, access_token), data=request, headers={'content-type': 'application/atom+xml', 'If-Match': '*'})
+ try:
+ req = urllib2.Request(
+ 'https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/batch?%s' % (spreadsheet_key, urllib.urlencode({'v': 3, 'access_token': access_token})),
+ data=request,
+ headers={'content-type': 'application/atom+xml', 'If-Match': '*'})
+ urllib2.urlopen(req)
+ except (urllib2.HTTPError, urllib2.URLError):
+ _logger.warning("An error occured while writting the formula on the Google Spreadsheet.")
description = '''
formula: %s
diff --git a/addons/hr_holidays/doc/changelog.rst b/addons/hr_holidays/doc/changelog.rst
new file mode 100644
index 00000000000..b286a60d1b5
--- /dev/null
+++ b/addons/hr_holidays/doc/changelog.rst
@@ -0,0 +1,13 @@
+.. _changelog:
+
+Changelog
+=========
+
+`trunk (saas-2)`
+----------------
+
+ - updated ``hr.holidays`` workflow. It now starts in ``confirm`` state. In
+ ``confirm```and ``refuse`` a Reset to Draft has been added in view / workflow,
+ allowing to edit the request. Added a ``can_reset`` computed field to enable
+ this transition. A user can edit its own requests, or all requests if he is
+ an Hr Manager.
diff --git a/addons/hr_holidays/doc/index.rst b/addons/hr_holidays/doc/index.rst
new file mode 100644
index 00000000000..dc87c275b74
--- /dev/null
+++ b/addons/hr_holidays/doc/index.rst
@@ -0,0 +1,13 @@
+Hr Holidays module documentation
+================================
+
+Hr Holidays documentation topics
+''''''''''''''''''''''''''''''''
+
+Changelog
+'''''''''
+
+.. toctree::
+ :maxdepth: 1
+
+ changelog.rst
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index f9eee9cd243..008c711a1f0 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -22,11 +22,10 @@
##############################################################################
import datetime
+import math
import time
-from itertools import groupby
-from operator import attrgetter, itemgetter
+from operator import attrgetter
-import math
from openerp import tools
from openerp.osv import fields, osv
from openerp.tools.translate import _
@@ -36,40 +35,37 @@ class hr_holidays_status(osv.osv):
_name = "hr.holidays.status"
_description = "Leave Type"
- def get_days(self, cr, uid, ids, employee_id, return_false, context=None):
- cr.execute("""SELECT id, type, number_of_days, holiday_status_id FROM hr_holidays WHERE employee_id = %s AND state='validate' AND holiday_status_id in %s""",
- [employee_id, tuple(ids)])
- result = sorted(cr.dictfetchall(), key=lambda x: x['holiday_status_id'])
- grouped_lines = dict((k, [v for v in itr]) for k, itr in groupby(result, itemgetter('holiday_status_id')))
- res = {}
- for record in self.browse(cr, uid, ids, context=context):
- res[record.id] = {}
- max_leaves = leaves_taken = 0
- if not return_false:
- if record.id in grouped_lines:
- leaves_taken = -sum([item['number_of_days'] for item in grouped_lines[record.id] if item['type'] == 'remove'])
- max_leaves = sum([item['number_of_days'] for item in grouped_lines[record.id] if item['type'] == 'add'])
- res[record.id]['max_leaves'] = max_leaves
- res[record.id]['leaves_taken'] = leaves_taken
- res[record.id]['remaining_leaves'] = max_leaves - leaves_taken
- return res
+ def get_days(self, cr, uid, ids, employee_id, context=None):
+ result = dict((id, dict(max_leaves=0, leaves_taken=0, remaining_leaves=0,
+ virtual_remaining_leaves=0)) for id in ids)
+ holiday_ids = self.pool['hr.holidays'].search(cr, uid, [('employee_id', '=', employee_id),
+ ('state', 'in', ['confirm', 'validate1', 'validate']),
+ ('holiday_status_id', 'in', ids)
+ ], context=context)
+ for holiday in self.pool['hr.holidays'].browse(cr, uid, holiday_ids, context=context):
+ status_dict = result[holiday.holiday_status_id.id]
+ if holiday.type == 'add':
+ status_dict['virtual_remaining_leaves'] += holiday.number_of_days
+ if holiday.state == 'validate':
+ status_dict['max_leaves'] += holiday.number_of_days
+ status_dict['remaining_leaves'] += holiday.number_of_days
+ elif holiday.type == 'remove': # number of days is negative
+ status_dict['virtual_remaining_leaves'] += holiday.number_of_days
+ if holiday.state == 'validate':
+ status_dict['leaves_taken'] -= holiday.number_of_days
+ status_dict['remaining_leaves'] += holiday.number_of_days
+ return result
def _user_left_days(self, cr, uid, ids, name, args, context=None):
- return_false = False
employee_id = False
- res = {}
- if context and context.has_key('employee_id'):
- if not context['employee_id']:
- return_false = True
+ if context and 'employee_id' in context:
employee_id = context['employee_id']
else:
- employee_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)], context=context)
+ employee_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
if employee_ids:
employee_id = employee_ids[0]
- else:
- return_false = True
if employee_id:
- res = self.get_days(cr, uid, ids, employee_id, return_false, context=context)
+ res = self.get_days(cr, uid, ids, employee_id, context=context)
else:
res = dict.fromkeys(ids, {'leaves_taken': 0, 'remaining_leaves': 0, 'max_leaves': 0})
return res
@@ -84,6 +80,7 @@ class hr_holidays_status(osv.osv):
'max_leaves': fields.function(_user_left_days, string='Maximum Allowed', help='This value is given by the sum of all holidays requests with a positive value.', multi='user_left_days'),
'leaves_taken': fields.function(_user_left_days, string='Leaves Already Taken', help='This value is given by the sum of all holidays requests with a negative value.', multi='user_left_days'),
'remaining_leaves': fields.function(_user_left_days, string='Remaining Leaves', help='Maximum Leaves Allowed - Leaves Already Taken', multi='user_left_days'),
+ 'virtual_remaining_leaves': fields.function(_user_left_days, string='Virtual Remaining Leaves', help='Maximum Leaves Allowed - Leaves Already Taken - Leaves Waiting Approval', multi='user_left_days'),
'double_validation': fields.boolean('Apply Double Validation', help="When selected, the Allocation/Leave Requests for this type require a second validation to be approved."),
}
_defaults = {
@@ -92,8 +89,6 @@ class hr_holidays_status(osv.osv):
}
def name_get(self, cr, uid, ids, context=None):
- if not ids:
- return []
res = []
for record in self.browse(cr, uid, ids, context=context):
name = record.name
@@ -134,6 +129,19 @@ class hr_holidays(osv.osv):
result[hol.id] = hol.number_of_days_temp
return result
+ def _get_can_reset(self, cr, uid, ids, name, arg, context=None):
+ """User can reset a leave request if it is its own leave request or if
+ he is an Hr Manager. """
+ user = self.pool['res.users'].browse(cr, uid, uid, context=context)
+ group_hr_manager_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_manager')[1]
+ if group_hr_manager_id in [g.id for g in user.groups_id]:
+ return dict.fromkeys(ids, True)
+ result = dict.fromkeys(ids, False)
+ for holiday in self.browse(cr, uid, ids, context=context):
+ if holiday.employee_id and holiday.employee_id.user_id and holiday.employee_id.user_id.id == uid:
+ result[holiday.id] = True
+ return result
+
def _check_date(self, cr, uid, ids):
for holiday in self.browse(cr, uid, ids):
holiday_ids = self.search(cr, uid, [('date_from', '<=', holiday.date_to), ('date_to', '>=', holiday.date_from), ('employee_id', '=', holiday.employee_id.id), ('id', '<>', holiday.id)])
@@ -167,10 +175,13 @@ class hr_holidays(osv.osv):
'holiday_type': fields.selection([('employee','By Employee'),('category','By Employee Tag')], 'Allocation Mode', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}, help='By Employee: Allocation/Request for individual Employee, By Employee Tag: Allocation/Request for group of employees in category', required=True),
'manager_id2': fields.many2one('hr.employee', 'Second Approval', readonly=True, help='This area is automaticly filled by the user who validate the leave with second level (If Leave type need second validation)'),
'double_validation': fields.related('holiday_status_id', 'double_validation', type='boolean', relation='hr.holidays.status', string='Apply Double Validation'),
+ 'can_reset': fields.function(
+ _get_can_reset,
+ type='boolean'),
}
_defaults = {
'employee_id': _employee_get,
- 'state': 'draft',
+ 'state': 'confirm',
'type': 'remove',
'user_id': lambda obj, cr, uid, context: uid,
'holiday_type': 'employee'
@@ -302,27 +313,20 @@ class hr_holidays(osv.osv):
if context is None:
context = {}
context = dict(context, mail_create_nolog=True)
- return super(hr_holidays, self).create(cr, uid, values, context=context)
-
- def write(self, cr, uid, ids, vals, context=None):
- check_fnct = self.pool.get('hr.holidays.status').check_access_rights
- for holiday in self.browse(cr, uid, ids, context=context):
- if holiday.state in ('validate','validate1') and not check_fnct(cr, uid, 'write', raise_exception=False):
- raise osv.except_osv(_('Warning!'),_('You cannot modify a leave request that has been approved. Contact a human resource manager.'))
- return super(hr_holidays, self).write(cr, uid, ids, vals, context=context)
+ hol_id = super(hr_holidays, self).create(cr, uid, values, context=context)
+ self.check_holidays(cr, uid, [hol_id], context=context)
+ return hol_id
- def set_to_draft(self, cr, uid, ids, context=None):
+ def holidays_reset(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {
'state': 'draft',
'manager_id': False,
'manager_id2': False,
})
- self.delete_workflow(cr, uid, ids)
- self.create_workflow(cr, uid, ids)
to_unlink = []
for record in self.browse(cr, uid, ids, context=context):
for record2 in record.linked_request_ids:
- self.set_to_draft(cr, uid, [record2.id], context=context)
+ self.holidays_reset(cr, uid, [record2.id], context=context)
to_unlink.append(record2.id)
if to_unlink:
self.unlink(cr, uid, to_unlink, context=context)
@@ -421,13 +425,16 @@ class hr_holidays(osv.osv):
return True
def check_holidays(self, cr, uid, ids, context=None):
- holi_status_obj = self.pool.get('hr.holidays.status')
- for record in self.browse(cr, uid, ids):
- if record.holiday_type == 'employee' and record.type == 'remove':
- if record.employee_id and not record.holiday_status_id.limit:
- leaves_rest = holi_status_obj.get_days( cr, uid, [record.holiday_status_id.id], record.employee_id.id, False)[record.holiday_status_id.id]['remaining_leaves']
- if leaves_rest < record.number_of_days_temp:
- raise osv.except_osv(_('Warning!'), _('There are not enough %s allocated for employee %s; please create an allocation request for this leave type.') % (record.holiday_status_id.name, record.employee_id.name))
+ for record in self.browse(cr, uid, ids, context=context):
+ if record.holiday_type != 'employee' or record.type != 'remove' or not record.employee_id or record.holiday_status_id.limit:
+ continue
+ leave_days = self.pool.get('hr.holidays.status').get_days(cr, uid, [record.holiday_status_id.id], record.employee_id.id, context=context)[record.holiday_status_id.id]
+ if leave_days['remaining_leaves'] < record.number_of_days_temp:
+ raise osv.except_osv(_('Warning!'),
+ _('There are not enough remaining days available in %s for employee %s.') % (record.holiday_status_id.name, record.employee_id.name))
+ if leave_days['virtual_remaining_leaves'] < record.number_of_days_temp:
+ raise osv.except_osv(_('Warning!'),
+ _('Other pending requests already book too much days in %s for employee %s.') % (record.holiday_status_id.name, record.employee_id.name))
return True
# -----------------------------
diff --git a/addons/hr_holidays/hr_holidays_data.xml b/addons/hr_holidays/hr_holidays_data.xml
index 2b370f08821..703fa74a2ee 100644
--- a/addons/hr_holidays/hr_holidays_data.xml
+++ b/addons/hr_holidays/hr_holidays_data.xml
@@ -49,7 +49,7 @@
<record id="mt_holidays_confirmed" model="mail.message.subtype">
<field name="name">To Approve</field>
<field name="res_model">hr.holidays</field>
- <field name="description">Request created and waiting confirmation</field>
+ <field name="description">Request confirmed and waiting approval</field>
</record>
<record id="mt_holidays_approved" model="mail.message.subtype">
<field name="name">Approved</field>
diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml
index 85bbcb96f94..d532a8e9bbb 100644
--- a/addons/hr_holidays/hr_holidays_view.xml
+++ b/addons/hr_holidays/hr_holidays_view.xml
@@ -53,11 +53,14 @@
<field name="priority">1</field>
<field name="arch" type="xml">
<form string="Leave Request" version="7.0">
+ <field name="can_reset" invisible="1"/>
<header>
+ <button string="Confirm" name="confirm" states="draft" type="workflow" class="oe_highlight"/>
<button string="Approve" name="validate" states="confirm" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Validate" name="second_validate" states="validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Refuse" name="refuse" states="confirm,validate1,validate" type="workflow" groups="base.group_hr_user"/>
- <button string="Reset to New" name="set_to_draft" states="refuse" type="object" groups="base.group_hr_user"/>
+ <button string="Reset to Draft" name="reset" type="workflow"
+ attrs="{'invisible': ['|', ('can_reset', '=', False), ('state', 'not in', ['confirm', 'refuse'])]}"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate" statusbar_colors='{"confirm":"blue","validate1":"blue","refuse":"red"}'/>
</header>
<sheet string="Leave Request">
@@ -98,11 +101,14 @@
<field name="model">hr.holidays</field>
<field name="arch" type="xml">
<form string="Allocation Request" version="7.0">
+ <field name="can_reset" invisible="1"/>
<header>
+ <button string="Confirm" name="confirm" states="draft" type="workflow" class="oe_highlight"/>
<button string="Approve" name="validate" states="confirm" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Validate" name="second_validate" states="validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Refuse" name="refuse" states="confirm,validate,validate1" type="workflow" groups="base.group_hr_user"/>
- <button string="Reset to New" name="set_to_draft" states="cancel,refuse" type="object" groups="base.group_hr_user"/>
+ <button string="Reset to Draft" name="reset" type="workflow"
+ attrs="{'invisible': ['|', ('can_reset', '=', False), ('state', 'not in', ['confirm', 'refuse'])]}"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate" statusbar_colors='{"confirm":"blue","validate1":"blue","refuse":"red"}'/>
</header>
<sheet>
@@ -163,7 +169,7 @@
<button string="Submit to Manager" name="confirm" states="draft" type="workflow" icon="gtk-yes"/>
<button string="Approve" name="validate" states="confirm" type="workflow" icon="gtk-apply"/>
<button string="Refuse" name="refuse" states="confirm,validate,draft" type="workflow" icon="gtk-no"/>
- <button string="Reset to New" name="set_to_draft" states="cancel" type="object" icon="gtk-convert"/>
+ <button string="Reset to Draft" name="reset" states="confirm" type="workflow" groups="base.group_hr_manager"/>
<field name="state"/>
</header>
<group col="4">
@@ -351,8 +357,8 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" eval="view_holiday_simple"/>
- <field name="context">{'search_default_group_type': 1, 'search_default_validated': 1}</field>
- <field name="domain">[('holiday_type','=','employee')]</field>
+ <field name="context">{'search_default_group_type': 1}</field>
+ <field name="domain">[('holiday_type','=','employee'), ('state', '!=', 'refuse')]</field>
<field name="search_view_id" ref="view_hr_holidays_filter"/>
</record>
diff --git a/addons/hr_holidays/hr_holidays_workflow.xml b/addons/hr_holidays/hr_holidays_workflow.xml
index b729ea54a30..14cbc48138a 100644
--- a/addons/hr_holidays/hr_holidays_workflow.xml
+++ b/addons/hr_holidays/hr_holidays_workflow.xml
@@ -2,15 +2,16 @@
<openerp>
<data>
- <!-- Workflow definition
- 1. draft->submitted (no signal)
+ <!-- Workflow definition
+ 1. draft->submitted (confirm signal) if can_reset
+ 2. submitted->draft (reset signal) if can_reset
2. submitted->accepted (validate signal) if not double_validation
- 2. submitted -> first_accepted (validate signal) if double_validation
+ 2. submitted->first_accepted (validate signal) if double_validation
2. submitted->refused (refuse signal)
3. accepted->refused (refuse signal)
- 4. first_accepted -> accepted (second_validate signal)
+ 4. first_accepted -> accepted (second_validate signal)
4. first_accepted -> refused (refuse signal)
-
+ 5. refuse -> draft (reset signal) if can_reset
-->
<record model="workflow" id="wkf_holidays">
@@ -21,13 +22,15 @@
<record model="workflow.activity" id="act_draft"> <!-- draft -->
<field name="wkf_id" ref="wkf_holidays" />
- <field name="flow_start">True</field>
<field name="name">draft</field>
+ <field name="kind">function</field>
+ <field name="action">holidays_reset()</field>
</record>
<record model="workflow.activity" id="act_confirm"> <!-- submitted -->
<field name="wkf_id" ref="wkf_holidays" />
<field name="name">confirm</field>
+ <field name="flow_start">True</field>
<field name="kind">function</field>
<field name="action">holidays_confirm()</field>
<field name="split_mode">OR</field>
@@ -48,11 +51,9 @@
<field name="split_mode">OR</field>
</record>
-
<record model="workflow.activity" id="act_refuse"> <!-- refused -->
<field name="wkf_id" ref="wkf_holidays" />
<field name="name">refuse</field>
- <field name="flow_stop">True</field>
<field name="kind">function</field>
<field name="action">holidays_refuse()</field>
</record>
@@ -61,9 +62,20 @@
workflow transition
-->
- <record model="workflow.transition" id="holiday_draft2confirm"> <!-- 1. draft->submitted (no signal) -->
+ <record model="workflow.transition" id="holiday_draft2confirm"> <!-- 1. draft->submitted (confirm signal) -->
<field name="act_from" ref="act_draft" />
<field name="act_to" ref="act_confirm" />
+ <field name="signal">confirm</field>
+ <field name="condition">can_reset</field>
+ <field name="group_id" ref="base.group_user"/>
+ </record>
+
+ <record model="workflow.transition" id="holiday_confirm2draft"> <!-- 2. submitted->draft (reset signal) -->
+ <field name="act_from" ref="act_confirm" />
+ <field name="act_to" ref="act_draft" />
+ <field name="signal">reset</field>
+ <field name="condition">can_reset</field>
+ <field name="group_id" ref="base.group_user"/>
</record>
<record model="workflow.transition" id="holiday_confirm2validate"> <!-- 2. submitted->accepted (validate signal) if not double_validation-->
@@ -82,7 +94,6 @@
<field name="group_id" ref="base.group_hr_user"/>
</record>
-
<record model="workflow.transition" id="holiday_confirm2refuse"> <!-- 2. submitted->refused (refuse signal) -->
<field name="act_from" ref="act_confirm" />
<field name="act_to" ref="act_refuse" />
@@ -107,7 +118,6 @@
<field name="group_id" ref="base.group_hr_user"/>
</record>
-
<record model="workflow.transition" id="holiday_validate1_validate"> <!-- 4. first_accepted -> accepted (second_validate signal) -->
<field name="act_from" ref="act_validate1" />
<field name="act_to" ref="act_validate" />
@@ -124,5 +134,13 @@
<field name="group_id" ref="base.group_hr_user"/>
</record>
+ <record model="workflow.transition" id="holiday_refuse2draft"> <!-- 5. refused->draft (reset signal) -->
+ <field name="act_from" ref="act_refuse" />
+ <field name="act_to" ref="act_draft" />
+ <field name="signal">reset</field>
+ <field name="condition">can_reset</field>
+ <field name="group_id" ref="base.group_hr_manager"/>
+ </record>
+
</data>
</openerp>
diff --git a/addons/hr_holidays/security/ir.model.access.csv b/addons/hr_holidays/security/ir.model.access.csv
index 0375a17ac53..8a2594bb7d7 100644
--- a/addons/hr_holidays/security/ir.model.access.csv
+++ b/addons/hr_holidays/security/ir.model.access.csv
@@ -1,8 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_hr_holydays_status_user,hr.holidays.status user,model_hr_holidays_status,base.group_hr_user,1,1,1,1
access_hr_holidays_user,hr.holidays.user,model_hr_holidays,base.group_hr_user,1,1,1,1
access_hr_holidays_employee,hr.holidays.employee,model_hr_holidays,base.group_user,1,1,1,1
access_hr_holydays_status_employee,hr.holidays.status employee,model_hr_holidays_status,base.group_user,1,0,0,0
+access_hr_holydays_status_manager,hr.holidays.status manager,model_hr_holidays_status,base.group_hr_manager,1,1,1,1
access_hr_holidays_remain_user,hr.holidays.ramain.user,model_hr_holidays_remaining_leaves_user,base.group_hr_user,1,1,1,1
access_resource_calendar_leaves_user,resource_calendar_leaves_user,resource.model_resource_calendar_leaves,base.group_hr_user,1,1,1,1
+access_crm_meeting_hr_user,crm.meeting.hr.user,base_calendar.model_crm_meeting,base.group_hr_user,1,1,1,1
access_crm_meeting_type_manager,crm.meeting.type.manager,base_calendar.model_crm_meeting_type,base.group_hr_manager,1,1,1,1
diff --git a/addons/hr_holidays/test/test_hr_holiday.yml b/addons/hr_holidays/test/test_hr_holiday.yml
index 2bb60300cff..7bedd3302e8 100644
--- a/addons/hr_holidays/test/test_hr_holiday.yml
+++ b/addons/hr_holidays/test/test_hr_holiday.yml
@@ -18,7 +18,7 @@
I again set to draft and then confirm.
-
!python {model: hr.holidays}: |
- self.set_to_draft(cr, uid, [ref('hr_holidays_employee1_cl')])
+ self.holidays_reset(cr, uid, [ref('hr_holidays_employee1_cl')])
self.signal_confirm(cr, uid, [ref('hr_holidays_employee1_cl')])
-
I validate the holiday request by clicking on "To Approve" button.
diff --git a/addons/hr_holidays/tests/__init__.py b/addons/hr_holidays/tests/__init__.py
new file mode 100644
index 00000000000..f70a6277163
--- /dev/null
+++ b/addons/hr_holidays/tests/__init__.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.addons.hr_holidays.tests import test_holidays_flow
+
+checks = [
+ test_holidays_flow,
+]
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_holidays/tests/common.py b/addons/hr_holidays/tests/common.py
new file mode 100644
index 00000000000..2124a25ac39
--- /dev/null
+++ b/addons/hr_holidays/tests/common.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.tests import common
+
+
+class TestHrHolidaysBase(common.TransactionCase):
+
+ def setUp(self):
+ super(TestHrHolidaysBase, self).setUp()
+ cr, uid = self.cr, self.uid
+
+ # Usefull models
+ self.hr_employee = self.registry('hr.employee')
+ self.hr_holidays = self.registry('hr.holidays')
+ self.hr_holidays_status = self.registry('hr.holidays.status')
+ self.res_users = self.registry('res.users')
+ self.res_partner = self.registry('res.partner')
+
+ # Find Employee group
+ group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
+ self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
+
+ # Find Hr User group
+ group_hr_user_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_user')
+ self.group_hr_user_ref_id = group_hr_user_ref and group_hr_user_ref[1] or False
+
+ # Find Hr Manager group
+ group_hr_manager_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_manager')
+ self.group_hr_manager_ref_id = group_hr_manager_ref and group_hr_manager_ref[1] or False
+
+ # Test partners to use through the various tests
+ self.hr_partner_id = self.res_partner.create(cr, uid, {
+ 'name': 'Gertrude AgrolaitPartner',
+ 'email': 'gertrude.partner@agrolait.com',
+ })
+ self.email_partner_id = self.res_partner.create(cr, uid, {
+ 'name': 'Patrick Ratatouille',
+ 'email': 'patrick.ratatouille@agrolait.com',
+ })
+
+ # Test users to use through the various tests
+ self.user_hruser_id = self.res_users.create(cr, uid, {
+ 'name': 'Armande HrUser',
+ 'login': 'Armande',
+ 'alias_name': 'armande',
+ 'email': 'armande.hruser@example.com',
+ 'groups_id': [(6, 0, [self.group_employee_id, self.group_hr_user_ref_id])]
+ }, {'no_reset_password': True})
+ self.user_hrmanager_id = self.res_users.create(cr, uid, {
+ 'name': 'Bastien HrManager',
+ 'login': 'bastien',
+ 'alias_name': 'bastien',
+ 'email': 'bastien.hrmanager@example.com',
+ 'groups_id': [(6, 0, [self.group_employee_id, self.group_hr_manager_ref_id])]
+ }, {'no_reset_password': True})
+ self.user_none_id = self.res_users.create(cr, uid, {
+ 'name': 'Charlie Avotbonkeur',
+ 'login': 'charlie',
+ 'alias_name': 'charlie',
+ 'email': 'charlie.noone@example.com',
+ 'groups_id': [(6, 0, [])]
+ }, {'no_reset_password': True})
+ self.user_employee_id = self.res_users.create(cr, uid, {
+ 'name': 'David Employee',
+ 'login': 'david',
+ 'alias_name': 'david',
+ 'email': 'david.employee@example.com',
+ 'groups_id': [(6, 0, [self.group_employee_id])]
+ }, {'no_reset_password': True})
+
+ # Hr Data
+ self.employee_emp_id = self.hr_employee.create(cr, uid, {
+ 'name': 'David Employee',
+ 'user_id': self.user_employee_id,
+ })
+ self.employee_hruser_id = self.hr_employee.create(cr, uid, {
+ 'name': 'Armande HrUser',
+ 'user_id': self.user_hruser_id,
+ })
diff --git a/addons/hr_holidays/tests/test_holidays_flow.py b/addons/hr_holidays/tests/test_holidays_flow.py
new file mode 100644
index 00000000000..caa6e14f2db
--- /dev/null
+++ b/addons/hr_holidays/tests/test_holidays_flow.py
@@ -0,0 +1,207 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
+
+from openerp.addons.hr_holidays.tests.common import TestHrHolidaysBase
+from openerp.osv.orm import except_orm
+from openerp.tools import mute_logger
+
+
+class TestHolidaysFlow(TestHrHolidaysBase):
+
+ @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ def test_00_leave_request_flow(self):
+ """ Testing leave request flow """
+ cr, uid = self.cr, self.uid
+
+ def _check_holidays_status(holiday_status, ml, lt, rl, vrl):
+ self.assertEqual(holiday_status.max_leaves, ml,
+ 'hr_holidays: wrong type days computation')
+ self.assertEqual(holiday_status.leaves_taken, lt,
+ 'hr_holidays: wrong type days computation')
+ self.assertEqual(holiday_status.remaining_leaves, rl,
+ 'hr_holidays: wrong type days computation')
+ self.assertEqual(holiday_status.virtual_remaining_leaves, vrl,
+ 'hr_holidays: wrong type days computation')
+
+ # HrUser creates some holiday statuses -> crash because only HrManagers should do this
+ with self.assertRaises(except_orm):
+ self.holidays_status_dummy = self.hr_holidays_status.create(cr, self.user_hruser_id, {
+ 'name': 'UserCheats',
+ 'limit': True,
+ })
+
+ # HrManager creates some holiday statuses
+ self.holidays_status_0 = self.hr_holidays_status.create(cr, self.user_hrmanager_id, {
+ 'name': 'WithMeetingType',
+ 'limit': True,
+ 'categ_id': self.registry('crm.meeting.type').create(cr, self.user_hrmanager_id, {'name': 'NotLimitedMeetingType'}),
+ })
+ self.holidays_status_1 = self.hr_holidays_status.create(cr, self.user_hrmanager_id, {
+ 'name': 'NotLimited',
+ 'limit': True,
+ })
+ self.holidays_status_2 = self.hr_holidays_status.create(cr, self.user_hrmanager_id, {
+ 'name': 'Limited',
+ 'limit': False,
+ 'double_validation': True,
+ })
+
+ # --------------------------------------------------
+ # Case1: unlimited type of leave request
+ # --------------------------------------------------
+
+ # Employee creates a leave request for another employee -> should crash
+ with self.assertRaises(except_orm):
+ self.hr_holidays.create(cr, self.user_employee_id, {
+ 'name': 'Hol10',
+ 'employee_id': self.employee_hruser_id,
+ 'holiday_status_id': self.holidays_status_1,
+ 'date_from': (datetime.today() - relativedelta(days=1)),
+ 'date_to': datetime.today(),
+ 'number_of_days_temp': 1,
+ })
+
+ # Employee creates a leave request in a no-limit category
+ hol1_id = self.hr_holidays.create(cr, self.user_employee_id, {
+ 'name': 'Hol11',
+ 'employee_id': self.employee_emp_id,
+ 'holiday_status_id': self.holidays_status_1,
+ 'date_from': (datetime.today() - relativedelta(days=1)),
+ 'date_to': datetime.today(),
+ 'number_of_days_temp': 1,
+ })
+ hol1 = self.hr_holidays.browse(cr, self.user_hruser_id, hol1_id)
+ self.assertEqual(hol1.state, 'confirm', 'hr_holidays: newly created leave request should be in confirm state')
+
+ # Employee validates its leave request -> should not work
+ self.hr_holidays.signal_validate(cr, self.user_employee_id, [hol1_id])
+ hol1.refresh()
+ self.assertEqual(hol1.state, 'confirm', 'hr_holidays: employee should not be able to validate its own leave request')
+
+ # HrUser validates the employee leave request
+ self.hr_holidays.signal_validate(cr, self.user_hrmanager_id, [hol1_id])
+ hol1.refresh()
+ self.assertEqual(hol1.state, 'validate', 'hr_holidays: validates leave request should be in validate state')
+
+ # --------------------------------------------------
+ # Case2: limited type of leave request
+ # --------------------------------------------------
+
+ # Employee creates a new leave request at the same time -> crash, avoid interlapping
+ with self.assertRaises(except_orm):
+ self.hr_holidays.create(cr, self.user_employee_id, {
+ 'name': 'Hol21',
+ 'employee_id': self.employee_emp_id,
+ 'holiday_status_id': self.holidays_status_1,
+ 'date_from': (datetime.today() - relativedelta(days=1)).strftime('%Y-%m-%d %H:%M'),
+ 'date_to': datetime.today(),
+ 'number_of_days_temp': 1,
+ })
+
+ # Employee creates a leave request in a limited category -> crash, not enough days left
+ with self.assertRaises(except_orm):
+ self.hr_holidays.create(cr, self.user_employee_id, {
+ 'name': 'Hol22',
+ 'employee_id': self.employee_emp_id,
+ 'holiday_status_id': self.holidays_status_2,
+ 'date_from': (datetime.today() + relativedelta(days=0)).strftime('%Y-%m-%d %H:%M'),
+ 'date_to': (datetime.today() + relativedelta(days=1)),
+ 'number_of_days_temp': 1,
+ })
+
+ # Clean transaction
+ self.hr_holidays.unlink(cr, uid, self.hr_holidays.search(cr, uid, [('name', 'in', ['Hol21', 'Hol22'])]))
+
+ # HrUser allocates some leaves to the employee
+ aloc1_id = self.hr_holidays.create(cr, self.user_hruser_id, {
+ 'name': 'Days for limited category',
+ 'employee_id': self.employee_emp_id,
+ 'holiday_status_id': self.holidays_status_2,
+ 'type': 'add',
+ 'number_of_days_temp': 2,
+ })
+ # HrUser validates the allocation request
+ self.hr_holidays.signal_validate(cr, self.user_hruser_id, [aloc1_id])
+ self.hr_holidays.signal_second_validate(cr, self.user_hruser_id, [aloc1_id])
+ # Checks Employee has effectively some days left
+ hol_status_2 = self.hr_holidays_status.browse(cr, self.user_employee_id, self.holidays_status_2)
+ _check_holidays_status(hol_status_2, 2.0, 0.0, 2.0, 2.0)
+
+ # Employee creates a leave request in the limited category, now that he has some days left
+ hol2_id = self.hr_holidays.create(cr, self.user_employee_id, {
+ 'name': 'Hol22',
+ 'employee_id': self.employee_emp_id,
+ 'holiday_status_id': self.holidays_status_2,
+ 'date_from': (datetime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M'),
+ 'date_to': (datetime.today() + relativedelta(days=3)),
+ 'number_of_days_temp': 1,
+ })
+ hol2 = self.hr_holidays.browse(cr, self.user_hruser_id, hol2_id)
+ # Check left days: - 1 virtual remaining day
+ hol_status_2.refresh()
+ _check_holidays_status(hol_status_2, 2.0, 0.0, 2.0, 1.0)
+
+ # HrUser validates the first step
+ self.hr_holidays.signal_validate(cr, self.user_hruser_id, [hol2_id])
+ hol2.refresh()
+ self.assertEqual(hol2.state, 'validate1',
+ 'hr_holidays: first validation should lead to validate1 state')
+
+ # HrUser validates the second step
+ self.hr_holidays.signal_second_validate(cr, self.user_hruser_id, [hol2_id])
+ hol2.refresh()
+ self.assertEqual(hol2.state, 'validate',
+ 'hr_holidays: second validation should lead to validate state')
+ # Check left days: - 1 day taken
+ hol_status_2.refresh()
+ _check_holidays_status(hol_status_2, 2.0, 1.0, 1.0, 1.0)
+
+ # HrManager finds an error: he refuses the leave request
+ self.hr_holidays.signal_refuse(cr, self.user_hrmanager_id, [hol2_id])
+ hol2.refresh()
+ self.assertEqual(hol2.state, 'refuse',
+ 'hr_holidays: refuse should lead to refuse state')
+ # Check left days: 2 days left again
+ hol_status_2.refresh()
+ _check_holidays_status(hol_status_2, 2.0, 0.0, 2.0, 2.0)
+
+ # Annoyed, HrUser tries to fix its error and tries to reset the leave request -> does not work, only HrManager
+ self.hr_holidays.signal_reset(cr, self.user_hruser_id, [hol2_id])
+ self.assertEqual(hol2.state, 'refuse',
+ 'hr_holidays: hr_user should not be able to reset a refused leave request')
+
+ # HrManager resets the request
+ self.hr_holidays.signal_reset(cr, self.user_hrmanager_id, [hol2_id])
+ hol2.refresh()
+ self.assertEqual(hol2.state, 'draft',
+ 'hr_holidays: resetting should lead to draft state')
+
+ # HrManager changes the date and put too much days -> crash when confirming
+ self.hr_holidays.write(cr, self.user_hrmanager_id, [hol2_id], {
+ 'date_from': (datetime.today() + relativedelta(days=4)).strftime('%Y-%m-%d %H:%M'),
+ 'date_to': (datetime.today() + relativedelta(days=7)),
+ 'number_of_days_temp': 4,
+ })
+ with self.assertRaises(except_orm):
+ self.hr_holidays.signal_confirm(cr, self.user_hrmanager_id, [hol2_id])
diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py
index 8f072dd9082..1b9111d3040 100644
--- a/addons/mail/__openerp__.py
+++ b/addons/mail/__openerp__.py
@@ -83,7 +83,6 @@ Main Features
'static/src/css/mail_group.css',
],
'js': [
- 'static/lib/jquery.expander/jquery.expander.js',
'static/src/js/mail.js',
'static/src/js/mail_followers.js',
'static/src/js/many2many_tags_email.js',
diff --git a/addons/mail/doc/changelog.rst b/addons/mail/doc/changelog.rst
index f6674bb42ad..a7a2cfcf2b5 100644
--- a/addons/mail/doc/changelog.rst
+++ b/addons/mail/doc/changelog.rst
@@ -6,6 +6,12 @@ Changelog
`trunk (saas-2)`
----------------
+ - added support of ``active_domain`` form context, coming from the list view.
+ When checking the header hook, the mass mailing will be done on all records
+ matching the ``active_domain``.
+ - added ``mail_server_id`` to mail_message, removing it from mail_mail. This allows
+ to set the preferred mail server to use for notifications emails, when using
+ templates.
- added ``_mail_post_access`` attribute that specifies the access right that
should have the user in order to post a new message on a given model. Values
- are ``read`` (portal documents), ``write`` (default value), ``unlink`` or ``create``. \ No newline at end of file
+ are ``read`` (portal documents), ``write`` (default value), ``unlink`` or ``create``.
diff --git a/addons/mail/i18n/bs.po b/addons/mail/i18n/bs.po
new file mode 100644
index 00000000000..b50a043e2a7
--- /dev/null
+++ b/addons/mail/i18n/bs.po
@@ -0,0 +1,1687 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-08-06 10:21+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
+
+#. module: mail
+#: view:mail.followers:0
+msgid "Followers Form"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_publisher_warranty_contract
+msgid "publisher_warranty.contract"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,author_id:0
+#: view:mail.mail:0
+#: field:mail.message,author_id:0
+msgid "Author"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Message Details"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,email_to:0
+msgid "Message recipients"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,default:0
+msgid "Activated by default when subscribing."
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Comments"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: view:mail.mail:0
+msgid "Group By..."
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,body:0
+#: help:mail.message,body:0
+msgid "Automatically sanitized HTML contents"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_name:0
+msgid ""
+"The name of the email alias, e.g. 'jobs' if you want to catch emails for "
+"<jobs@example.my.openerp.com>"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard
+#: view:mail.compose.message:0
+msgid "Compose Email"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:132
+#, python-format
+msgid "Add them into recipients and followers"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Group Name"
+msgstr ""
+
+#. module: mail
+#: selection:mail.group,public:0
+msgid "Public"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Body"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Show messages to read"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,email_from:0
+#: help:mail.message,email_from:0
+msgid ""
+"Email address of the sender. This field is set when no matching partner is "
+"found for incoming emails."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_compose_message
+msgid "Email composition wizard"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:23
+#, python-format
+msgid "Add others"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,parent_id:0
+msgid "Parent"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,message_unread:0
+#: field:mail.thread,message_unread:0
+#: field:res.partner,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:313
+#, python-format
+msgid "show"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,group_ids:0
+msgid ""
+"Members of those groups will automatically added as followers. Note that "
+"they will be able to manage their subscription manually if necessary."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail.js:1029
+#, python-format
+msgid "Do you really want to delete this message?"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+#: field:mail.notification,read:0
+msgid "Read"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Search Groups"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail_followers.js:157
+#, python-format
+msgid "followers"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:737
+#, python-format
+msgid "Access Denied"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,image_medium:0
+msgid ""
+"Medium-sized photo of the group. It is automatically resized as a 128x128px "
+"image, with aspect ratio preserved. Use this field in form views or some "
+"kanban views."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:212
+#, python-format
+msgid "Uploading error"
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_support
+msgid "Support"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:738
+#, python-format
+msgid ""
+"The requested operation cannot be completed due to security restrictions. "
+"Please contact your system administrator.\n"
+"\n"
+"(Document type: %s, Operation: %s)"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: selection:mail.mail,state:0
+msgid "Received"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Thread"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:29
+#, python-format
+msgid "Open the full mail composer"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:29
+#, python-format
+msgid "&ograve"
+msgstr ""
+
+#. module: mail
+#: field:base.config.settings,alias_domain:0
+msgid "Alias Domain"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,group_ids:0
+msgid "Auto Subscription"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,references:0
+msgid "References"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:206
+#, python-format
+msgid "No messages."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_group
+msgid "Discussion group"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:96
+#: code:addons/mail/static/src/xml/mail.xml:108
+#, python-format
+msgid "uploading"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:52
+#, python-format
+msgid "more."
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,type:0
+#: help:mail.message,type:0
+msgid ""
+"Message type: email for email message, notification for system message, "
+"comment for other messages such as user replies"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,relation_field:0
+msgid ""
+"Field used to link the related model to the subtype model when using "
+"automatic subscription on a related document. The field is used to compute "
+"getattr(related_document.relation_field)."
+msgstr ""
+
+#. module: mail
+#: selection:mail.mail,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,reply_to:0
+msgid "Reply-To"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/wizard/invite.py:37
+#, python-format
+msgid "<div>You have been invited to follow %s.</div>"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,message_unread:0
+#: help:mail.thread,message_unread:0
+#: help:res.partner,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: mail
+#: field:mail.group,image_medium:0
+msgid "Medium-sized photo"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_to_me_feeds
+#: model:ir.ui.menu,name:mail.mail_tomefeeds
+msgid "To: me"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,name:0
+msgid "Message Type"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,auto_delete:0
+msgid "Auto Delete"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:12
+#: view:mail.group:0
+#, python-format
+msgid "Unfollow"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:312
+#, python-format
+msgid "show one more message"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_mail.py:75
+#: code:addons/mail/res_users.py:69
+#, python-format
+msgid "Invalid Action!"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:25
+#, python-format
+msgid "User img"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_mail_mail
+#: model:ir.ui.menu,name:mail.menu_mail_mail
+#: view:mail.mail:0
+#: view:mail.message:0
+msgid "Emails"
+msgstr ""
+
+#. module: mail
+#: field:mail.followers,partner_id:0
+msgid "Related Partner"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,message_summary:0
+#: help:mail.thread,message_summary:0
+#: help:res.partner,message_summary:0
+msgid ""
+"Holds the Chatter summary (number of messages, ...). This summary is "
+"directly in html format in order to be inserted in kanban views."
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_model_id:0
+msgid ""
+"The model (OpenERP Document Kind) to which this alias corresponds. Any "
+"incoming email that does not reply to an existing record will cause the "
+"creation of a new record of this model (e.g. a Project Task)"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,relation_field:0
+msgid "Relation field"
+msgstr ""
+
+#. module: mail
+#: selection:mail.compose.message,type:0
+#: selection:mail.message,type:0
+msgid "System notification"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: mail
+#: model:ir.ui.menu,name:mail.mail_my_stuff
+msgid "Organizer"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,subject:0
+#: field:mail.message,subject:0
+msgid "Subject"
+msgstr ""
+
+#. module: mail
+#: field:mail.wizard.invite,partner_ids:0
+msgid "Partners"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Retry"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,email_from:0
+#: field:mail.mail,email_from:0
+#: field:mail.message,email_from:0
+msgid "From"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: view:mail.message.subtype:0
+msgid "Email message"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_base_config_settings
+msgid "base.config.settings"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:36
+#: view:mail.compose.message:0
+#, python-format
+msgid "Send"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail_followers.js:153
+#, python-format
+msgid "No followers"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Failed"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:22
+#: model:ir.actions.act_window,name:mail.action_view_followers
+#: model:ir.ui.menu,name:mail.menu_email_followers
+#: view:mail.followers:0
+#: field:mail.group,message_follower_ids:0
+#: field:mail.thread,message_follower_ids:0
+#: field:res.partner,message_follower_ids:0
+#, python-format
+msgid "Followers"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_archives_feeds
+#: model:ir.ui.menu,name:mail.mail_archivesfeeds
+msgid "Archives"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:95
+#: code:addons/mail/static/src/xml/mail.xml:107
+#, python-format
+msgid "Delete this attachment"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:245
+#: view:mail.mail:0
+#, python-format
+msgid "Reply"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail_followers.js:155
+#, python-format
+msgid "One follower"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,type:0
+#: field:mail.message,type:0
+msgid "Type"
+msgstr ""
+
+#. module: mail
+#: selection:mail.compose.message,type:0
+#: view:mail.mail:0
+#: selection:mail.message,type:0
+msgid "Email"
+msgstr ""
+
+#. module: mail
+#: field:ir.ui.menu,mail_group_id:0
+msgid "Mail Group"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "Comments and Emails"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_defaults:0
+msgid "Default Values"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/res_users.py:89
+#, python-format
+msgid "%s has joined the %s network."
+msgstr ""
+
+#. module: mail
+#: help:mail.group,image_small:0
+msgid ""
+"Small-sized photo of the group. It is automatically resized as a 64x64px "
+"image, with aspect ratio preserved. Use this field anywhere a small image is "
+"required."
+msgstr ""
+
+#. module: mail
+#: view:mail.compose.message:0
+#: field:mail.message,partner_ids:0
+msgid "Recipients"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:140
+#, python-format
+msgid "<<<"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:43
+#, python-format
+msgid "Write to the followers of this document..."
+msgstr ""
+
+#. module: mail
+#: field:mail.group,group_public_id:0
+msgid "Authorized Group"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Join Group"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,email_from:0
+msgid "Message sender, taken from user preferences."
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/wizard/invite.py:40
+#, python-format
+msgid "<div>You have been invited to follow a new document.</div>"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,parent_id:0
+#: field:mail.message,parent_id:0
+msgid "Parent Message"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,res_id:0
+#: field:mail.followers,res_id:0
+#: field:mail.message,res_id:0
+#: field:mail.wizard.invite,res_id:0
+msgid "Related Document ID"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_to_me_feeds
+msgid ""
+"<p>\n"
+" <b>No private message.</b>\n"
+" </p><p>\n"
+" This list contains messages sent to you.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_rd
+msgid "R&D"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:61
+#, python-format
+msgid "/web/binary/upload_attachment"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_thread
+msgid "Email Thread"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Advanced"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:244
+#, python-format
+msgid "Move to Inbox"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/wizard/mail_compose_message.py:193
+#, python-format
+msgid "Re:"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,to_read:0
+#: field:mail.message,to_read:0
+msgid "To read"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/res_users.py:69
+#, python-format
+msgid ""
+"You may not create a user. To create new users, you should use the "
+"\"Settings > Users\" menu."
+msgstr ""
+
+#. module: mail
+#: help:mail.followers,res_model:0
+#: help:mail.wizard.invite,res_model:0
+msgid "Model of the followed resource"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:337
+#, python-format
+msgid "like"
+msgstr ""
+
+#. module: mail
+#: view:mail.compose.message:0
+#: view:mail.wizard.invite:0
+msgid "Cancel"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:47
+#, python-format
+msgid "Share with my followers..."
+msgstr ""
+
+#. module: mail
+#: field:mail.notification,partner_id:0
+msgid "Contact"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid ""
+"Only the invited followers can read the\n"
+" discussions on this group."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_ir_ui_menu
+msgid "ir.ui.menu"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Has attachments"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "on"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:926
+#, python-format
+msgid ""
+"The following partners chosen as recipients for the email have no email "
+"address linked :"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_defaults:0
+msgid ""
+"A Python dictionary that will be evaluated to provide default values when "
+"creating new records for this alias."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_message_subtype
+msgid "Message subtypes"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,notified_partner_ids:0
+#: help:mail.message,notified_partner_ids:0
+msgid ""
+"Partners that have a notification pushing this message in their mailboxes"
+msgstr ""
+
+#. module: mail
+#: selection:mail.compose.message,type:0
+#: view:mail.mail:0
+#: selection:mail.message,type:0
+msgid "Comment"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_inbox_feeds
+msgid ""
+"<p>\n"
+" <b>Good Job!</b> Your inbox is empty.\n"
+" </p><p>\n"
+" Your inbox contains private messages or emails sent to "
+"you\n"
+" as well as information related to documents or people "
+"you\n"
+" follow.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,notification:0
+msgid "Is Notification"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:188
+#, python-format
+msgid "Compose a new message"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Send Now"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_mail.py:75
+#, python-format
+msgid ""
+"Unable to send email, please configure the sender's email address or alias."
+msgstr ""
+
+#. module: mail
+#: help:res.users,alias_id:0
+msgid ""
+"Email address internally associated with this user. Incoming emails will "
+"appear in the user's notifications."
+msgstr ""
+
+#. module: mail
+#: field:mail.group,image:0
+msgid "Photo"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:54
+#: code:addons/mail/static/src/xml/mail.xml:191
+#: view:mail.compose.message:0
+#: view:mail.wizard.invite:0
+#, python-format
+msgid "or"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,vote_user_ids:0
+#: help:mail.message,vote_user_ids:0
+msgid "Users that voted for this message"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,alias_id:0
+msgid ""
+"The email address associated with this group. New emails received will "
+"automatically create new topics."
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Month"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Email Search"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,child_ids:0
+#: field:mail.message,child_ids:0
+msgid "Child Messages"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_user_id:0
+msgid "Owner"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_message
+#: field:mail.mail,mail_message_id:0
+#: view:mail.message:0
+#: field:mail.notification,message_id:0
+#: field:mail.wizard.invite,message:0
+msgid "Message"
+msgstr ""
+
+#. module: mail
+#: help:mail.followers,res_id:0
+#: help:mail.wizard.invite,res_id:0
+msgid "Id of the followed resource"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,body:0
+#: field:mail.message,body:0
+msgid "Contents"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_mail_alias
+#: model:ir.ui.menu,name:mail.mail_alias_menu
+msgid "Aliases"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,description:0
+msgid ""
+"Description that will be added in the message posted for this subtype. If "
+"void, the name will be added instead."
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,vote_user_ids:0
+#: field:mail.message,vote_user_ids:0
+msgid "Votes"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Group"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,starred:0
+#: help:mail.message,starred:0
+msgid "Current user has a starred notification linked to this message"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,public:0
+msgid "Privacy"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Notification"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/mail.js:654
+#, python-format
+msgid "Please complete partner's informations"
+msgstr ""
+
+#. module: mail
+#: view:mail.wizard.invite:0
+msgid "Add Followers"
+msgstr ""
+
+#. module: mail
+#: view:mail.compose.message:0
+msgid "Followers of selected items and"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_force_thread_id:0
+msgid "Record Thread ID"
+msgstr ""
+
+#. module: mail
+#: model:ir.ui.menu,name:mail.mail_group_root
+msgid "My Groups"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_archives_feeds
+msgid ""
+"<p>\n"
+" No message found and no message sent yet.\n"
+" </p><p>\n"
+" Click on the top-right icon to compose a message. This\n"
+" message will be sent by email if it's an internal "
+"contact.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: field:mail.mail,state:0
+msgid "Status"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: selection:mail.mail,state:0
+msgid "Outgoing"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "All feeds"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,record_name:0
+#: help:mail.message,record_name:0
+msgid "Name get of the related document."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_notifications
+#: model:ir.model,name:mail.model_mail_notification
+#: model:ir.ui.menu,name:mail.menu_email_notifications
+#: field:mail.compose.message,notification_ids:0
+#: view:mail.message:0
+#: field:mail.message,notification_ids:0
+#: view:mail.notification:0
+msgid "Notifications"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+msgid "Search Alias"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_force_thread_id:0
+msgid ""
+"Optional ID of a thread (record) to which all incoming messages will be "
+"attached, even if they did not reply to it. If set, this will disable the "
+"creation of new records completely."
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,name:0
+msgid ""
+"Message subtype gives a more precise type on the message, especially for "
+"system notifications. For example, it can be a notification related to a new "
+"record (New), or to a stage change in a process (Stage change). Message "
+"subtypes allow to precisely tune the notifications the user want to receive "
+"on its wall."
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "by"
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_best_sales_practices
+msgid "Best Sales Practices"
+msgstr ""
+
+#. module: mail
+#: selection:mail.group,public:0
+msgid "Selected Group Only"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,message_is_follower:0
+#: field:mail.thread,message_is_follower:0
+#: field:res.partner,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: view:mail.mail:0
+msgid "User"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Groups"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Messages Search"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,date:0
+#: field:mail.message,date:0
+msgid "Date"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:34
+#, python-format
+msgid "Post"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Extended Filters..."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:120
+#, python-format
+msgid "To:"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:193
+#, python-format
+msgid "Write to my followers"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_res_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: mail
+#: field:mail.message.subtype,default:0
+msgid "Default"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:311
+#, python-format
+msgid "show more message"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:246
+#, python-format
+msgid "Mark as Todo"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,parent_id:0
+msgid "Parent subtype, used for automatic subscription."
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_wizard_invite
+msgid "Invite wizard"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,message_summary:0
+#: field:mail.thread,message_summary:0
+#: field:res.partner,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: mail
+#: help:mail.message.subtype,res_model:0
+msgid ""
+"Model the subtype applies to. If False, this subtype applies to all models."
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,subtype_id:0
+#: field:mail.followers,subtype_ids:0
+#: field:mail.message,subtype_id:0
+#: view:mail.message.subtype:0
+msgid "Subtype"
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid "Group Form"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,starred:0
+#: field:mail.message,starred:0
+#: field:mail.notification,starred:0
+msgid "Starred"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:313
+#, python-format
+msgid "more messages"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/update.py:93
+#, python-format
+msgid "Error"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:13
+#, python-format
+msgid "Following"
+msgstr ""
+
+#. module: mail
+#: sql_constraint:mail.alias:0
+msgid ""
+"Unfortunately this email alias is already used, please choose a unique one"
+msgstr ""
+
+#. module: mail
+#: help:mail.alias,alias_user_id:0
+msgid ""
+"The owner of records created upon receiving emails on this alias. If this "
+"field is not set the system will attempt to find the right owner based on "
+"the sender (From) address, or will use the Administrator account if no "
+"system user is found for that address."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:52
+#, python-format
+msgid "And"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,message_id:0
+#: field:mail.message,message_id:0
+msgid "Message-Id"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,image:0
+msgid ""
+"This field holds the image used as photo for the group, limited to "
+"1024x1024px."
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,attachment_ids:0
+#: view:mail.mail:0
+#: field:mail.message,attachment_ids:0
+msgid "Attachments"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,record_name:0
+#: field:mail.message,record_name:0
+msgid "Message Record Name"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,email_cc:0
+msgid "Cc"
+msgstr ""
+
+#. module: mail
+#: help:mail.notification,starred:0
+msgid "Starred message that goes into the todo mailbox"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:123
+#: view:mail.compose.message:0
+#, python-format
+msgid "Followers of"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,auto_delete:0
+msgid "Permanently delete this email after sending it, to save space"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_group_feeds
+msgid "Discussion Group"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:242
+#, python-format
+msgid "Done"
+msgstr ""
+
+#. module: mail
+#: model:mail.message.subtype,name:mail.mt_comment
+msgid "Discussions"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:11
+#, python-format
+msgid "Follow"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,name:0
+msgid "Name"
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_all_employees
+msgid "Whole Company"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:129
+#: code:addons/mail/static/src/xml/mail.xml:292
+#: view:mail.compose.message:0
+#, python-format
+msgid "and"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,body_html:0
+msgid "Rich-text/HTML message"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+msgid "Creation Month"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:323
+#, python-format
+msgid "Compose new Message"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,menu_id:0
+msgid "Related Menu"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Content"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,email_to:0
+msgid "To"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,notified_partner_ids:0
+#: field:mail.message,notified_partner_ids:0
+msgid "Notified partners"
+msgstr ""
+
+#. module: mail
+#: help:mail.group,public:0
+msgid ""
+"This group is visible by non members. Invisible groups can add "
+"members through the invite button."
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_board
+msgid "Board meetings"
+msgstr ""
+
+#. module: mail
+#: constraint:mail.alias:0
+msgid ""
+"Invalid expression, it must be a literal python dictionary definition e.g. "
+"\"{'field': 'value'}\""
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_model_id:0
+msgid "Aliased Model"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,message_id:0
+#: help:mail.message,message_id:0
+msgid "Message unique identifier"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,description:0
+#: field:mail.message.subtype,description:0
+msgid "Description"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_followers
+msgid "Document Followers"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail_followers.xml:35
+#, python-format
+msgid "Remove this follower"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "Never"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,mail_server_id:0
+msgid "Outgoing mail server"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/mail_message.py:930
+#, python-format
+msgid "Partners email addresses not found"
+msgstr ""
+
+#. module: mail
+#: view:mail.mail:0
+#: selection:mail.mail,state:0
+msgid "Sent"
+msgstr ""
+
+#. module: mail
+#: field:mail.mail,body_html:0
+msgid "Rich-text Contents"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,to_read:0
+#: help:mail.message,to_read:0
+msgid "Current user has an unread notification linked to this message"
+msgstr ""
+
+#. module: mail
+#: help:res.partner,notification_email_send:0
+msgid ""
+"Choose in which case you want to receive an email when you receive new feeds."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_groups
+#: model:ir.ui.menu,name:mail.mail_allgroups
+msgid "Join a group"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_group_feeds
+msgid ""
+"<p>\n"
+" No message in this group.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:213
+#, python-format
+msgid "Please, wait while the file is uploading."
+msgstr ""
+
+#. module: mail
+#: view:mail.group:0
+msgid ""
+"This group is visible by everyone,\n"
+" including your customers if you "
+"installed\n"
+" the portal module."
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:243
+#, python-format
+msgid "Set back to Todo"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:126
+#, python-format
+msgid "this document"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,filter_id:0
+msgid "Filters"
+msgstr ""
+
+#. module: mail
+#: field:res.partner,notification_email_send:0
+msgid "Receive Feeds by Email"
+msgstr ""
+
+#. module: mail
+#: help:base.config.settings,alias_domain:0
+msgid ""
+"If you have setup a catch-all email domain redirected to the OpenERP server, "
+"enter the domain name here."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_mail_message
+#: model:ir.ui.menu,name:mail.menu_mail_message
+#: field:mail.group,message_ids:0
+#: view:mail.message:0
+#: field:mail.thread,message_ids:0
+#: field:res.partner,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:139
+#, python-format
+msgid "others..."
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_star_feeds
+#: model:ir.ui.menu,name:mail.mail_starfeeds
+msgid "To-do"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: field:mail.alias,alias_name:0
+#: field:mail.group,alias_id:0
+#: field:res.users,alias_id:0
+msgid "Alias"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_mail
+msgid "Outgoing Mails"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,notification_ids:0
+#: help:mail.message,notification_ids:0
+msgid ""
+"Technical field holding the message notifications. Use notified_partner_ids "
+"to access notified partners."
+msgstr ""
+
+#. module: mail
+#: model:ir.ui.menu,name:mail.mail_feeds
+#: model:ir.ui.menu,name:mail.mail_feeds_main
+msgid "Messaging"
+msgstr ""
+
+#. module: mail
+#: view:mail.alias:0
+#: field:mail.message.subtype,res_model:0
+msgid "Model"
+msgstr ""
+
+#. module: mail
+#: view:mail.message:0
+msgid "Unread"
+msgstr ""
+
+#. module: mail
+#: help:mail.followers,subtype_ids:0
+msgid ""
+"Message subtypes followed, meaning subtypes that will be pushed onto the "
+"user's Wall."
+msgstr ""
+
+#. module: mail
+#: help:mail.group,message_ids:0
+#: help:mail.thread,message_ids:0
+#: help:res.partner,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,references:0
+msgid "Message references, such as identifiers of previous messages"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,composition_mode:0
+msgid "Composition mode"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,model:0
+#: field:mail.followers,res_model:0
+#: field:mail.message,model:0
+#: field:mail.wizard.invite,res_model:0
+msgid "Related Document Model"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:338
+#, python-format
+msgid "unlike"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,author_id:0
+#: help:mail.message,author_id:0
+msgid ""
+"Author of the message. If not set, email_from may hold an email address that "
+"did not match any partner."
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,email_cc:0
+msgid "Carbon copy message recipients"
+msgstr ""
+
+#. module: mail
+#: field:mail.alias,alias_domain:0
+msgid "Alias domain"
+msgstr ""
+
+#. module: mail
+#: code:addons/mail/update.py:93
+#, python-format
+msgid "Error during communication with the publisher warranty server."
+msgstr ""
+
+#. module: mail
+#: selection:mail.group,public:0
+msgid "Private"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,help:mail.action_mail_star_feeds
+msgid ""
+"<p>\n"
+" <b>No todo.</b>\n"
+" </p><p>\n"
+" When you process messages in your inbox, you can mark "
+"some\n"
+" as <i>todo</i>. From this menu, you can process all your "
+"todo.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: mail
+#: selection:mail.mail,state:0
+msgid "Delivery Failed"
+msgstr ""
+
+#. module: mail
+#: field:mail.compose.message,partner_ids:0
+msgid "Additional contacts"
+msgstr ""
+
+#. module: mail
+#: help:mail.compose.message,parent_id:0
+#: help:mail.message,parent_id:0
+msgid "Initial thread message."
+msgstr ""
+
+#. module: mail
+#: model:mail.group,name:mail.group_hr_policies
+msgid "HR Policies"
+msgstr ""
+
+#. module: mail
+#: selection:res.partner,notification_email_send:0
+msgid "Emails only"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.client,name:mail.action_mail_inbox_feeds
+#: model:ir.ui.menu,name:mail.mail_inboxfeeds
+msgid "Inbox"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/xml/mail.xml:58
+#, python-format
+msgid "File"
+msgstr ""
+
+#. module: mail
+#. openerp-web
+#: code:addons/mail/static/src/js/many2many_tags_email.js:63
+#, python-format
+msgid "Please complete partner's informations and Email"
+msgstr ""
+
+#. module: mail
+#: model:ir.actions.act_window,name:mail.action_view_message_subtype
+#: model:ir.ui.menu,name:mail.menu_message_subtype
+msgid "Subtypes"
+msgstr ""
+
+#. module: mail
+#: model:ir.model,name:mail.model_mail_alias
+msgid "Email Aliases"
+msgstr ""
+
+#. module: mail
+#: field:mail.group,image_small:0
+msgid "Small-sized photo"
+msgstr ""
+
+#. module: mail
+#: help:mail.mail,reply_to:0
+msgid "Preferred response address for the message"
+msgstr ""
diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py
index 9d96a6ff59c..ac350810aa6 100644
--- a/addons/mail/mail_followers.py
+++ b/addons/mail/mail_followers.py
@@ -151,7 +151,7 @@ class mail_notification(osv.Model):
return footer
def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None,
- force_send=False, user_signature=True):
+ force_send=False, user_signature=True):
""" Send by email the notification depending on the user preferences
:param list partners_to_notify: optional list of partner ids restricting
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
index d45ae04ddd1..b105d6677bd 100644
--- a/addons/mail/mail_mail.py
+++ b/addons/mail/mail_mail.py
@@ -44,7 +44,6 @@ class mail_mail(osv.Model):
_columns = {
'mail_message_id': fields.many2one('mail.message', 'Message', required=True, ondelete='cascade'),
- 'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
'state': fields.selection([
('outgoing', 'Outgoing'),
('sent', 'Sent'),
@@ -140,10 +139,16 @@ class mail_mail(osv.Model):
# notification field: if not set, set if mail comes from an existing mail.message
if 'notification' not in values and values.get('mail_message_id'):
values['notification'] = True
+ mail_id = super(mail_mail, self).create(cr, uid, values, context=context)
+
# reply_to: if not set, set with default values that require creation values
+ # but delegate after creation because of mail_message.message_id automatic
+ # creation using existence of reply_to
if not values.get('reply_to'):
- values['reply_to'] = self._get_reply_to(cr, uid, values, context=context)
- return super(mail_mail, self).create(cr, uid, values, context=context)
+ reply_to = self._get_reply_to(cr, uid, values, context=context)
+ if reply_to:
+ self.write(cr, uid, [mail_id], {'reply_to': reply_to}, context=context)
+ return mail_id
def unlink(self, cr, uid, ids, context=None):
# cascade-delete the parent message for all mails that are not created for a notification
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index 9d6829f3f6e..f90baa5a320 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -191,6 +191,7 @@ class mail_message(osv.Model):
'vote_user_ids': fields.many2many('res.users', 'mail_vote',
'message_id', 'user_id', string='Votes',
help='Users that voted for this message'),
+ 'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
}
def _needaction_domain_get(self, cr, uid, context=None):
@@ -394,15 +395,21 @@ class mail_message(osv.Model):
has_voted = uid in [user.id for user in message.vote_user_ids]
try:
- body_html = html_email_clean(message.body)
+ if parent_id:
+ max_length = 300
+ else:
+ max_length = 100
+ body_short = html_email_clean(message.body, remove=False, shorten=True, max_length=max_length)
+
except Exception:
- body_html = '<p><b>Encoding Error : </b><br/>Unable to convert this message (id: %s).</p>' % message.id
+ body_short = '<p><b>Encoding Error : </b><br/>Unable to convert this message (id: %s).</p>' % message.id
_logger.exception(Exception)
return {'id': message.id,
'type': message.type,
'subtype': message.subtype_id.name if message.subtype_id else False,
- 'body': body_html,
+ 'body': message.body,
+ 'body_short': body_short,
'model': message.model,
'res_id': message.res_id,
'record_name': message.record_name,
@@ -780,8 +787,8 @@ class mail_message(osv.Model):
values['message_id'] = tools.generate_tracking_message_id('private')
newid = super(mail_message, self).create(cr, uid, values, context)
self._notify(cr, uid, newid, context=context,
- force_send=context.get('mail_notify_force_send', True),
- user_signature=context.get('mail_notify_user_signature', True))
+ force_send=context.get('mail_notify_force_send', True),
+ user_signature=context.get('mail_notify_user_signature', True))
# TDE FIXME: handle default_starred. Why not setting an inv on starred ?
# Because starred will call set_message_starred, that looks for notifications.
# When creating a new mail_message, it will create a notification to a message
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 306e5fd5905..94e9126f020 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -682,6 +682,12 @@ class mail_thread(osv.AbstractModel):
assert thread_id == 0, 'Routing: posting a message without model should be with a null res_id (private message).'
_warn('posting a message without model should be with a null res_id (private message), resetting thread_id')
thread_id = 0
+ # Private message: should have a parent_id (only answers)
+ if not model and not message_dict.get('parent_id'):
+ if assert_model:
+ assert message_dict.get('parent_id'), 'Routing: posting a message without model should be with a parent_id (private mesage).'
+ _warn('posting a message without model should be with a parent_id (private mesage), skipping')
+ return ()
# Existing Document: check if exists; if not, fallback on create if allowed
if thread_id and not model_pool.exists(cr, uid, thread_id):
@@ -695,7 +701,7 @@ class mail_thread(osv.AbstractModel):
return ()
# Existing Document: check model accepts the mailgateway
- if thread_id and not hasattr(model_pool, 'message_update'):
+ if thread_id and model and not hasattr(model_pool, 'message_update'):
if create_fallback:
_warn('model %s does not accept document update, fall back on document creation' % model)
thread_id = None
@@ -706,7 +712,7 @@ class mail_thread(osv.AbstractModel):
return ()
# New Document: check model accepts the mailgateway
- if not thread_id and not hasattr(model_pool, 'message_new'):
+ if not thread_id and model and not hasattr(model_pool, 'message_new'):
if assert_model:
assert hasattr(model_pool, 'message_new'), 'Model %s does not accept document creation, crashing' % model
_warn('model %s does not accept document creation, skipping' % model)
@@ -798,16 +804,16 @@ class mail_thread(osv.AbstractModel):
# 2. Reply to a private message
if in_reply_to:
- message_ids = self.pool.get('mail.message').search(cr, uid, [
+ mail_message_ids = self.pool.get('mail.message').search(cr, uid, [
('message_id', '=', in_reply_to),
'!', ('message_id', 'ilike', 'reply_to')
], limit=1, context=context)
- if message_ids:
- message = self.pool.get('mail.message').browse(cr, uid, message_ids[0], context=context)
+ if mail_message_ids:
+ mail_message = self.pool.get('mail.message').browse(cr, uid, mail_message_ids[0], context=context)
_logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s',
- email_from, email_to, message_id, message.id, custom_values, uid)
+ email_from, email_to, message_id, mail_message.id, custom_values, uid)
route = self.message_route_verify(cr, uid, message, message_dict,
- (message.model, message.res_id, custom_values, uid, None),
+ (mail_message.model, mail_message.res_id, custom_values, uid, None),
update_author=True, assert_model=True, create_fallback=True, context=context)
return route and [route] or []
diff --git a/addons/mail/static/lib/jquery.expander/jquery.expander.js b/addons/mail/static/lib/jquery.expander/jquery.expander.js
deleted file mode 100644
index 91cc03db918..00000000000
--- a/addons/mail/static/lib/jquery.expander/jquery.expander.js
+++ /dev/null
@@ -1,385 +0,0 @@
-/*!
- * jQuery Expander Plugin v1.4.2
- *
- * Date: Fri Mar 16 14:29:56 2012 EDT
- * Requires: jQuery v1.3+
- *
- * Copyright 2011, Karl Swedberg
- * Dual licensed under the MIT and GPL licenses (just like jQuery):
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- *
- *
- *
-*/
-
-(function($) {
- $.expander = {
- version: '1.4.2',
- defaults: {
- // the number of characters at which the contents will be sliced into two parts.
- slicePoint: 100,
-
- // whether to keep the last word of the summary whole (true) or let it slice in the middle of a word (false)
- preserveWords: true,
-
- // a threshold of sorts for whether to initially hide/collapse part of the element's contents.
- // If after slicing the contents in two there are fewer words in the second part than
- // the value set by widow, we won't bother hiding/collapsing anything.
- widow: 4,
-
- // text displayed in a link instead of the hidden part of the element.
- // clicking this will expand/show the hidden/collapsed text
- expandText: 'read more',
- expandPrefix: '&hellip; ',
-
- expandAfterSummary: false,
-
- // class names for summary element and detail element
- summaryClass: 'summary',
- detailClass: 'details',
-
- // class names for <span> around "read-more" link and "read-less" link
- moreClass: 'read-more',
- lessClass: 'read-less',
-
- // number of milliseconds after text has been expanded at which to collapse the text again.
- // when 0, no auto-collapsing
- collapseTimer: 0,
-
- // effects for expanding and collapsing
- expandEffect: 'fadeIn',
- expandSpeed: 250,
- collapseEffect: 'fadeOut',
- collapseSpeed: 200,
-
- // allow the user to re-collapse the expanded text.
- userCollapse: true,
-
- // text to use for the link to re-collapse the text
- userCollapseText: 'read less',
- userCollapsePrefix: ' ',
-
-
- // all callback functions have the this keyword mapped to the element in the jQuery set when .expander() is called
-
- onSlice: null, // function() {}
- beforeExpand: null, // function() {},
- afterExpand: null, // function() {},
- onCollapse: null // function(byUser) {}
- }
- };
-
- $.fn.expander = function(options) {
- var meth = 'init';
-
- if (typeof options == 'string') {
- meth = options;
- options = {};
- }
-
- var opts = $.extend({}, $.expander.defaults, options),
- rSelfClose = /^<(?:area|br|col|embed|hr|img|input|link|meta|param).*>$/i,
- rAmpWordEnd = opts.wordEnd || /(&(?:[^;]+;)?|[a-zA-Z\u00C0-\u0100]+)$/,
- rOpenCloseTag = /<\/?(\w+)[^>]*>/g,
- rOpenTag = /<(\w+)[^>]*>/g,
- rCloseTag = /<\/(\w+)>/g,
- rLastCloseTag = /(<\/[^>]+>)\s*$/,
- rTagPlus = /^<[^>]+>.?/,
- delayedCollapse;
-
- var methods = {
- init: function() {
- this.each(function() {
- var i, l, tmp, newChar, summTagless, summOpens, summCloses,
- lastCloseTag, detailText, detailTagless,
- $thisDetails, $readMore,
- openTagsForDetails = [],
- closeTagsForsummaryText = [],
- defined = {},
- thisEl = this,
- $this = $(this),
- $summEl = $([]),
- o = $.meta ? $.extend({}, opts, $this.data()) : opts,
- hasDetails = !!$this.find('.' + o.detailClass).length,
- hasBlocks = !!$this.find('*').filter(function() {
- var display = $(this).css('display');
- return (/^block|table|list/).test(display);
- }).length,
- el = hasBlocks ? 'div' : 'span',
- detailSelector = el + '.' + o.detailClass,
- moreSelector = 'span.' + o.moreClass,
- expandSpeed = o.expandSpeed || 0,
- allHtml = $.trim( $this.html() ),
- allText = $.trim( $this.text() ),
- summaryText = allHtml.slice(0, o.slicePoint);
-
- // bail out if we've already set up the expander on this element
- if ( $.data(this, 'expander') ) {
- return;
- }
-
- $.data(this, 'expander', true);
-
- // determine which callback functions are defined
- $.each(['onSlice','beforeExpand', 'afterExpand', 'onCollapse'], function(index, val) {
- defined[val] = $.isFunction(o[val]);
- });
-
- // back up if we're in the middle of a tag or word
- summaryText = backup(summaryText);
-
- // summary text sans tags length
- summTagless = summaryText.replace(rOpenCloseTag, '').length;
-
- // add more characters to the summary, one for each character in the tags
- while (summTagless < o.slicePoint) {
- newChar = allHtml.charAt(summaryText.length);
- if (newChar == '<') {
- newChar = allHtml.slice(summaryText.length).match(rTagPlus)[0];
- }
- summaryText += newChar;
- summTagless++;
- }
-
- summaryText = backup(summaryText, o.preserveWords);
-
- // separate open tags from close tags and clean up the lists
- summOpens = summaryText.match(rOpenTag) || [];
- summCloses = summaryText.match(rCloseTag) || [];
-
- // filter out self-closing tags
- tmp = [];
- $.each(summOpens, function(index, val) {
- if ( !rSelfClose.test(val) ) {
- tmp.push(val);
- }
- });
- summOpens = tmp;
-
- // strip close tags to just the tag name
- l = summCloses.length;
- for (i = 0; i < l; i++) {
- summCloses[i] = summCloses[i].replace(rCloseTag, '$1');
- }
-
- // tags that start in summary and end in detail need:
- // a). close tag at end of summary
- // b). open tag at beginning of detail
- $.each(summOpens, function(index, val) {
- var thisTagName = val.replace(rOpenTag, '$1');
- var closePosition = $.inArray(thisTagName, summCloses);
- if (closePosition === -1) {
- openTagsForDetails.push(val);
- closeTagsForsummaryText.push('</' + thisTagName + '>');
-
- } else {
- summCloses.splice(closePosition, 1);
- }
- });
-
- // reverse the order of the close tags for the summary so they line up right
- closeTagsForsummaryText.reverse();
-
- // create necessary summary and detail elements if they don't already exist
- if ( !hasDetails ) {
-
- // end script if there is no detail text or if detail has fewer words than widow option
- detailText = allHtml.slice(summaryText.length);
- detailTagless = $.trim( detailText.replace(rOpenCloseTag, '') );
-
- if ( detailTagless === '' || detailTagless.split(/\s+/).length < o.widow ) {
- return;
- }
- // otherwise, continue...
- lastCloseTag = closeTagsForsummaryText.pop() || '';
- summaryText += closeTagsForsummaryText.join('');
- detailText = openTagsForDetails.join('') + detailText;
-
- } else {
- // assume that even if there are details, we still need readMore/readLess/summary elements
- // (we already bailed out earlier when readMore el was found)
- // but we need to create els differently
-
- // remove the detail from the rest of the content
- detailText = $this.find(detailSelector).remove().html();
-
- // The summary is what's left
- summaryText = $this.html();
-
- // allHtml is the summary and detail combined (this is needed when content has block-level elements)
- allHtml = summaryText + detailText;
-
- lastCloseTag = '';
- }
- o.moreLabel = $this.find(moreSelector).length ? '' : buildMoreLabel(o);
-
- if (hasBlocks) {
- detailText = allHtml;
- }
- summaryText += lastCloseTag;
-
- // onSlice callback
- o.summary = summaryText;
- o.details = detailText;
- o.lastCloseTag = lastCloseTag;
-
- if (defined.onSlice) {
- // user can choose to return a modified options object
- // one last chance for user to change the options. sneaky, huh?
- // but could be tricky so use at your own risk.
- tmp = o.onSlice.call(thisEl, o);
-
- // so, if the returned value from the onSlice function is an object with a details property, we'll use that!
- o = tmp && tmp.details ? tmp : o;
- }
-
- // build the html with summary and detail and use it to replace old contents
- var html = buildHTML(o, hasBlocks);
-
- $this.html( html );
-
- // set up details and summary for expanding/collapsing
- $thisDetails = $this.find(detailSelector);
- $readMore = $this.find(moreSelector);
- $thisDetails.hide();
- $readMore.find('a').unbind('click.expander').bind('click.expander', expand);
-
- $summEl = $this.find('div.' + o.summaryClass);
-
- if ( o.userCollapse && !$this.find('span.' + o.lessClass).length ) {
- $this
- .find(detailSelector)
- .append('<span class="' + o.lessClass + '">' + o.userCollapsePrefix + '<a href="#">' + o.userCollapseText + '</a></span>');
- }
-
- $this
- .find('span.' + o.lessClass + ' a')
- .unbind('click.expander')
- .bind('click.expander', function(event) {
- event.preventDefault();
- clearTimeout(delayedCollapse);
- var $detailsCollapsed = $(this).closest(detailSelector);
- reCollapse(o, $detailsCollapsed);
- if (defined.onCollapse) {
- o.onCollapse.call(thisEl, true);
- }
- });
-
- function expand(event) {
- event.preventDefault();
- $readMore.hide();
- $summEl.hide();
- if (defined.beforeExpand) {
- o.beforeExpand.call(thisEl);
- }
-
- $thisDetails.stop(false, true)[o.expandEffect](expandSpeed, function() {
- $thisDetails.css({zoom: ''});
- if (defined.afterExpand) {o.afterExpand.call(thisEl);}
- delayCollapse(o, $thisDetails, thisEl);
- });
- }
-
- }); // this.each
- },
- destroy: function() {
- if ( !this.data('expander') ) {
- return;
- }
- this.removeData('expander');
- this.each(function() {
- var $this = $(this),
- o = $.meta ? $.extend({}, opts, $this.data()) : opts,
- details = $this.find('.' + o.detailClass).contents();
-
- $this.find('.' + o.moreClass).remove();
- $this.find('.' + o.summaryClass).remove();
- $this.find('.' + o.detailClass).after(details).remove();
- $this.find('.' + o.lessClass).remove();
-
- });
- }
- };
-
- // run the methods (almost always "init")
- if ( methods[meth] ) {
- methods[ meth ].call(this);
- }
-
- // utility functions
- function buildHTML(o, blocks) {
- var el = 'span',
- summary = o.summary;
- if ( blocks ) {
- el = 'div';
- // if summary ends with a close tag, tuck the moreLabel inside it
- if ( rLastCloseTag.test(summary) && !o.expandAfterSummary) {
- summary = summary.replace(rLastCloseTag, o.moreLabel + '$1');
- } else {
- // otherwise (e.g. if ends with self-closing tag) just add moreLabel after summary
- // fixes #19
- summary += o.moreLabel;
- }
-
- // and wrap it in a div
- summary = '<div class="' + o.summaryClass + '">' + summary + '</div>';
- } else {
- summary += o.moreLabel;
- }
-
- return [
- summary,
- '<',
- el + ' class="' + o.detailClass + '"',
- '>',
- o.details,
- '</' + el + '>'
- ].join('');
- }
-
- function buildMoreLabel(o) {
- var ret = '<span class="' + o.moreClass + '">' + o.expandPrefix;
- ret += '<a href="#">' + o.expandText + '</a></span>';
- return ret;
- }
-
- function backup(txt, preserveWords) {
- if ( txt.lastIndexOf('<') > txt.lastIndexOf('>') ) {
- txt = txt.slice( 0, txt.lastIndexOf('<') );
- }
- if (preserveWords) {
- txt = txt.replace(rAmpWordEnd,'');
- }
-
- return $.trim(txt);
- }
-
- function reCollapse(o, el) {
- el.stop(true, true)[o.collapseEffect](o.collapseSpeed, function() {
- var prevMore = el.prev('span.' + o.moreClass).show();
- if (!prevMore.length) {
- el.parent().children('div.' + o.summaryClass).show()
- .find('span.' + o.moreClass).show();
- }
- });
- }
-
- function delayCollapse(option, $collapseEl, thisEl) {
- if (option.collapseTimer) {
- delayedCollapse = setTimeout(function() {
- reCollapse(option, $collapseEl);
- if ( $.isFunction(option.onCollapse) ) {
- option.onCollapse.call(thisEl, false);
- }
- }, option.collapseTimer);
- }
- }
-
- return this;
- };
-
- // plugin defaults
- $.fn.expander.defaults = $.expander.defaults;
-})(jQuery);
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index c6f7c911f8a..a4beca607ba 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -118,6 +118,9 @@
text-overflow:ellipsis;
word-wrap: break-word;
}
+.openerp .oe_mail .oe_msg .oe_msg_content .oe_msg_body .oe_mail_cleaned {
+ display: none;
+}
/* a) Indented Messages */
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index 5d54a6acc48..62e9241cf4f 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -2,7 +2,7 @@ openerp.mail = function (session) {
var _t = session.web._t,
_lt = session.web._lt;
- var mail = session.mail = {};
+ var mail = session.mail;
openerp_mail_followers(session, mail); // import mail_followers.js
openerp_FieldMany2ManyTagsEmail(session); // import manyy2many_tags_email.js
@@ -225,6 +225,7 @@ openerp.mail = function (session) {
this.name = datasets.name || false,
this.record_name = datasets.record_name || false,
this.body = datasets.body || '',
+ this.body_short = datasets.body_short || '',
this.vote_nb = datasets.vote_nb || 0,
this.has_voted = datasets.has_voted || false,
this.is_favorite = datasets.is_favorite || false,
@@ -944,7 +945,6 @@ openerp.mail = function (session) {
start: function () {
this._super.apply(this, arguments);
- this.expender();
this.bind_events();
if(this.thread_level < this.options.display_indented_thread) {
this.create_thread();
@@ -967,6 +967,8 @@ openerp.mail = function (session) {
this.$('.oe_reply').on('click', this.on_message_reply);
this.$('.oe_star').on('click', this.on_star);
this.$('.oe_msg_vote').on('click', this.on_vote);
+ this.$('.oe_mail_expand').on('click', this.on_expand);
+ this.$('.oe_mail_reduce').on('click', this.on_expand);
this.$('.oe_mail_action_model').on('click', this.on_record_clicked);
},
@@ -995,15 +997,11 @@ openerp.mail = function (session) {
return false;
},
- expender: function () {
- this.$('.oe_msg_body:first').expander({
- slicePoint: this.options.truncate_limit,
- expandText: _t('read more'),
- userCollapseText: _t('read less'),
- detailClass: 'oe_msg_tail',
- moreClass: 'oe_mail_expand',
- lessClass: 'oe_mail_reduce',
- });
+ on_expand: function (event) {
+ event.stopPropagation();
+ this.$('.oe_msg_body_short:first').toggle();
+ this.$('.oe_msg_body_long:first').toggle();
+ return false;
},
/**
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index 94ee1ff452f..1be9754e1c7 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -266,7 +266,13 @@
<t t-if="widget.subject" t-raw="widget.subject"/>
</h1>
<div class="oe_msg_body">
- <t t-raw="widget.body"/>
+ <t t-if="widget.body_short">
+ <div class="oe_msg_body_short"><t t-raw="widget.body_short"/></div>
+ <div class="oe_msg_body_long" style="display: none;"><t t-raw="widget.body"/><span class="oe_mail_reduce"><a href="#">read less</a></span></div>
+ </t>
+ <t t-if="! widget.body_short">
+ <t t-raw="widget.body"/>
+ </t>
</div>
</div>
<div class="oe_msg_footer">
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py
index 148b5faba87..ae5555c01ca 100644
--- a/addons/mail/tests/test_mail_features.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -640,7 +640,7 @@ class test_mail(TestMailBase):
})
compose = mail_compose.browse(cr, uid, compose_id)
- # D: Post the comment, get created message for each group
+ # Do: Post the comment, get created message for each group
mail_compose.send_mail(cr, user_raoul.id, [compose_id], context={
'default_res_id': -1,
'active_ids': [self.group_pigs_id, group_bird_id]
@@ -679,6 +679,37 @@ class test_mail(TestMailBase):
self.assertEqual(set(bird_pids), set(test_pids),
'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account')
+ # Do: Compose in mass_mail, coming from list_view, we have an active_domain that should be supported
+ compose_id = mail_compose.create(cr, user_raoul.id,
+ {
+ 'subject': _subject,
+ 'body': '${object.description}',
+ 'partner_ids': [(4, p_c_id), (4, p_d_id)],
+ }, context={
+ 'default_composition_mode': 'mass_mail',
+ 'default_model': 'mail.group',
+ 'default_res_id': False,
+ 'active_ids': [self.group_pigs_id],
+ 'active_domain': [('name', 'in', ['Pigs', 'Bird'])],
+ })
+ compose = mail_compose.browse(cr, uid, compose_id)
+
+ # Do: Post the comment, get created message for each group
+ mail_compose.send_mail(
+ cr, user_raoul.id, [compose_id], context={
+ 'default_res_id': -1,
+ 'active_ids': [self.group_pigs_id, group_bird_id]
+ })
+ group_pigs.refresh()
+ group_bird.refresh()
+ message1 = group_pigs.message_ids[0]
+ message2 = group_bird.message_ids[0]
+
+ # Test: Pigs and Bird did receive their message
+ test_msg_ids = self.mail_message.search(cr, uid, [], limit=2)
+ self.assertIn(message1.id, test_msg_ids, 'compose wizard: Pigs did not receive its mass mailing message')
+ self.assertIn(message2.id, test_msg_ids, 'compose wizard: Bird did not receive its mass mailing message')
+
def test_30_needaction(self):
""" Tests for mail.message needaction. """
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py
index 2e0ba336dc4..fade38869f1 100644
--- a/addons/mail/tests/test_mail_gateway.py
+++ b/addons/mail/tests/test_mail_gateway.py
@@ -20,7 +20,7 @@
##############################################################################
from openerp.addons.mail.tests.test_mail_base import TestMailBase
-from openerp.tools import mute_logger, email_split
+from openerp.tools import mute_logger
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
To: {to}
@@ -101,9 +101,9 @@ class TestMailgateway(TestMailBase):
# Do: find partner with email -> first partner should be found
partner_info = self.mail_thread.message_partner_info_from_emails(cr, uid, None, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
self.assertEqual(partner_info['full_name'], 'Maybe Raoul <test@test.fr>',
- 'mail_thread: message_partner_info_from_emails did not handle email')
+ 'mail_thread: message_partner_info_from_emails did not handle email')
self.assertEqual(partner_info['partner_id'], p_a_id,
- 'mail_thread: message_partner_info_from_emails wrong partner found')
+ 'mail_thread: message_partner_info_from_emails wrong partner found')
# Data: add some data about partners
# 2 - User BRaoul
@@ -112,7 +112,7 @@ class TestMailgateway(TestMailBase):
# Do: find partner with email -> first user should be found
partner_info = self.mail_thread.message_partner_info_from_emails(cr, uid, None, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
self.assertEqual(partner_info['partner_id'], p_b_id,
- 'mail_thread: message_partner_info_from_emails wrong partner found')
+ 'mail_thread: message_partner_info_from_emails wrong partner found')
# --------------------------------------------------
# CASE1: with object
@@ -122,7 +122,7 @@ class TestMailgateway(TestMailBase):
self.mail_group.message_subscribe(cr, uid, [group_pigs.id], [p_b_id])
partner_info = self.mail_group.message_partner_info_from_emails(cr, uid, group_pigs.id, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
self.assertEqual(partner_info['partner_id'], p_b_id,
- 'mail_thread: message_partner_info_from_emails wrong partner found')
+ 'mail_thread: message_partner_info_from_emails wrong partner found')
def test_05_mail_message_mail_mail(self):
""" Tests designed for testing email values based on mail.message, aliases, ... """
@@ -146,46 +146,46 @@ class TestMailgateway(TestMailBase):
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
# Test: message content
self.assertIn('reply_to', msg.message_id,
- 'mail_message: message_id should be specific to a mail_message with a given reply_to')
+ 'mail_message: message_id should be specific to a mail_message with a given reply_to')
self.assertEqual(msg.reply_to, reply_to1,
- 'mail_message: incorrect reply_to: should come from values')
+ 'mail_message: incorrect reply_to: should come from values')
self.assertEqual(msg.email_from, email_from1,
- 'mail_message: incorrect email_from: should come from values')
+ 'mail_message: incorrect email_from: should come from values')
# Do: create a mail_mail with the previous mail_message
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, reply_to1,
- 'mail_mail: incorrect reply_to: should come from mail.message')
+ 'mail_mail: incorrect reply_to: should come from mail.message')
self.assertEqual(mail.email_from, email_from1,
- 'mail_mail: incorrect email_from: should come from mail.message')
+ 'mail_mail: incorrect email_from: should come from mail.message')
# Do: create a mail_mail with the previous mail_message + specified reply_to
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel', 'reply_to': reply_to2})
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, reply_to2,
- 'mail_mail: incorrect reply_to: should come from values')
+ 'mail_mail: incorrect reply_to: should come from values')
self.assertEqual(mail.email_from, email_from1,
- 'mail_mail: incorrect email_from: should come from mail.message')
+ 'mail_mail: incorrect email_from: should come from mail.message')
# Do: mail_message attached to a document
msg_id = self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_pigs_id})
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
# Test: message content
self.assertIn('mail.group', msg.message_id,
- 'mail_message: message_id should contain model')
+ 'mail_message: message_id should contain model')
self.assertIn('%s' % self.group_pigs_id, msg.message_id,
- 'mail_message: message_id should contain res_id')
+ 'mail_message: message_id should contain res_id')
self.assertFalse(msg.reply_to,
- 'mail_message: incorrect reply_to: should not be generated if not specified')
+ 'mail_message: incorrect reply_to: should not be generated if not specified')
self.assertEqual(msg.email_from, raoul_from,
- 'mail_message: incorrect email_from: should be Raoul')
+ 'mail_message: incorrect email_from: should be Raoul')
# Do: create a mail_mail based on the previous mail_message
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, raoul_reply,
- 'mail_mail: incorrect reply_to: should be Raoul')
+ 'mail_mail: incorrect reply_to: should be Raoul')
# Data: set catchall domain
self.registry('ir.config_parameter').set_param(cr, uid, 'mail.catchall.domain', alias_domain)
@@ -199,7 +199,7 @@ class TestMailgateway(TestMailBase):
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, raoul_reply_alias,
- 'mail_mail: incorrect reply_to: should be Pigs alias')
+ 'mail_mail: incorrect reply_to: should be Pigs alias')
# Update message: test alias on email_from
msg_id = self.mail_message.create(cr, user_raoul_id, {})
@@ -209,7 +209,7 @@ class TestMailgateway(TestMailBase):
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, raoul_from_alias,
- 'mail_mail: incorrect reply_to: should be message email_from using Raoul alias')
+ 'mail_mail: incorrect reply_to: should be message email_from using Raoul alias')
# Update message
self.mail_message.write(cr, user_raoul_id, [msg_id], {'res_id': False, 'email_from': 'someone@schlouby.fr', 'reply_to': False})
@@ -219,7 +219,7 @@ class TestMailgateway(TestMailBase):
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, msg.email_from,
- 'mail_mail: incorrect reply_to: should be message email_from')
+ 'mail_mail: incorrect reply_to: should be message email_from')
# Data: set catchall alias
self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.alias', 'gateway')
@@ -232,21 +232,21 @@ class TestMailgateway(TestMailBase):
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail Content-Type
self.assertEqual(mail.reply_to, 'gateway@schlouby.fr',
- 'mail_mail: reply_to should equal the catchall email alias')
+ 'mail_mail: reply_to should equal the catchall email alias')
# Do: create a mail_mail
mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, 'gateway@schlouby.fr',
- 'mail_mail: reply_to should equal the catchall email alias')
+ 'mail_mail: reply_to should equal the catchall email alias')
# Do: create a mail_mail
mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel', 'reply_to': 'someone@example.com'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, 'someone@example.com',
- 'mail_mail: reply_to should equal the rpely_to given to create')
+ 'mail_mail: reply_to should equal the rpely_to given to create')
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_10_message_process(self):
@@ -254,9 +254,9 @@ class TestMailgateway(TestMailBase):
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
def format_and_process(template, to='groups@example.com, other@gmail.com', subject='Frogs',
- extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
- msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
- model=None):
+ extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
+ msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
+ model=None):
self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', subject)]), [])
mail = template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
self.mail_thread.message_process(cr, uid, model, mail)
@@ -289,29 +289,29 @@ class TestMailgateway(TestMailBase):
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False)
self.assertEqual(res[0].get('create_uid'), uid,
- 'message_process: group should have been created by uid as alias_user__id is False on the alias')
+ 'message_process: group should have been created by uid as alias_user__id is False on the alias')
# Test: one message that is the incoming email
self.assertEqual(len(frog_group.message_ids), 1,
- 'message_process: newly created group should have the incoming email in message_ids')
+ 'message_process: newly created group should have the incoming email in message_ids')
msg = frog_group.message_ids[0]
self.assertEqual('Frogs', msg.subject,
- 'message_process: newly created group should have the incoming email as first message')
+ 'message_process: newly created group should have the incoming email as first message')
self.assertIn('Please call me as soon as possible this afternoon!', msg.body,
- 'message_process: newly created group should have the incoming email as first message')
+ 'message_process: newly created group should have the incoming email as first message')
self.assertEqual('email', msg.type,
- 'message_process: newly created group should have an email as first message')
+ 'message_process: newly created group should have an email as first message')
self.assertEqual('Discussions', msg.subtype_id.name,
- 'message_process: newly created group should not have a log first message but an email')
+ 'message_process: newly created group should not have a log first message but an email')
# Test: message: unknown email address -> message has email_from, not author_id
self.assertFalse(msg.author_id,
- 'message_process: message on created group should not have an author_id')
+ 'message_process: message on created group should not have an author_id')
self.assertIn('test.sylvie.lelitre@agrolait.com', msg.email_from,
- 'message_process: message on created group should have an email_from')
+ 'message_process: message on created group should have an email_from')
# Test: followers: nobody
self.assertEqual(len(frog_group.message_follower_ids), 0, 'message_process: newly create group should not have any follower')
# Test: sent emails: no-one
self.assertEqual(len(sent_emails), 0,
- 'message_process: should create emails without any follower added')
+ 'message_process: should create emails without any follower added')
# Data: unlink group
frog_group.unlink()
@@ -324,11 +324,11 @@ class TestMailgateway(TestMailBase):
# Test: email bounced
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 1,
- 'message_process: incoming email on Partners alias should send a bounce email')
+ 'message_process: incoming email on Partners alias should send a bounce email')
self.assertIn('Frogs', sent_emails[0].get('subject'),
- 'message_process: bounce email on Partners alias should contain the original subject')
+ 'message_process: bounce email on Partners alias should contain the original subject')
self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to'),
- 'message_process: bounce email on Partners alias should have original email sender as recipient')
+ 'message_process: bounce email on Partners alias should have original email sender as recipient')
# Do: incoming email from an unknown partner on a Followers only alias -> bounce
self._init_mock_build_email()
@@ -339,11 +339,11 @@ class TestMailgateway(TestMailBase):
# Test: email bounced
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 1,
- 'message_process: incoming email on Followers alias should send a bounce email')
+ 'message_process: incoming email on Followers alias should send a bounce email')
self.assertIn('Frogs', sent_emails[0].get('subject'),
- 'message_process: bounce email on Followers alias should contain the original subject')
+ 'message_process: bounce email on Followers alias should contain the original subject')
self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to'),
- 'message_process: bounce email on Followers alias should have original email sender as recipient')
+ 'message_process: bounce email on Followers alias should have original email sender as recipient')
# Do: incoming email from a known partner on a Partners alias -> ok (+ test on alias.user_id)
self.mail_alias.write(cr, uid, [alias_id], {'alias_user_id': self.user_raoul_id, 'alias_contact': 'partners'})
@@ -357,24 +357,24 @@ class TestMailgateway(TestMailBase):
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False)
self.assertEqual(res[0].get('create_uid'), self.user_raoul_id,
- 'message_process: group should have been created by alias_user_id')
+ 'message_process: group should have been created by alias_user_id')
# Test: one message that is the incoming email
self.assertEqual(len(frog_group.message_ids), 1,
- 'message_process: newly created group should have the incoming email in message_ids')
+ 'message_process: newly created group should have the incoming email in message_ids')
msg = frog_group.message_ids[0]
# Test: message: author found
self.assertEqual(p1id, msg.author_id.id,
- 'message_process: message on created group should have Sylvie as author_id')
+ 'message_process: message on created group should have Sylvie as author_id')
self.assertIn('Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', msg.email_from,
- 'message_process: message on created group should have have an email_from')
+ 'message_process: message on created group should have have an email_from')
# Test: author (not recipient and not Raoul (as alias owner)) added as follower
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
self.assertEqual(frog_follower_ids, set([p1id]),
- 'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
+ 'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
# Test: sent emails: no-one, no bounce effet
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 0,
- 'message_process: should not bounce incoming emails')
+ 'message_process: should not bounce incoming emails')
# Data: unlink group
frog_group.unlink()
@@ -387,7 +387,7 @@ class TestMailgateway(TestMailBase):
# Test: email bounced
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 1,
- 'message_process: incoming email on Partners alias should send a bounce email')
+ 'message_process: incoming email on Partners alias should send a bounce email')
# Do: incoming email from a parent document follower on a Followers only alias -> ok
self._init_mock_build_email()
@@ -398,15 +398,15 @@ class TestMailgateway(TestMailBase):
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: one message that is the incoming email
self.assertEqual(len(frog_group.message_ids), 1,
- 'message_process: newly created group should have the incoming email in message_ids')
+ 'message_process: newly created group should have the incoming email in message_ids')
# Test: author (and not recipient) added as follower
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
self.assertEqual(frog_follower_ids, set([p1id]),
- 'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
+ 'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
# Test: sent emails: no-one, no bounce effet
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 0,
- 'message_process: should not bounce incoming emails')
+ 'message_process: should not bounce incoming emails')
# --------------------------------------------------
# Test2: update-like alias
@@ -416,43 +416,43 @@ class TestMailgateway(TestMailBase):
self._init_mock_build_email()
self.mail_group.write(cr, uid, [frog_group.id], {'alias_name': 'frogs', 'alias_contact': 'followers', 'alias_force_thread_id': frog_group.id})
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
- msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
- to='frogs@example.com>', subject='Re: news')
+ msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
+ to='frogs@example.com>', subject='Re: news')
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
- 'message_process: reply on Frogs should not have created a new group with new subject')
+ 'message_process: reply on Frogs should not have created a new group with new subject')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
self.assertEqual(len(frog_groups), 1,
- 'message_process: reply on Frogs should not have created a duplicate group with old subject')
+ 'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: email bounced
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 1,
- 'message_process: incoming email on Followers alias should send a bounce email')
+ 'message_process: incoming email on Followers alias should send a bounce email')
self.assertIn('Re: news', sent_emails[0].get('subject'),
- 'message_process: bounce email on Followers alias should contain the original subject')
+ 'message_process: bounce email on Followers alias should contain the original subject')
# Do: Pigs alias is restricted, should accept Followers
self._init_mock_build_email()
self.mail_group.message_subscribe(cr, uid, [frog_group.id], [p2id])
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
- msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>',
- to='frogs@example.com>', subject='Re: cats')
+ msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>',
+ to='frogs@example.com>', subject='Re: cats')
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
- 'message_process: reply on Frogs should not have created a new group with new subject')
+ 'message_process: reply on Frogs should not have created a new group with new subject')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
self.assertEqual(len(frog_groups), 1,
- 'message_process: reply on Frogs should not have created a duplicate group with old subject')
+ 'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: one new message
self.assertEqual(len(frog_group.message_ids), 2, 'message_process: group should contain 2 messages after reply')
# Test: sent emails: 1 (Sylvie copy of the incoming email, but no bounce)
sent_emails = self._build_email_kwargs_list
self.assertEqual(len(sent_emails), 1,
- 'message_process: one email should have been generated')
+ 'message_process: one email should have been generated')
self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to')[0],
- 'message_process: email should be sent to Sylvie')
+ 'message_process: email should be sent to Sylvie')
self.mail_group.message_unsubscribe(cr, uid, [frog_group.id], [p2id])
# --------------------------------------------------
@@ -461,40 +461,40 @@ class TestMailgateway(TestMailBase):
# Do: even with a wrong destination, a reply should end up in the correct thread
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
- msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
- to='erroneous@example.com>', subject='Re: news',
- extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
+ msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
+ to='erroneous@example.com>', subject='Re: news',
+ extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
- 'message_process: reply on Frogs should not have created a new group with new subject')
+ 'message_process: reply on Frogs should not have created a new group with new subject')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
self.assertEqual(len(frog_groups), 1,
- 'message_process: reply on Frogs should not have created a duplicate group with old subject')
+ 'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: one new message
self.assertEqual(len(frog_group.message_ids), 3, 'message_process: group should contain 2 messages after reply')
# Test: author (and not recipient) added as follower
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
self.assertEqual(frog_follower_ids, set([p1id, p2id]),
- 'message_process: after reply, group should have 2 followers')
+ 'message_process: after reply, group should have 2 followers')
# Do: due to some issue, same email goes back into the mailgateway
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
- msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
- subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
+ msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
+ subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
- 'message_process: reply on Frogs should not have created a new group with new subject')
+ 'message_process: reply on Frogs should not have created a new group with new subject')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
self.assertEqual(len(frog_groups), 1,
- 'message_process: reply on Frogs should not have created a duplicate group with old subject')
+ 'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: no new message
self.assertEqual(len(frog_group.message_ids), 3, 'message_process: message with already existing message_id should not have been duplicated')
# Test: message_id is still unique
msg_ids = self.mail_message.search(cr, uid, [('message_id', 'ilike', '<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>')])
self.assertEqual(len(msg_ids), 1,
- 'message_process: message with already existing message_id should not have been duplicated')
+ 'message_process: message with already existing message_id should not have been duplicated')
# --------------------------------------------------
# Test4: email_from and partner finding
@@ -505,28 +505,28 @@ class TestMailgateway(TestMailBase):
# Do: post a new message, with a known partner -> duplicate emails -> partner
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
- to='erroneous@example.com>', subject='Re: news (2)',
- msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>',
- extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
+ to='erroneous@example.com>', subject='Re: news (2)',
+ msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>',
+ extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: author is A-Raoul (only existing)
self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id,
- 'message_process: email_from -> author_id wrong')
+ 'message_process: email_from -> author_id wrong')
# Do: post a new message, with a known partner -> duplicate emails -> user
frog_group.message_unsubscribe([extra_partner_id])
raoul_email = self.user_raoul.email
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
- to='erroneous@example.com>', subject='Re: news (3)',
- msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>',
- extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
+ to='erroneous@example.com>', subject='Re: news (3)',
+ msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>',
+ extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: author is Raoul (user), not A-Raoul
self.assertEqual(frog_group.message_ids[0].author_id.id, self.partner_raoul_id,
- 'message_process: email_from -> author_id wrong')
+ 'message_process: email_from -> author_id wrong')
# Do: post a new message, with a known partner -> duplicate emails -> partner because is follower
frog_group.message_unsubscribe([self.partner_raoul_id])
@@ -534,14 +534,14 @@ class TestMailgateway(TestMailBase):
raoul_email = self.user_raoul.email
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
- to='erroneous@example.com>', subject='Re: news (3)',
- msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>',
- extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
+ to='erroneous@example.com>', subject='Re: news (3)',
+ msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>',
+ extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: author is Raoul (user), not A-Raoul
self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id,
- 'message_process: email_from -> author_id wrong')
+ 'message_process: email_from -> author_id wrong')
self.res_users.write(cr, uid, self.user_raoul_id, {'email': raoul_email})
@@ -551,37 +551,37 @@ class TestMailgateway(TestMailBase):
# Do: incoming email with model that does not accepts incoming emails must raise
self.assertRaises(AssertionError,
- format_and_process,
- MAIL_TEMPLATE,
- to='noone@example.com', subject='spam', extra='', model='res.country',
- msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>')
+ format_and_process,
+ MAIL_TEMPLATE,
+ to='noone@example.com', subject='spam', extra='', model='res.country',
+ msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>')
# Do: incoming email without model and without alias must raise
self.assertRaises(AssertionError,
- format_and_process,
- MAIL_TEMPLATE,
- to='noone@example.com', subject='spam', extra='',
- msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>')
+ format_and_process,
+ MAIL_TEMPLATE,
+ to='noone@example.com', subject='spam', extra='',
+ msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>')
# Do: incoming email with model that accepting incoming emails as fallback
frog_groups = format_and_process(MAIL_TEMPLATE,
- to='noone@example.com',
- subject='Spammy', extra='', model='mail.group',
- msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>')
+ to='noone@example.com',
+ subject='Spammy', extra='', model='mail.group',
+ msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>')
self.assertEqual(len(frog_groups), 1,
- 'message_process: erroneous email but with a fallback model should have created a new mail.group')
+ 'message_process: erroneous email but with a fallback model should have created a new mail.group')
# Do: incoming email in plaintext should be stored as html
frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT,
- to='groups@example.com', subject='Frogs Return', extra='',
- msg_id='<deadcafe.1337@smtp.agrolait.com>')
+ to='groups@example.com', subject='Frogs Return', extra='',
+ msg_id='<deadcafe.1337@smtp.agrolait.com>')
# Test: one group created with one message
self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
msg = frog_group.message_ids[0]
# Test: plain text content should be wrapped and stored as html
self.assertIn('<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>', msg.body,
- 'message_process: plaintext incoming email incorrectly parsed')
+ 'message_process: plaintext incoming email incorrectly parsed')
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_20_thread_parent_resolution(self):
@@ -602,26 +602,26 @@ class TestMailgateway(TestMailBase):
# Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms
# 0. Direct alias match
reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs <group+pigs@example.com>',
- extra='In-Reply-To: %s' % msg1.message_id,
- msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>')
+ extra='In-Reply-To: %s' % msg1.message_id,
+ msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>')
self.mail_group.message_process(cr, uid, None, reply_msg1)
# 1. In-Reply-To header
reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com',
- extra='In-Reply-To: %s' % msg1.message_id,
- msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>')
+ extra='In-Reply-To: %s' % msg1.message_id,
+ msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>')
self.mail_group.message_process(cr, uid, None, reply_msg2)
# 2. References header
reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com',
- extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id,
- msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>')
+ extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id,
+ msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>')
self.mail_group.message_process(cr, uid, None, reply_msg3)
# 3. Subject contains [<ID>] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids)
reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com',
- extra='', subject='Re: [%s] 1' % self.group_pigs_id,
- msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>')
+ extra='', subject='Re: [%s] 1' % self.group_pigs_id,
+ msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>')
self.mail_group.message_process(cr, uid, 'mail.group', reply_msg4)
group_pigs.refresh()
@@ -633,12 +633,19 @@ class TestMailgateway(TestMailBase):
""" Testing private discussion between partners. """
cr, uid = self.cr, self.uid
+ def format(template, to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: 1',
+ extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
+ msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
+ return template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
+
# Do: Raoul writes to Bert and Administrator, with a thread_model in context that should not be taken into account
msg1_pids = [self.partner_admin_id, self.partner_bert_id]
- msg1_id = self.mail_thread.message_post(cr, self.user_raoul_id, False,
- partner_ids=msg1_pids,
- subtype='mail.mt_comment',
- context={'thread_model': 'mail.group'})
+ msg1_id = self.mail_thread.message_post(
+ cr, self.user_raoul_id, False,
+ partner_ids=msg1_pids,
+ subtype='mail.mt_comment',
+ context={'thread_model': 'mail.group'}
+ )
# Test: message recipients
msg = self.mail_message.browse(cr, uid, msg1_id)
@@ -647,16 +654,26 @@ class TestMailgateway(TestMailBase):
test_pids = msg1_pids
test_nids = msg1_pids
self.assertEqual(set(msg_pids), set(test_pids),
- 'message_post: private discussion: incorrect recipients')
+ 'message_post: private discussion: incorrect recipients')
self.assertEqual(set(msg_nids), set(test_nids),
- 'message_post: private discussion: incorrect notified recipients')
+ 'message_post: private discussion: incorrect notified recipients')
self.assertEqual(msg.model, False,
- 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id')
+ 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id')
+ # Test: message reply_to and message-id
+ self.assertFalse(msg.reply_to,
+ 'message_post: private discussion: initial message should not have any reply_to specified')
+ self.assertIn('openerp-private', msg.message_id,
+ 'message_post: private discussion: message-id should contain the private keyword')
# Do: Bert replies through mailgateway (is a customer)
- msg2_id = self.mail_thread.message_post(cr, uid, False,
- author_id=self.partner_bert_id,
- parent_id=msg1_id, subtype='mail.mt_comment')
+ reply_message = format(MAIL_TEMPLATE, to='not_important@mydomain.com',
+ email_from='bert@bert.fr',
+ extra='In-Reply-To: %s' % msg.message_id,
+ msg_id='<test30.JavaMail.0@agrolait.com>')
+ self.mail_thread.message_process(cr, uid, None, reply_message)
+
+ # Test: last mail_message created
+ msg2_id = self.mail_message.search(cr, uid, [], limit=1)[0]
# Test: message recipients
msg = self.mail_message.browse(cr, uid, msg2_id)
@@ -664,14 +681,32 @@ class TestMailgateway(TestMailBase):
msg_nids = [p.id for p in msg.notified_partner_ids]
test_pids = [self.partner_admin_id, self.partner_raoul_id]
test_nids = test_pids
+ self.assertEqual(msg.author_id.id, self.partner_bert_id,
+ 'message_post: private discussion: wrong author through mailgatewya based on email')
+ self.assertEqual(set(msg_pids), set(test_pids),
+ 'message_post: private discussion: incorrect recipients when replying')
+ self.assertEqual(set(msg_nids), set(test_nids),
+ 'message_post: private discussion: incorrect notified recipients when replying')
+
+ # Do: Bert replies through chatter (is a customer)
+ msg3_id = self.mail_thread.message_post(
+ cr, uid, False,
+ author_id=self.partner_bert_id,
+ parent_id=msg1_id, subtype='mail.mt_comment')
+
+ # Test: message recipients
+ msg = self.mail_message.browse(cr, uid, msg3_id)
+ msg_pids = [p.id for p in msg.partner_ids]
+ msg_nids = [p.id for p in msg.notified_partner_ids]
+ test_pids = [self.partner_admin_id, self.partner_raoul_id]
+ test_nids = test_pids
self.assertEqual(set(msg_pids), set(test_pids),
- 'message_post: private discussion: incorrect recipients when replying')
+ 'message_post: private discussion: incorrect recipients when replying')
self.assertEqual(set(msg_nids), set(test_nids),
- 'message_post: private discussion: incorrect notified recipients when replying')
+ 'message_post: private discussion: incorrect notified recipients when replying')
# Do: Administrator replies
- msg3_id = self.mail_thread.message_post(cr, uid, False,
- parent_id=msg2_id, subtype='mail.mt_comment')
+ msg3_id = self.mail_thread.message_post(cr, uid, False, parent_id=msg3_id, subtype='mail.mt_comment')
# Test: message recipients
msg = self.mail_message.browse(cr, uid, msg3_id)
@@ -680,6 +715,6 @@ class TestMailgateway(TestMailBase):
test_pids = [self.partner_bert_id, self.partner_raoul_id]
test_nids = test_pids
self.assertEqual(set(msg_pids), set(test_pids),
- 'message_post: private discussion: incorrect recipients when replying')
+ 'message_post: private discussion: incorrect recipients when replying')
self.assertEqual(set(msg_nids), set(test_nids),
- 'message_post: private discussion: incorrect notified recipients when replying')
+ 'message_post: private discussion: incorrect notified recipients when replying')
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index 7685a27f1ed..6ab1f0e81ff 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -73,6 +73,11 @@ class mail_compose_message(osv.TransientModel):
res_id = context.get('default_res_id', context.get('active_id'))
message_id = context.get('default_parent_id', context.get('message_id', context.get('active_id')))
active_ids = context.get('active_ids')
+ if 'active_domain' in context: # not context.get() because we want to keep global [] domains
+ result['use_active_domain'] = True
+ result['active_domain'] = '%s' % context.get('active_domain')
+ else:
+ result['active_domain'] = ''
# get default values according to the composition mode
if composition_mode == 'reply':
@@ -112,6 +117,8 @@ class mail_compose_message(osv.TransientModel):
'partner_ids': fields.many2many('res.partner',
'mail_compose_message_res_partner_rel',
'wizard_id', 'partner_id', 'Additional contacts'),
+ 'use_active_domain': fields.boolean('Use active domain'),
+ 'active_domain': fields.char('Active domain', readonly=True),
'post': fields.boolean('Post a copy in the document',
help='Post a copy of the message on the document communication history.'),
'notify': fields.boolean('Notify followers',
@@ -129,7 +136,6 @@ class mail_compose_message(osv.TransientModel):
'body': lambda self, cr, uid, ctx={}: '',
'subject': lambda self, cr, uid, ctx={}: False,
'partner_ids': lambda self, cr, uid, ctx={}: [],
- 'notify': lambda self, cr, uid, ctx={}: False,
'post': lambda self, cr, uid, ctx={}: True,
'same_thread': lambda self, cr, uid, ctx={}: True,
}
@@ -238,8 +244,14 @@ class mail_compose_message(osv.TransientModel):
context['thread_model'] = wizard.model
active_model_pool = self.pool['mail.thread']
- # wizard works in batch mode: [res_id] or active_ids
- res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id]
+ # wizard works in batch mode: [res_id] or active_ids or active_domain
+ if mass_mail_mode and wizard.use_active_domain and wizard.model:
+ res_ids = self.pool[wizard.model].search(cr, uid, eval(wizard.active_domain), context=context)
+ elif mass_mail_mode and wizard.model and active_ids:
+ res_ids = active_ids
+ else:
+ res_ids = [wizard.res_id]
+
for res_id in res_ids:
# mail.message values, according to the wizard options
post_values = {
diff --git a/addons/mail/wizard/mail_compose_message_view.xml b/addons/mail/wizard/mail_compose_message_view.xml
index 1ca07b6a94c..07d39bb0965 100644
--- a/addons/mail/wizard/mail_compose_message_view.xml
+++ b/addons/mail/wizard/mail_compose_message_view.xml
@@ -12,6 +12,9 @@
<field name="model" invisible="1"/>
<field name="res_id" invisible="1"/>
<field name="parent_id" invisible="1"/>
+ <field name="mail_server_id" invisible="1"/>
+ <field name="use_active_domain" invisible="1"/>
+ <field name="active_domain" invisible="1"/>
<!-- visible wizard -->
<field name="email_from"
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
diff --git a/addons/mrp/i18n/zh_CN.po b/addons/mrp/i18n/zh_CN.po
index 2722e28fee4..216c9f4d8b9 100644
--- a/addons/mrp/i18n/zh_CN.po
+++ b/addons/mrp/i18n/zh_CN.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-11-28 14:03+0000\n"
-"Last-Translator: hifly <Unknown>\n"
+"PO-Revision-Date: 2013-08-07 16:09+0000\n"
+"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:02+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-08-08 04:39+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
#. module: mrp
#: help:mrp.config.settings,module_mrp_repair:0
@@ -69,7 +69,7 @@ msgstr "周期数"
msgid ""
"The 'Minimum stock rule' allows the system to create procurement orders "
"automatically as soon as the minimum stock is reached."
-msgstr "最小库存规则允许系统在达到最小库存数量的时候立即创建补货单"
+msgstr "最小库存规则允许系统在达到最小库存数量的时会自动创建补货单"
#. module: mrp
#: code:addons/mrp/report/price.py:130
@@ -199,7 +199,7 @@ msgstr "用于外购的物料"
#. module: mrp
#: model:ir.ui.menu,name:mrp.menu_mrp_production_order_action
msgid "Order Planning"
-msgstr ""
+msgstr "制造单计划"
#. module: mrp
#: field:mrp.config.settings,module_mrp_operations:0
@@ -286,7 +286,7 @@ msgstr "从一个生产订单生产几个产品"
msgid ""
"The selection of the right Bill of Material to use will depend on the "
"properties specified on the sales order and the Bill of Material."
-msgstr ""
+msgstr "被正确使用的BOM依赖于销售单和BOM中指定的属性"
#. module: mrp
#: view:mrp.bom:0
@@ -294,7 +294,7 @@ msgid ""
"When processing a sales order for this product, the delivery order\n"
" will contain the raw materials, instead of "
"the finished product."
-msgstr ""
+msgstr "当处理该产品的销售单时,发运单将以原料来替代成品"
#. module: mrp
#: report:mrp.production.order:0
@@ -490,6 +490,16 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 创建新属性\n"
+" </p><p>\n"
+" 当同一个产品有多种组成的方式,\n"
+" OpenERP会根据属性来选择合适的BoM。\n"
+" 你可以给每个物料清单分配若干个属性,\n"
+" 当销售人员创建销售订单,根据需要指定几个属性,\n"
+" 然后OpenERP 会根据其来自动选择相应的BoM。\n"
+" </p>\n"
+" "
#. module: mrp
#: view:mrp.production:0
@@ -499,7 +509,7 @@ msgid "Scheduled Date"
msgstr "下单日期"
#. module: mrp
-#: code:addons/mrp/procurement.py:124
+#: code:addons/mrp/procurement.py:129
#, python-format
msgid "Manufacturing Order <em>%s</em> created."
msgstr "生产订单 <em>%s</em> 创建。"
@@ -684,7 +694,7 @@ msgid "Work Center Load"
msgstr "工作中心负载"
#. module: mrp
-#: code:addons/mrp/procurement.py:50
+#: code:addons/mrp/procurement.py:55
#, python-format
msgid "No BoM defined for this product !"
msgstr "该产品尚未定义物料清单!"
@@ -991,7 +1001,7 @@ msgid "BoM Type"
msgstr "物料清单类型"
#. module: mrp
-#: code:addons/mrp/procurement.py:52
+#: code:addons/mrp/procurement.py:57
#, python-format
msgid ""
"Procurement '%s' has an exception: 'No BoM defined for this product !'"
@@ -1120,7 +1130,7 @@ msgstr "生产订单"
#. module: mrp
#: selection:mrp.production,state:0
msgid "Awaiting Raw Materials"
-msgstr ""
+msgstr "等待原材料"
#. module: mrp
#: field:mrp.bom,position:0
@@ -1629,6 +1639,17 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 点击创建属性组\n"
+" </p><p>\n"
+" 可以定义特定的属性组用来分配到BoM和销售订单。\n"
+" 根据销售人员在销售订单上选取的属性,OpenERP可以\n"
+" 自动选择相应的BoM。\n"
+" </p><p>\n"
+" 例如,在属性组“保修” ,你有两个属性:1年保修,3年保修。\n"
+" 根据销售订单上的选择,OpenERP会自动选择对应的BoM排单生产。\n"
+" </p>\n"
+" "
#. module: mrp
#: field:mrp.workcenter,capacity_per_cycle:0
@@ -1774,8 +1795,8 @@ msgid ""
"the quantity selected and it will finish the production order when total "
"ordered quantities are produced."
msgstr ""
-"'废料' 模式会仅消耗对应成品数量的原材料而无产成品产出。\n"
-"'报工' 模式会消耗对应成品数量的原材料而且产出对应数量的产成品。"
+"'投料' 模式会仅消耗对应成品数量的原材料暂无产成品产出。\n"
+"'投料并产出' 模式会消耗对应成品数量的原材料并立即产出对应数量的产成品。"
#. module: mrp
#: view:mrp.production:0
@@ -1981,7 +2002,7 @@ msgstr "新建"
#. module: mrp
#: selection:mrp.product.produce,mode:0
msgid "Consume Only"
-msgstr "废料"
+msgstr "投料"
#. module: mrp
#: view:mrp.production:0
@@ -2161,7 +2182,7 @@ msgstr "用户"
#. module: mrp
#: selection:mrp.product.produce,mode:0
msgid "Consume & Produce"
-msgstr "报工"
+msgstr "投料并产出"
#. module: mrp
#: field:mrp.bom,bom_id:0
@@ -2191,7 +2212,7 @@ msgstr "产品类型是可库存或消耗品"
#. module: mrp
#: selection:mrp.production,state:0
msgid "Production Started"
-msgstr "生产开始了"
+msgstr "已开始生产"
#. module: mrp
#: model:process.node,name:mrp.process_node_procureproducts0
diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py
index 87861ba8fc6..52fdda1a7b2 100644
--- a/addons/mrp_operations/mrp_operations.py
+++ b/addons/mrp_operations/mrp_operations.py
@@ -246,6 +246,7 @@ class mrp_production(osv.osv):
""" Cancels work order if production order is canceled.
@return: Super method
"""
+ workcenter_pool = self.pool.get('mrp.production.workcenter.line')
obj = self.browse(cr, uid, ids,context=context)[0]
for workcenter_line in obj.workcenter_lines:
workcenter_pool.signal_button_cancel(cr, uid, [workcenter_line.id])
diff --git a/addons/note/i18n/bs.po b/addons/note/i18n/bs.po
new file mode 100644
index 00000000000..d31dd1870f0
--- /dev/null
+++ b/addons/note/i18n/bs.po
@@ -0,0 +1,284 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-08-06 16:51+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
+
+#. module: note
+#: field:note.note,memo:0
+msgid "Note Content"
+msgstr ""
+
+#. module: note
+#: view:note.stage:0
+msgid "Stages of Notes"
+msgstr ""
+
+#. module: note
+#: model:note.stage,name:note.demo_note_stage_04
+#: model:note.stage,name:note.note_stage_02
+msgid "This Week"
+msgstr ""
+
+#. module: note
+#: model:ir.model,name:note.model_base_config_settings
+msgid "base.config.settings"
+msgstr ""
+
+#. module: note
+#: model:ir.model,name:note.model_note_tag
+msgid "Note Tag"
+msgstr ""
+
+#. module: note
+#: model:res.groups,name:note.group_note_fancy
+msgid "Notes / Fancy mode"
+msgstr ""
+
+#. module: note
+#: model:ir.model,name:note.model_note_note
+#: view:note.note:0
+msgid "Note"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+msgid "Group By..."
+msgstr ""
+
+#. module: note
+#: field:note.note,message_follower_ids:0
+msgid "Followers"
+msgstr ""
+
+#. module: note
+#: model:ir.actions.act_window,help:note.action_note_note
+msgid ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" Click to add a personal note.\n"
+" </p><p>\n"
+" Use notes to organize personal tasks or notes. All\n"
+" notes are private; no one else will be able to see them. "
+"However\n"
+" you can share some notes with other people by inviting "
+"followers\n"
+" on the note. (Useful for meeting minutes, especially if\n"
+" you activate the pad feature for collaborative writings).\n"
+" </p><p>\n"
+" You can customize how you process your notes/tasks by adding,\n"
+" removing or modifying columns.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: note
+#: model:note.stage,name:note.demo_note_stage_01
+#: model:note.stage,name:note.note_stage_01
+msgid "Today"
+msgstr ""
+
+#. module: note
+#: model:ir.model,name:note.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+msgid "í"
+msgstr ""
+
+#. module: note
+#: view:note.stage:0
+msgid "Stage of Notes"
+msgstr ""
+
+#. module: note
+#: field:note.note,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: note
+#: field:note.note,current_partner_id:0
+msgid "unknown"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+msgid "By sticky note Category"
+msgstr ""
+
+#. module: note
+#: help:note.note,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: note
+#: field:note.stage,name:0
+msgid "Stage Name"
+msgstr ""
+
+#. module: note
+#: field:note.note,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: note
+#: model:note.stage,name:note.demo_note_stage_02
+msgid "Tomorrow"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+#: field:note.note,open:0
+msgid "Active"
+msgstr ""
+
+#. module: note
+#: help:note.stage,user_id:0
+msgid "Owner of the note stage."
+msgstr ""
+
+#. module: note
+#: model:ir.ui.menu,name:note.menu_notes_stage
+msgid "Categories"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+#: field:note.note,stage_id:0
+msgid "Stage"
+msgstr ""
+
+#. module: note
+#: field:note.tag,name:0
+msgid "Tag Name"
+msgstr ""
+
+#. module: note
+#: field:note.note,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: note
+#: view:base.config.settings:0
+#: model:ir.actions.act_window,name:note.action_note_note
+#: model:ir.ui.menu,name:note.menu_note_notes
+#: view:note.note:0
+#: model:note.stage,name:note.note_stage_04
+msgid "Notes"
+msgstr ""
+
+#. module: note
+#: model:note.stage,name:note.demo_note_stage_03
+#: model:note.stage,name:note.note_stage_03
+msgid "Later"
+msgstr ""
+
+#. module: note
+#: model:ir.model,name:note.model_note_stage
+msgid "Note Stage"
+msgstr ""
+
+#. module: note
+#: field:note.note,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: note
+#: field:note.note,stage_ids:0
+msgid "Stages of Users"
+msgstr ""
+
+#. module: note
+#: field:note.note,name:0
+msgid "Note Summary"
+msgstr ""
+
+#. module: note
+#: model:ir.actions.act_window,name:note.action_note_stage
+#: view:note.note:0
+msgid "Stages"
+msgstr ""
+
+#. module: note
+#: help:note.note,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+msgid "Delete"
+msgstr ""
+
+#. module: note
+#: field:note.note,color:0
+msgid "Color Index"
+msgstr ""
+
+#. module: note
+#: field:note.note,sequence:0
+#: field:note.stage,sequence:0
+msgid "Sequence"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+#: field:note.note,tag_ids:0
+msgid "Tags"
+msgstr ""
+
+#. module: note
+#: view:note.note:0
+msgid "Archive"
+msgstr ""
+
+#. module: note
+#: field:base.config.settings,module_note_pad:0
+msgid "Use collaborative pads (etherpad)"
+msgstr ""
+
+#. module: note
+#: help:note.note,message_summary:0
+msgid ""
+"Holds the Chatter summary (number of messages, ...). This summary is "
+"directly in html format in order to be inserted in kanban views."
+msgstr ""
+
+#. module: note
+#: field:base.config.settings,group_note_fancy:0
+msgid "Use fancy layouts for notes"
+msgstr ""
+
+#. module: note
+#: field:note.note,current_partner_id:0
+#: field:note.stage,user_id:0
+msgid "Owner"
+msgstr ""
+
+#. module: note
+#: help:note.stage,sequence:0
+msgid "Used to order the note stages"
+msgstr ""
+
+#. module: note
+#: field:note.note,date_done:0
+msgid "Date done"
+msgstr ""
+
+#. module: note
+#: field:note.stage,fold:0
+msgid "Folded by Default"
+msgstr ""
diff --git a/addons/point_of_sale/i18n/zh_CN.po b/addons/point_of_sale/i18n/zh_CN.po
index 23dc97f2376..2dc8e2bb0d0 100644
--- a/addons/point_of_sale/i18n/zh_CN.po
+++ b/addons/point_of_sale/i18n/zh_CN.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-04-24 06:41+0000\n"
-"Last-Translator: viney <Unknown>\n"
+"PO-Revision-Date: 2013-08-06 09:45+0000\n"
+"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n"
-"X-Generator: Launchpad (build 16580)\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
#. module: point_of_sale
#: field:report.transaction.pos,product_nb:0
@@ -42,6 +42,15 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 单击定义一个新的产品类别。\n"
+" </p><p>\n"
+" 产品类别用于通过触摸屏浏览产品。\n"
+" </p><p>\n"
+" "
+"为产品类别上传图片后,触摸屏布局将会自动调整。因此,针对分辨率小于(1024x768)的显示设备,我们建议不要为产品类别上传图片。\n"
+" </p>\n"
+" "
#. module: point_of_sale
#: view:pos.receipt:0
@@ -51,7 +60,7 @@ msgstr "打印销售订单的收据"
#. module: point_of_sale
#: field:pos.session,cash_register_balance_end:0
msgid "Computed Balance"
-msgstr ""
+msgstr "计算余额"
#. module: point_of_sale
#: view:pos.session:0
@@ -62,7 +71,7 @@ msgstr "今天"
#. module: point_of_sale
#: field:pos.config,iface_electronic_scale:0
msgid "Electronic Scale Interface"
-msgstr ""
+msgstr "电子称接口"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.plain_water
@@ -85,7 +94,7 @@ msgstr ""
#: field:pos.config,journal_id:0
#: field:pos.order,sale_journal:0
msgid "Sale Journal"
-msgstr ""
+msgstr "销售日记账"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.spa_2l_product_template
@@ -102,7 +111,7 @@ msgstr "销售详情"
#. module: point_of_sale
#: constraint:pos.config:0
msgid "You cannot have two cash controls in one Point Of Sale !"
-msgstr ""
+msgstr "同一个销售点不能使用两个钱箱"
#. module: point_of_sale
#: field:pos.payment.report.user,user_id:0
@@ -111,7 +120,7 @@ msgstr ""
#: view:report.pos.order:0
#: field:report.pos.order,user_id:0
msgid "Salesperson"
-msgstr ""
+msgstr "销售员"
#. module: point_of_sale
#: view:report.pos.order:0
@@ -128,13 +137,13 @@ msgstr "产品名称"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.pamplemousse_rouge_pamplemousse_product_template
msgid "Red grapefruit"
-msgstr ""
+msgstr "红葡萄柚"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:1343
+#: code:addons/point_of_sale/point_of_sale.py:1373
#, python-format
msgid "Assign a Custom EAN"
-msgstr ""
+msgstr "使用自定义的条码"
#. module: point_of_sale
#: view:pos.session.opening:0
@@ -164,12 +173,12 @@ msgstr "取钱"
#: code:addons/point_of_sale/point_of_sale.py:105
#, python-format
msgid "not used"
-msgstr ""
+msgstr "未被使用"
#. module: point_of_sale
#: field:pos.config,iface_vkeyboard:0
msgid "Virtual KeyBoard Interface"
-msgstr ""
+msgstr "虚拟键盘接口"
#. module: point_of_sale
#. openerp-web
@@ -181,11 +190,11 @@ msgstr "+/-"
#. module: point_of_sale
#: field:pos.ean_wizard,ean13_pattern:0
msgid "Reference"
-msgstr ""
+msgstr "单号"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:1041
-#: code:addons/point_of_sale/point_of_sale.py:1057
+#: code:addons/point_of_sale/point_of_sale.py:1066
+#: code:addons/point_of_sale/point_of_sale.py:1083
#: report:pos.invoice:0
#: report:pos.lines:0
#, python-format
@@ -200,32 +209,32 @@ msgstr "开始日期"
#. module: point_of_sale
#: constraint:pos.session:0
msgid "You cannot create two active sessions with the same responsible!"
-msgstr ""
+msgstr "同一个负责人不能创建两个活动销售会话"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:473
#, python-format
msgid "Weighting"
-msgstr ""
+msgstr "称重"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.fenouil_fenouil_product_template
msgid "Fennel"
-msgstr ""
+msgstr "小茴香"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:472
#, python-format
msgid "Help needed"
-msgstr ""
+msgstr "需要帮助"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:739
+#: code:addons/point_of_sale/point_of_sale.py:760
#, python-format
msgid "Configuration Error!"
-msgstr ""
+msgstr "设置错误!"
#. module: point_of_sale
#: report:account.statement:0
@@ -237,7 +246,7 @@ msgstr "业务伙伴"
#. module: point_of_sale
#: view:pos.session:0
msgid "Closing Cash Control"
-msgstr ""
+msgstr "关闭现金箱"
#. module: point_of_sale
#: report:pos.details:0
@@ -259,7 +268,7 @@ msgstr "会计信息"
#. module: point_of_sale
#: field:pos.session.opening,show_config:0
msgid "Show Config"
-msgstr ""
+msgstr "显示配置"
#. module: point_of_sale
#: report:pos.lines:0
@@ -277,7 +286,7 @@ msgstr "折扣合计"
#: code:addons/point_of_sale/static/src/xml/pos.xml:441
#, python-format
msgid "Debug Window"
-msgstr ""
+msgstr "调试窗口"
#. module: point_of_sale
#. openerp-web
@@ -285,7 +294,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:613
#, python-format
msgid "Change:"
-msgstr "零钞"
+msgstr "找零:"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.coca_regular_2l_product_template
@@ -315,10 +324,10 @@ msgid "Disc.(%)"
msgstr "折扣(%)"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:1006
+#: code:addons/point_of_sale/point_of_sale.py:1031
#, python-format
msgid "Please define income account for this product: \"%s\" (id:%d)."
-msgstr ""
+msgstr "请为这个产品定义收益科目:\"%s\" (id:%d)."
#. module: point_of_sale
#: view:report.pos.order:0
@@ -336,7 +345,7 @@ msgstr "Leffe Brune 33cl"
msgid ""
"Check this if this point of sale should open by default in a self checkout "
"mode. If unchecked, OpenERP uses the normal cashier mode by default."
-msgstr ""
+msgstr "如果需要把自助收银作为默认模式,请选中这里。 如果未选, OpenERP 将使用普通收银员作为默认模式。"
#. module: point_of_sale
#: model:ir.actions.report.xml,name:point_of_sale.pos_sales_user
@@ -353,7 +362,7 @@ msgstr "饮料类"
#: model:ir.actions.act_window,name:point_of_sale.action_pos_session_opening
#: model:ir.ui.menu,name:point_of_sale.menu_pos_session_opening
msgid "Your Session"
-msgstr ""
+msgstr "您的销售会话"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.stella_50cl_product_template
@@ -375,12 +384,12 @@ msgstr "上级类别"
#: code:addons/point_of_sale/static/src/xml/pos.xml:482
#, python-format
msgid "Open Cashbox"
-msgstr ""
+msgstr "打开钱箱"
#. module: point_of_sale
#: view:pos.session.opening:0
msgid "Select your Point of Sale"
-msgstr ""
+msgstr "选择您的销售点"
#. module: point_of_sale
#: field:report.sales.by.margin.pos,total:0
@@ -404,25 +413,25 @@ msgstr "Dr. Oetker Ristorante Speciale"
#: code:addons/point_of_sale/static/src/xml/pos.xml:480
#, python-format
msgid "Payment Request"
-msgstr ""
+msgstr "付款请求"
#. module: point_of_sale
#: field:product.product,to_weight:0
msgid "To Weight"
-msgstr ""
+msgstr "需要称重"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:476
#, python-format
msgid "Hardware Events"
-msgstr ""
+msgstr "硬件事件"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:301
#, python-format
msgid "You should assign a Point of Sale to your session."
-msgstr ""
+msgstr "您需要为您的销售会话指定一个销售点"
#. module: point_of_sale
#: view:pos.order.line:0
@@ -435,7 +444,7 @@ msgid "Fanta Orange 33cl"
msgstr "Fanta Orange 33cl"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:420
+#: code:addons/point_of_sale/point_of_sale.py:423
#, python-format
msgid ""
"Please set your profit and loss accounts on your payment method '%s'. This "
@@ -446,10 +455,10 @@ msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:315
-#: code:addons/point_of_sale/point_of_sale.py:512
+#: code:addons/point_of_sale/point_of_sale.py:514
#, python-format
msgid "error!"
-msgstr ""
+msgstr "错误!"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_report_sales_by_user_pos_month
@@ -471,12 +480,12 @@ msgstr ""
#. module: point_of_sale
#: model:product.template,name:point_of_sale.Onions_product_template
msgid "Onions"
-msgstr ""
+msgstr "洋葱"
#. module: point_of_sale
#: view:pos.session:0
msgid "Validate & Open Session"
-msgstr ""
+msgstr "验证并打开销售会话"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:99
@@ -484,18 +493,18 @@ msgstr ""
#: selection:pos.session.opening,pos_state:0
#, python-format
msgid "In Progress"
-msgstr ""
+msgstr "进行中"
#. module: point_of_sale
#: view:pos.session:0
#: field:pos.session,opening_details_ids:0
msgid "Opening Cash Control"
-msgstr ""
+msgstr "正在打开钱箱"
#. module: point_of_sale
#: help:res.users,ean13:0
msgid "BarCode"
-msgstr ""
+msgstr "条码"
#. module: point_of_sale
#: help:pos.category,image_medium:0
@@ -508,19 +517,19 @@ msgstr ""
#. module: point_of_sale
#: view:pos.session.opening:0
msgid "Open Session"
-msgstr ""
+msgstr "打开销售会话"
#. module: point_of_sale
#: model:ir.ui.menu,name:point_of_sale.menu_point_of_sale
msgid "Daily Operations"
-msgstr "每天经营"
+msgstr "日常经营"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:42
#, python-format
msgid "Google Chrome"
-msgstr ""
+msgstr "Google Chrome"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.sparkling_water
@@ -543,7 +552,7 @@ msgstr "查询现金对账单"
#: field:pos.session.opening,pos_state_str:0
#: field:report.pos.order,state:0
msgid "Status"
-msgstr ""
+msgstr "状态"
#. module: point_of_sale
#: selection:report.pos.order,month:0
@@ -568,14 +577,14 @@ msgstr "POS单明细"
#. module: point_of_sale
#: view:pos.config:0
msgid "Point of Sale Configuration"
-msgstr ""
+msgstr "销售点配置"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:359
#, python-format
msgid "Your order has to be validated by a cashier."
-msgstr ""
+msgstr "您的订单已被收银员确认"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.fanta_orange_50cl_product_template
@@ -609,7 +618,7 @@ msgid ""
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:867
+#: code:addons/point_of_sale/point_of_sale.py:888
#, python-format
msgid "Customer Invoice"
msgstr "客户发票"
@@ -619,7 +628,7 @@ msgstr "客户发票"
msgid ""
"You can continue sales from the touchscreen interface by clicking on \"Start "
"Selling\" or close the cash register session."
-msgstr ""
+msgstr "通过触摸屏幕的“开始销售”或者关闭钱箱之后您就可以继续进行销售。"
#. module: point_of_sale
#: report:account.statement:0
@@ -631,7 +640,7 @@ msgstr "结束日期"
#. module: point_of_sale
#: view:pos.session:0
msgid "Opening Cashbox Lines"
-msgstr ""
+msgstr "正在打开钱箱"
#. module: point_of_sale
#: selection:report.pos.order,month:0
@@ -678,7 +687,7 @@ msgstr "行号"
#: code:addons/point_of_sale/static/src/xml/pos.xml:453
#, python-format
msgid "Set Weight"
-msgstr ""
+msgstr "设置重量"
#. module: point_of_sale
#: view:account.bank.statement:0
@@ -693,7 +702,7 @@ msgstr "净合计:"
#. module: point_of_sale
#: model:ir.actions.client,name:point_of_sale.action_client_pos_menu
msgid "Open POS Menu"
-msgstr ""
+msgstr "打开销售点菜单"
#. module: point_of_sale
#: report:pos.details_summary:0
@@ -710,12 +719,12 @@ msgstr "发表POS机日记帐分录"
#: code:addons/point_of_sale/static/src/xml/pos.xml:457
#, python-format
msgid "Barcode Scanner"
-msgstr ""
+msgstr "条码扫描器"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.pomme_granny_smith_product_template
msgid "Granny Smith apples"
-msgstr ""
+msgstr "Granny Smith 苹果"
#. module: point_of_sale
#: help:product.product,expense_pdt:0
@@ -739,11 +748,13 @@ msgid ""
"use\n"
" a modern browser like"
msgstr ""
+"销售点功能不支持 Microsoft Internet Explorer 浏览器,请使用更现代化的浏览器如:Mozilla Firefox 和 "
+"Google Chrome 等"
#. module: point_of_sale
#: view:pos.session.opening:0
msgid "Click to start a session."
-msgstr ""
+msgstr "单击开始销售会话"
#. module: point_of_sale
#: view:pos.details:0
@@ -778,7 +789,7 @@ msgstr "新增产品"
#. module: point_of_sale
#: field:pos.config,name:0
msgid "Point of Sale Name"
-msgstr ""
+msgstr "销售点名称"
#. module: point_of_sale
#: field:report.transaction.pos,invoice_am:0
@@ -825,7 +836,7 @@ msgstr "期末结余"
#: code:addons/point_of_sale/wizard/pos_box_out.py:89
#, python-format
msgid "please check that account is set to %s."
-msgstr ""
+msgstr "请检查该科目已经设为为:%s"
#. module: point_of_sale
#: help:pos.category,image:0
@@ -863,7 +874,7 @@ msgstr ""
#. module: point_of_sale
#: view:pos.ean_wizard:0
msgid "Ean13 Generator"
-msgstr ""
+msgstr "条码生成器"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.spa_1l_product_template
@@ -879,7 +890,7 @@ msgstr "错误:无效的EAN编码"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.legumes_racine
msgid "Root vegetables"
-msgstr ""
+msgstr "根类蔬菜"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.act_pos_open_statement
@@ -934,12 +945,12 @@ msgstr "付款合计"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_pos_session_opening
msgid "pos.session.opening"
-msgstr ""
+msgstr "pos.session.opening"
#. module: point_of_sale
#: view:res.users:0
msgid "Edit EAN"
-msgstr ""
+msgstr "编辑条码"
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_open_statement.py:80
@@ -965,7 +976,7 @@ msgstr ""
#. module: point_of_sale
#: field:pos.session.opening,pos_session_id:0
msgid "PoS Session"
-msgstr ""
+msgstr "销售点会话"
#. module: point_of_sale
#: selection:report.pos.order,month:0
@@ -979,7 +990,7 @@ msgid "User's Product"
msgstr "用户的产品"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:1143
+#: code:addons/point_of_sale/point_of_sale.py:1173
#, python-format
msgid ""
"You have to select a pricelist in the sale form !\n"
@@ -1011,7 +1022,7 @@ msgstr "增加一个全局折扣"
#. module: point_of_sale
#: view:pos.config:0
msgid "Journals"
-msgstr ""
+msgstr "日记账"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.oetker_prosciutto_product_template
@@ -1031,7 +1042,7 @@ msgstr "Coca-Cola Light Lemon 50cl"
#. module: point_of_sale
#. openerp-web
-#: code:addons/point_of_sale/point_of_sale.py:518
+#: code:addons/point_of_sale/point_of_sale.py:520
#: code:addons/point_of_sale/static/src/xml/pos.xml:689
#: code:addons/point_of_sale/static/src/xml/pos.xml:744
#, python-format
@@ -1041,7 +1052,7 @@ msgstr ""
#. module: point_of_sale
#: view:product.product:0
msgid "Set a Custom EAN"
-msgstr ""
+msgstr "设置自定义条码"
#. module: point_of_sale
#. openerp-web
@@ -1053,7 +1064,7 @@ msgstr ""
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.legumes
msgid "Fresh vegetables"
-msgstr ""
+msgstr "新鲜蔬菜"
#. module: point_of_sale
#: view:pos.session:0
@@ -1065,7 +1076,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:478
#, python-format
msgid "Scan Item Success"
-msgstr ""
+msgstr "扫描条目成功"
#. module: point_of_sale
#: report:account.statement:0
@@ -1077,22 +1088,22 @@ msgstr "期初余额"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.lays_naturel_oven_150g_product_template
msgid "Oven Baked Lays Natural 150g"
-msgstr ""
+msgstr "Oven Baked Lays Natural 150g"
#. module: point_of_sale
#: sql_constraint:pos.session:0
msgid "The name of this POS Session must be unique !"
-msgstr ""
+msgstr "销售会话名称必须唯一"
#. module: point_of_sale
#: view:pos.session:0
msgid "Opening Subtotal"
-msgstr ""
+msgstr "小计"
#. module: point_of_sale
#: view:pos.session:0
msgid "payment method."
-msgstr ""
+msgstr "付款方式"
#. module: point_of_sale
#: view:pos.order:0
@@ -1137,12 +1148,12 @@ msgstr "折扣"
#. module: point_of_sale
#: view:pos.order:0
msgid "(update)"
-msgstr ""
+msgstr "(更新)"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.ijsboerke_vanille_2,5l_product_template
msgid "IJsboerke Vanilla 2.5L"
-msgstr ""
+msgstr "IJsboerke Vanilla 2.5L"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_report_pos_details
@@ -1153,15 +1164,15 @@ msgstr "销售详情"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.evian_2l_product_template
msgid "2L Evian"
-msgstr ""
+msgstr "2L 依云"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:373
-#: code:addons/point_of_sale/point_of_sale.py:472
-#: code:addons/point_of_sale/wizard/pos_session_opening.py:34
+#: code:addons/point_of_sale/point_of_sale.py:474
+#: code:addons/point_of_sale/wizard/pos_session_opening.py:33
#, python-format
msgid "Start Point Of Sale"
-msgstr ""
+msgstr "启动销售点"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.pils
@@ -1215,14 +1226,14 @@ msgstr "Chaudfontaine Petillante 50cl"
#: code:addons/point_of_sale/static/src/xml/pos.xml:485
#, python-format
msgid "Read Weighting Scale"
-msgstr ""
+msgstr "读取电子秤"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:426
#, python-format
msgid "0.00 €"
-msgstr ""
+msgstr "0.00 €"
#. module: point_of_sale
#: field:pos.order.line,create_date:0
@@ -1240,7 +1251,7 @@ msgstr "今天的销售情况"
#: code:addons/point_of_sale/static/src/xml/pos.xml:324
#, python-format
msgid "Welcome"
-msgstr ""
+msgstr "欢迎"
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_box_entries.py:46
@@ -1295,7 +1306,7 @@ msgstr "已开票合计"
#: model:ir.model,name:point_of_sale.model_pos_category
#: field:product.product,pos_categ_id:0
msgid "Point of Sale Category"
-msgstr ""
+msgstr "销售点商品分类"
#. module: point_of_sale
#: view:report.pos.order:0
@@ -1315,7 +1326,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:324
#, python-format
msgid "Choose your type of receipt:"
-msgstr ""
+msgstr "选择小票类型"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_report_sales_by_margin_pos_month
@@ -1352,7 +1363,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:479
#, python-format
msgid "Scan Item Unrecognized"
-msgstr ""
+msgstr "未能识别扫描的条目"
#. module: point_of_sale
#: report:all.closed.cashbox.of.the.day:0
@@ -1360,7 +1371,7 @@ msgid "Today's Closed Cashbox"
msgstr "今日关闭的钱箱"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:897
+#: code:addons/point_of_sale/point_of_sale.py:920
#, python-format
msgid "Selected orders do not have the same session!"
msgstr ""
@@ -1396,7 +1407,7 @@ msgstr "开启日期"
#: model:ir.actions.act_window,name:point_of_sale.action_pos_session
#: model:ir.ui.menu,name:point_of_sale.menu_pos_session_all
msgid "All Sessions"
-msgstr ""
+msgstr "全部销售会话"
#. module: point_of_sale
#. openerp-web
@@ -1415,7 +1426,7 @@ msgstr "税:"
#: code:addons/point_of_sale/static/src/xml/pos.xml:271
#, python-format
msgid "Thank you for shopping with us."
-msgstr ""
+msgstr "感谢您的光临。"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.coca_light_2l_product_template
@@ -1431,7 +1442,7 @@ msgstr "Dr. Oetker Ristorante Funghi"
#: model:ir.actions.act_window,name:point_of_sale.pos_category_action
#: model:ir.ui.menu,name:point_of_sale.menu_pos_category
msgid "Product Categories"
-msgstr ""
+msgstr "商品类别"
#. module: point_of_sale
#: help:pos.config,journal_id:0
@@ -1448,7 +1459,7 @@ msgstr "折扣"
#: code:addons/point_of_sale/static/src/xml/pos.xml:467
#, python-format
msgid "Invalid Ean"
-msgstr ""
+msgstr "无效的条码"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.lindemans_kriek_37,5cl_product_template
@@ -1458,7 +1469,7 @@ msgstr "Lindemans Kriek 37.5cl"
#. module: point_of_sale
#: view:pos.config:0
msgid "Point of Sale Config"
-msgstr ""
+msgstr "销售点配置"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.coca_zero_33cl_product_template
@@ -1511,7 +1522,7 @@ msgstr "税:"
#. module: point_of_sale
#: view:pos.session:0
msgid "+ Transactions"
-msgstr ""
+msgstr "+ 交易"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_pos_discount
@@ -1541,12 +1552,12 @@ msgstr "用户"
#: code:addons/point_of_sale/static/src/xml/pos.xml:194
#, python-format
msgid "Kg"
-msgstr ""
+msgstr "千克"
#. module: point_of_sale
#: field:product.product,available_in_pos:0
msgid "Available in the Point of Sale"
-msgstr ""
+msgstr "可在销售点销售"
#. module: point_of_sale
#: selection:pos.config,state:0
@@ -1563,7 +1574,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:338
#, python-format
msgid "The scanned product was not recognized"
-msgstr ""
+msgstr "无法识别扫描的商品"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_report_transaction_pos
@@ -1613,7 +1624,7 @@ msgstr "11月"
#: code:addons/point_of_sale/static/src/xml/pos.xml:267
#, python-format
msgid "Please scan an item or your member card"
-msgstr ""
+msgstr "请扫描商品或您的会员卡"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.poivron_verts_product_template
@@ -1644,7 +1655,7 @@ msgid "Number of Transaction"
msgstr "交易数"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:738
+#: code:addons/point_of_sale/point_of_sale.py:759
#, python-format
msgid ""
"There is no receivable account defined to make payment for the partner: "
@@ -1655,7 +1666,7 @@ msgstr ""
#: view:pos.config:0
#: selection:pos.config,state:0
msgid "Inactive"
-msgstr ""
+msgstr "不活跃的"
#. module: point_of_sale
#. openerp-web
@@ -1679,7 +1690,7 @@ msgstr "取消"
#: code:addons/point_of_sale/static/src/xml/pos.xml:296
#, python-format
msgid "Please put your product on the scale"
-msgstr ""
+msgstr "请将商品放到称上"
#. module: point_of_sale
#: model:ir.actions.report.xml,name:point_of_sale.pos_details_summary
@@ -1699,7 +1710,7 @@ msgstr "Timmermans Kriek 37.5cl"
#. module: point_of_sale
#: field:pos.config,sequence_id:0
msgid "Order IDs Sequence"
-msgstr ""
+msgstr "订单号序列"
#. module: point_of_sale
#: report:pos.invoice:0
@@ -1815,7 +1826,7 @@ msgid "Difference"
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:529
+#: code:addons/point_of_sale/point_of_sale.py:549
#, python-format
msgid "Unable to Delete !"
msgstr "不能删除!"
@@ -1978,7 +1989,7 @@ msgid "Salespeople"
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:756
+#: code:addons/point_of_sale/point_of_sale.py:777
#: code:addons/point_of_sale/wizard/pos_box_entries.py:118
#: code:addons/point_of_sale/wizard/pos_box_out.py:91
#, python-format
@@ -1986,7 +1997,7 @@ msgid "You have to open at least one cashbox."
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:1142
+#: code:addons/point_of_sale/point_of_sale.py:1172
#, python-format
msgid "No Pricelist !"
msgstr "没有价格表!"
@@ -2038,7 +2049,7 @@ msgid "No Cash Register Defined !"
msgstr "没有定义收银机"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:513
+#: code:addons/point_of_sale/point_of_sale.py:515
#, python-format
msgid ""
"No cash statement found for this session. Unable to record returned cash."
@@ -2761,7 +2772,7 @@ msgid "Pos Lines"
msgstr "销售单明细"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:413
+#: code:addons/point_of_sale/point_of_sale.py:416
#, python-format
msgid "Point of Sale Profit"
msgstr ""
@@ -2774,7 +2785,7 @@ msgid "Please wait, a cashier is on the way"
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/wizard/pos_session_opening.py:68
+#: code:addons/point_of_sale/wizard/pos_session_opening.py:67
#: field:pos.box.entries,session_id:0
#: view:pos.order:0
#: field:pos.order,session_id:0
@@ -3085,15 +3096,17 @@ msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:300
#: code:addons/point_of_sale/point_of_sale.py:409
-#: code:addons/point_of_sale/point_of_sale.py:419
-#: code:addons/point_of_sale/point_of_sale.py:457
-#: code:addons/point_of_sale/point_of_sale.py:712
-#: code:addons/point_of_sale/point_of_sale.py:756
-#: code:addons/point_of_sale/point_of_sale.py:818
-#: code:addons/point_of_sale/point_of_sale.py:897
-#: code:addons/point_of_sale/point_of_sale.py:1006
+#: code:addons/point_of_sale/point_of_sale.py:412
+#: code:addons/point_of_sale/point_of_sale.py:422
+#: code:addons/point_of_sale/point_of_sale.py:459
+#: code:addons/point_of_sale/point_of_sale.py:536
+#: code:addons/point_of_sale/point_of_sale.py:733
+#: code:addons/point_of_sale/point_of_sale.py:777
+#: code:addons/point_of_sale/point_of_sale.py:839
+#: code:addons/point_of_sale/point_of_sale.py:920
+#: code:addons/point_of_sale/point_of_sale.py:1031
#: code:addons/point_of_sale/report/pos_invoice.py:46
-#: code:addons/point_of_sale/wizard/pos_box.py:23
+#: code:addons/point_of_sale/wizard/pos_box.py:22
#: code:addons/point_of_sale/wizard/pos_box_entries.py:46
#: code:addons/point_of_sale/wizard/pos_box_entries.py:118
#: code:addons/point_of_sale/wizard/pos_box_entries.py:123
@@ -3187,13 +3200,13 @@ msgid "Chaudfontaine 1.5l"
msgstr "Chaudfontaine 1.5l"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:1069
+#: code:addons/point_of_sale/point_of_sale.py:1096
#, python-format
msgid "Trade Receivables"
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:529
+#: code:addons/point_of_sale/point_of_sale.py:549
#, python-format
msgid "In order to delete a sale, it must be new or cancelled."
msgstr "只有新的或被取消的销售流水可以删除"
@@ -3228,7 +3241,7 @@ msgid "Journal Entry"
msgstr "日记账簿"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:736
+#: code:addons/point_of_sale/point_of_sale.py:757
#, python-format
msgid "There is no receivable account defined to make payment."
msgstr ""
@@ -3259,7 +3272,7 @@ msgid "Supplier Invoice"
msgstr "供应商发票"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:458
+#: code:addons/point_of_sale/point_of_sale.py:460
#, python-format
msgid ""
"You cannot confirm all orders of this session, because they have not the "
@@ -3338,7 +3351,7 @@ msgid "Coca-Cola Regular 1L"
msgstr "Coca-Cola Regular 1L"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:712
+#: code:addons/point_of_sale/point_of_sale.py:733
#, python-format
msgid "Unable to cancel the picking."
msgstr "无法取消发货"
@@ -3379,7 +3392,7 @@ msgid "Spa Barisart 1.5l"
msgstr "Spa Barisart 1.5l"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:789
+#: code:addons/point_of_sale/point_of_sale.py:810
#: view:pos.order:0
#, python-format
msgid "Return Products"
@@ -3418,7 +3431,7 @@ msgstr "销售明细"
#: view:res.partner:0
#: view:res.users:0
msgid "Point of Sale"
-msgstr "POS"
+msgstr "销售点"
#. module: point_of_sale
#: view:pos.order:0
@@ -3495,7 +3508,7 @@ msgid "Default Point of Sale"
msgstr ""
#. module: point_of_sale
-#: code:addons/point_of_sale/wizard/pos_box.py:24
+#: code:addons/point_of_sale/wizard/pos_box.py:23
#, python-format
msgid "There is no cash register for this PoS Session"
msgstr ""
@@ -3539,7 +3552,7 @@ msgid "PRO-FORMA"
msgstr "形式发票"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:818
+#: code:addons/point_of_sale/point_of_sale.py:839
#, python-format
msgid "Please provide a partner for the sale."
msgstr "请提供业务伙伴。"
@@ -3591,7 +3604,7 @@ msgid "Print Receipt"
msgstr "打印收银条"
#. module: point_of_sale
-#: code:addons/point_of_sale/point_of_sale.py:417
+#: code:addons/point_of_sale/point_of_sale.py:420
#, python-format
msgid "Point of Sale Loss"
msgstr ""
@@ -4020,6 +4033,7 @@ msgstr ""
#~ msgid "Discount percentage"
#~ msgstr "折扣百分比"
+#, python-format
#~ msgid "Close"
#~ msgstr "关闭"
@@ -4843,9 +4857,11 @@ msgstr ""
#~ msgid "Subtotal:"
#~ msgstr "小计:"
+#, python-format
#~ msgid "Validate"
#~ msgstr "确认"
+#, python-format
#~ msgid "Print"
#~ msgstr "打印"
@@ -4931,6 +4947,7 @@ msgstr ""
#~ msgid "PoS Backend"
#~ msgstr "POS后端"
+#, python-format
#~ msgid "Next Order"
#~ msgstr "下一订单"
diff --git a/addons/portal_crm/i18n/bs.po b/addons/portal_crm/i18n/bs.po
new file mode 100644
index 00000000000..0e91dd772da
--- /dev/null
+++ b/addons/portal_crm/i18n/bs.po
@@ -0,0 +1,546 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-08-06 08:35+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,type:0
+msgid "Lead"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,title:0
+msgid "Title"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,probability:0
+msgid "Success Rate (%)"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Contact us"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_action:0
+msgid "Next Action Date"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,fax:0
+msgid "Fax"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,zip:0
+msgid "Zip"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,day_open:0
+msgid "Days to Open"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Thank you for your interest, we'll respond to your request shortly."
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,priority:0
+msgid "Highest"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,mobile:0
+msgid "Mobile"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,description:0
+msgid "Notes"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,color:0
+msgid "Color Index"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_latitude:0
+msgid "Geo Latitude"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_name:0
+msgid "Customer Name"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,channel_id:0
+msgid "Communication channel (mail, direct, phone, ...)"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,type_id:0
+msgid "Campaign"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,ref:0
+msgid "Reference"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_action_next:0
+#: field:portal_crm.crm_contact_us,title_action:0
+msgid "Next Action"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,message_summary:0
+msgid ""
+"Holds the Chatter summary (number of messages, ...). This summary is "
+"directly in html format in order to be inserted in kanban views."
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_id:0
+msgid "Partner"
+msgstr ""
+
+#. module: portal_crm
+#: model:ir.actions.act_window,name:portal_crm.action_contact_us
+msgid "Contact Us"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,name:0
+msgid "Subject"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,opt_out:0
+msgid "Opt-Out"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,priority:0
+msgid "Priority"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,state_id:0
+msgid "State"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,message_follower_ids:0
+msgid "Followers"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,partner_id:0
+msgid "Linked partner (optional). Usually created when converting the lead."
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,payment_mode:0
+msgid "Payment Mode"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,state:0
+msgid "New"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,type:0
+msgid "Type"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,email_from:0
+msgid "Email"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,channel_id:0
+msgid "Channel"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Name"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,priority:0
+msgid "Lowest"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,create_date:0
+msgid "Creation Date"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Close"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,state:0
+msgid "Pending"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,type:0
+msgid "Type is used to separate Leads and Opportunities"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,categ_ids:0
+msgid "Categories"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,stage_id:0
+msgid "Stage"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,user_login:0
+msgid "User Login"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,opt_out:0
+msgid ""
+"If opt-out is checked, this contact has refused to receive emails or "
+"unsubscribed to a campaign."
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,contact_name:0
+msgid "Contact Name"
+msgstr ""
+
+#. module: portal_crm
+#: model:ir.ui.menu,name:portal_crm.portal_company_contact
+msgid "Contact"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_address_email:0
+msgid "Partner Contact Email"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,planned_revenue:0
+msgid "Expected Revenue"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,task_ids:0
+msgid "Tasks"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Contact form"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,company_currency:0
+msgid "Currency"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,write_date:0
+msgid "Update Date"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_deadline:0
+msgid "Expected Closing"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,ref2:0
+msgid "Reference 2"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,user_email:0
+msgid "User Email"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_open:0
+msgid "Opened"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,state:0
+msgid "In Progress"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,partner_name:0
+msgid ""
+"The name of the future partner company that will be created while converting "
+"the lead into opportunity"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,planned_cost:0
+msgid "Planned Costs"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,date_deadline:0
+msgid "Estimate of the date on which the opportunity will be won."
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,email_cc:0
+msgid ""
+"These email addresses will be added to the CC field of all inbound and "
+"outbound emails for this record before being sent. Separate multiple email "
+"addresses with a comma"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,priority:0
+msgid "Low"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_closed:0
+#: selection:portal_crm.crm_contact_us,state:0
+msgid "Closed"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_assign:0
+msgid "Assignation Date"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,state:0
+msgid "Status"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,priority:0
+msgid "Normal"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,email_cc:0
+msgid "Global CC"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,street2:0
+msgid "Street2"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,id:0
+msgid "ID"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,phone:0
+msgid "Phone"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,active:0
+msgid "Active"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,user_id:0
+msgid "Salesperson"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,day_close:0
+msgid "Days to Close"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,company_ids:0
+msgid "Companies"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,section_id:0
+msgid ""
+"When sending mails, the default email address is taken from the sales team."
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_address_name:0
+msgid "Partner Contact Name"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_longitude:0
+msgid "Geo Longitude"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,date_assign:0
+msgid "Last date this case was forwarded/assigned to a partner"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,email_from:0
+msgid "Email address of the contact"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,city:0
+msgid "City"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Submit"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,function:0
+msgid "Function"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,referred:0
+msgid "Referred By"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,partner_assigned_id:0
+msgid "Assigned Partner"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,type:0
+msgid "Opportunity"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,partner_assigned_id:0
+msgid "Partner this case has been forwarded/assigned to."
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,country_id:0
+msgid "Country"
+msgstr ""
+
+#. module: portal_crm
+#: view:portal_crm.crm_contact_us:0
+msgid "Thank you"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,state:0
+msgid ""
+"The Status is set to 'Draft', when a case is created. If the case is in "
+"progress the Status is set to 'Open'. When the case is over, the Status is "
+"set to 'Done'. If the case needs to be reviewed then the Status is set to "
+"'Pending'."
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: portal_crm
+#: help:portal_crm.crm_contact_us,type_id:0
+msgid ""
+"From which campaign (seminar, marketing campaign, mass mailing, ...) did "
+"this contact come from?"
+msgstr ""
+
+#. module: portal_crm
+#: selection:portal_crm.crm_contact_us,priority:0
+msgid "High"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,section_id:0
+msgid "Sales Team"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,street:0
+msgid "Street"
+msgstr ""
+
+#. module: portal_crm
+#: field:portal_crm.crm_contact_us,date_action_last:0
+msgid "Last Action"
+msgstr ""
+
+#. module: portal_crm
+#: model:ir.model,name:portal_crm.model_portal_crm_crm_contact_us
+msgid "Contact form for the portal"
+msgstr ""
diff --git a/addons/product/i18n/zh_CN.po b/addons/product/i18n/zh_CN.po
index bd28e914c5e..470e1c0632b 100644
--- a/addons/product/i18n/zh_CN.po
+++ b/addons/product/i18n/zh_CN.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:06+0000\n"
-"PO-Revision-Date: 2012-11-27 09:28+0000\n"
-"Last-Translator: 盈通 ccdos <ccdos@163.com>\n"
+"PO-Revision-Date: 2013-07-28 11:18+0000\n"
+"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:25+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-07-29 05:25+0000\n"
+"X-Generator: Launchpad (build 16700)\n"
#. module: product
#: field:product.packaging,rows:0
@@ -513,7 +513,7 @@ msgstr "标准耳机"
#. module: product
#: model:product.uom,name:product.product_uom_day
msgid "Day(s)"
-msgstr ""
+msgstr "天"
#. module: product
#: help:product.product,incoming_qty:0
@@ -800,7 +800,7 @@ msgstr "结束日期"
#. module: product
#: model:product.uom,name:product.product_uom_litre
msgid "Liter(s)"
-msgstr ""
+msgstr "升"
#. module: product
#: view:product.price_list:0
@@ -843,7 +843,7 @@ msgstr "价格表"
#. module: product
#: model:product.uom,name:product.product_uom_hour
msgid "Hour(s)"
-msgstr ""
+msgstr "小时"
#. module: product
#: selection:product.template,state:0
@@ -1114,7 +1114,7 @@ msgstr "右父项"
#. module: product
#: field:product.product,price:0
msgid "Price"
-msgstr ""
+msgstr "价格"
#. module: product
#: field:product.pricelist.item,price_surcharge:0
@@ -1192,7 +1192,7 @@ msgstr "显示产品列表的顺序号"
#. module: product
#: model:product.uom,name:product.product_uom_dozen
msgid "Dozen(s)"
-msgstr ""
+msgstr "打"
#. module: product
#: field:product.uom,factor:0
@@ -1338,7 +1338,7 @@ msgstr "指定一个产品分类 ,规则只被应用在与这个分类以及å®
#. module: product
#: view:product.product:0
msgid "Inventory"
-msgstr "盘点"
+msgstr "库存"
#. module: product
#: field:product.product,seller_info_id:0
@@ -1346,7 +1346,7 @@ msgid "Supplier Info"
msgstr "供应商信息"
#. module: product
-#: code:addons/product/product.py:729
+#: code:addons/product/product.py:732
#, python-format
msgid "%s (copy)"
msgstr "%s (副本)"
@@ -1891,7 +1891,7 @@ msgstr "消息"
#. module: product
#: model:product.uom,name:product.product_uom_unit
msgid "Unit(s)"
-msgstr ""
+msgstr "件"
#. module: product
#: code:addons/product/product.py:176
@@ -2341,7 +2341,7 @@ msgstr "序列"
msgid ""
"Average delay in days to produce this product. In the case of multi-level "
"BOM, the manufacturing lead times of the components will be added."
-msgstr ""
+msgstr "生成该产品的平均延时天数。在多级BoM的情况下,部件的制造提前期将被累加"
#. module: product
#: model:product.template,name:product.product_assembly_product_template
@@ -2364,6 +2364,8 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"单击以创建一个新的计量单位\n"
+" "
#. module: product
#: model:product.template,name:product.product_product_11_product_template
@@ -2444,7 +2446,7 @@ msgid "15” LCD Monitor"
msgstr "15” LCD 显示器"
#. module: product
-#: code:addons/product/pricelist.py:376
+#: code:addons/product/pricelist.py:379
#: field:product.pricelist.item,base_pricelist_id:0
#, python-format
msgid "Other Pricelist"
diff --git a/addons/project/i18n/zh_CN.po b/addons/project/i18n/zh_CN.po
index 8d5f0a04018..2bb41d21e16 100644
--- a/addons/project/i18n/zh_CN.po
+++ b/addons/project/i18n/zh_CN.po
@@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-07-14 04:15+0000\n"
-"Last-Translator: Alan <shuchuan.wu@gmail.com>\n"
+"PO-Revision-Date: 2013-08-13 04:04+0000\n"
+"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-07-15 04:51+0000\n"
-"X-Generator: Launchpad (build 16696)\n"
+"X-Launchpad-Export-Date: 2013-08-13 05:00+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
#. module: project
#: view:project.project:0
msgid "Email Interface"
-msgstr "Email 接口"
+msgstr "电子邮件接口"
#. module: project
#: help:account.analytic.account,use_tasks:0
@@ -69,7 +69,7 @@ msgstr "基于该模板新建项目"
#: view:report.project.task.user:0
#: field:report.project.task.user,day:0
msgid "Day"
-msgstr "天"
+msgstr "日"
#. module: project
#: model:project.task.type,name:project.project_tt_merge
@@ -749,7 +749,7 @@ msgstr "待处理任务草稿"
#. module: project
#: field:project.project,alias_model:0
msgid "Alias Model"
-msgstr ""
+msgstr "别名模型"
#. module: project
#: help:report.project.task.user,closing_days:0
@@ -854,7 +854,7 @@ msgstr "增加筛选条件"
#. module: project
#: model:ir.ui.menu,name:project.menu_tasks_config
msgid "GTD"
-msgstr ""
+msgstr "GTD"
#. module: project
#: help:project.task,state:0
@@ -1214,7 +1214,7 @@ msgstr "%s (副本)"
#. module: project
#: model:mail.message.subtype,name:project.mt_project_task_stage
msgid "Task Stage Changed"
-msgstr ""
+msgstr "任务阶段已改变"
#. module: project
#: view:project.task:0
@@ -1706,6 +1706,12 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 单击创建新任务。\n"
+" </p><p>\n"
+"OpenERP 系统的任务管理允许你为了更高效地完成工作而管理任务管道。你可以跟踪任务进度、与他人讨论任务、附加文档附件等。\n"
+" </p>\n"
+" "
#. module: project
#: field:project.task,date_end:0
@@ -2013,7 +2019,7 @@ msgstr "准备好下一个阶段"
#. module: project
#: field:project.task.type,case_default:0
msgid "Default for New Projects"
-msgstr ""
+msgstr "默认用于新项目"
#. module: project
#: view:project.task:0
@@ -2051,6 +2057,8 @@ msgid ""
"resource allocation.\n"
" This installs the module project_long_term."
msgstr ""
+"用于长期项目管理的模块,能够跟踪计划、排程和资源控制。\n"
+" 将会安装模块“project_long_term”。"
#. module: project
#: model:mail.message.subtype,description:project.mt_task_closed
@@ -2083,6 +2091,8 @@ msgid ""
"Provides timesheet support for the issues/bugs management in project.\n"
" This installs the module project_issue_sheet."
msgstr ""
+"为项目中的问题/错误管理提供时间表支持。\n"
+" 将安装模块“project_issue_sheet”。"
#. module: project
#: selection:project.project,privacy_visibility:0
diff --git a/addons/project/project.py b/addons/project/project.py
index d09e3476a96..105fcd27d76 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -560,7 +560,6 @@ class task(osv.osv):
}
def _get_default_partner(self, cr, uid, context=None):
- """ Override of base_stage to add project specific behavior """
project_id = self._get_default_project_id(cr, uid, context)
if project_id:
project = self.pool.get('project.project').browse(cr, uid, project_id, context=context)
diff --git a/addons/project_issue/i18n/bs.po b/addons/project_issue/i18n/bs.po
new file mode 100644
index 00000000000..db49b0c586c
--- /dev/null
+++ b/addons/project_issue/i18n/bs.po
@@ -0,0 +1,984 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-08-06 17:46+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
+
+#. module: project_issue
+#: model:project.category,name:project_issue.project_issue_category_03
+msgid "Deadly bug"
+msgstr "Ubojita greška"
+
+#. module: project_issue
+#: help:project.config.settings,fetchmail_issue:0
+msgid ""
+"Allows you to configure your incoming mail server, and create issues from "
+"incoming emails."
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,delay_open:0
+msgid "Avg. Delay to Open"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: view:project.issue.report:0
+msgid "Group By..."
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,working_hours_open:0
+msgid "Working Hours to Open the Issue"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,description:project_issue.mt_issue_started
+msgid "Issue started"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,date_open:0
+msgid "Opened"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,opening_date:0
+msgid "Date of Opening"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "March"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,progress:0
+msgid "Progress (%)"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,company_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,email_cc:0
+msgid "Watchers Emails"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,kanban_state:0
+msgid ""
+"A Issue's kanban state indicates special situations affecting it:\n"
+" * Normal is the default situation\n"
+" * Blocked indicates something is preventing the progress of this issue\n"
+" * Ready for next stage indicates the issue is ready to be pulled to the "
+"next stage"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: project_issue
+#: help:account.analytic.account,use_issues:0
+msgid "Check this field if this project manages issues"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,day_open:0
+msgid "Days to Open"
+msgstr ""
+
+#. module: project_issue
+#: code:addons/project_issue/project_issue.py:479
+#, python-format
+msgid ""
+"You cannot escalate this issue.\n"
+"The relevant Project has not configured the Escalation Project!"
+msgstr ""
+
+#. module: project_issue
+#: constraint:project.project:0
+msgid "Error! You cannot assign escalation to the same project!"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,priority:0
+#: selection:project.issue.report,priority:0
+msgid "Highest"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,inactivity_days:0
+msgid "Difference in days between last action and current date"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+#: field:project.issue.report,day:0
+msgid "Day"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,days_since_creation:0
+msgid "Days since creation date"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,task_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,task_id:0
+msgid "Task"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,name:project_issue.mt_project_issue_stage
+msgid "Issue Stage Changed"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,inactivity_days:0
+msgid "Days since last action"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.model,name:project_issue.model_project_project
+#: view:project.issue:0
+#: field:project.issue,project_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,project_id:0
+msgid "Project"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,help:project_issue.project_issue_categ_act0
+msgid ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" Click to report a new issue.\n"
+" </p><p>\n"
+" The OpenERP issues tacker allows you to efficiantly manage "
+"things\n"
+" like internal requests, software development bugs, customer\n"
+" complaints, project troubles, material breakdowns, etc.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,state:0
+#: selection:project.issue.report,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,description:0
+msgid "Private Note"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,date_closed:0
+msgid "Date of Closing"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Issue Tracker Search"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,color:0
+msgid "Color Index"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,working_hours_open:0
+msgid "Avg. Working Hours to Open"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.model,name:project_issue.model_account_analytic_account
+msgid "Analytic Account"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,message_summary:0
+msgid ""
+"Holds the Chatter summary (number of messages, ...). This summary is "
+"directly in html format in order to be inserted in kanban views."
+msgstr ""
+
+#. module: project_issue
+#: help:project.project,project_escalation_id:0
+msgid ""
+"If any issue is escalated from the current Project, it will be listed under "
+"the project selected here."
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Extra Info"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,help:project_issue.action_project_issue_report
+msgid ""
+"This report on the project issues allows you to analyse the quality of your "
+"support or after-sales services. You can track the issues per age. You can "
+"analyse the time required to open or close an issue, the number of email to "
+"exchange and the time spent on average by issues."
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Edit..."
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Responsible"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Statistics"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,kanban_state:0
+msgid "Kanban State"
+msgstr ""
+
+#. module: project_issue
+#: code:addons/project_issue/project_issue.py:366
+#, python-format
+msgid "Project issue <b>converted</b> to task."
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,priority:0
+#: view:project.issue.report:0
+#: field:project.issue.report,priority:0
+msgid "Priority"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,version_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,version_id:0
+msgid "Version"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,message_follower_ids:0
+msgid "Followers"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: selection:project.issue,state:0
+#: view:project.issue.report:0
+msgid "New"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,name:project_issue.project_issue_categ_action
+msgid "Issue Categories"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,email_from:0
+msgid "Email"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,channel_id:0
+#: field:project.issue.report,channel_id:0
+msgid "Channel"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,priority:0
+#: selection:project.issue.report,priority:0
+msgid "Lowest"
+msgstr ""
+
+#. module: project_issue
+#: code:addons/project_issue/project_issue.py:388
+#, python-format
+msgid "%s (copy)"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Unassigned Issues"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,create_date:0
+#: view:project.issue.report:0
+#: field:project.issue.report,creation_date:0
+msgid "Creation Date"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,name:project_issue.project_issue_version_action
+#: model:ir.ui.menu,name:project_issue.menu_project_issue_version_act
+msgid "Versions"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "To Do Issues"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.model,name:project_issue.model_project_issue_version
+msgid "project.issue.version"
+msgstr ""
+
+#. module: project_issue
+#: field:project.config.settings,fetchmail_issue:0
+msgid "Create issues from an incoming email account "
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: selection:project.issue,state:0
+#: view:project.issue.report:0
+msgid "Done"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "July"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.ui.menu,name:project_issue.menu_project_issue_category_act
+msgid "Categories"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,stage_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,stage_id:0
+msgid "Stage"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,name:project_issue.action_project_issue_report
+#: model:ir.ui.menu,name:project_issue.menu_project_issue_report_tree
+#: view:project.issue.report:0
+msgid "Issues Analysis"
+msgstr ""
+
+#. module: project_issue
+#: code:addons/project_issue/project_issue.py:516
+#, python-format
+msgid "No Subject"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,name:project_issue.action_view_my_project_issue_tree
+msgid "My Project Issues"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,partner_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,partner_id:0
+msgid "Contact"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Delete"
+msgstr ""
+
+#. module: project_issue
+#: code:addons/project_issue/project_issue.py:371
+#, python-format
+msgid "Tasks"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,nbr:0
+msgid "# of Issues"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "September"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "December"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,categ_ids:0
+msgid "Tags"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Issue Tracker Tree"
+msgstr ""
+
+#. module: project_issue
+#: model:project.category,name:project_issue.project_issue_category_01
+msgid "Little problem"
+msgstr ""
+
+#. module: project_issue
+#: view:project.project:0
+msgid "creates"
+msgstr ""
+
+#. module: project_issue
+#: model:crm.case.categ,name:project_issue.feature_request_categ
+msgid "Feature Requests"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,write_date:0
+msgid "Update Date"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Project:"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Open Features"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,date_action_next:0
+msgid "Next Action"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: selection:project.issue,kanban_state:0
+msgid "Blocked"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,user_email:0
+msgid "User Email"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+msgid "#Number of Project Issues"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,channel_id:0
+msgid "Communication channel."
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,email_cc:0
+msgid ""
+"These email addresses will be added to the CC field of all inbound and "
+"outbound emails for this record before being sent. Separate multiple email "
+"addresses with a comma"
+msgstr ""
+
+#. module: project_issue
+#: model:crm.case.categ,name:project_issue.bug_categ
+msgid "Maintenance"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,state:0
+msgid "Draft"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,priority:0
+#: selection:project.issue.report,priority:0
+msgid "Low"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,date_closed:0
+#: selection:project.issue.report,state:0
+msgid "Closed"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,delay_close:0
+msgid "Avg. Delay to Close"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,state:0
+#: view:project.issue.report:0
+#: selection:project.issue.report,state:0
+msgid "Pending"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,state:0
+#: field:project.issue.report,state:0
+msgid "Status"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+msgid "#Project Issues"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "August"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,kanban_state:0
+#: selection:project.issue,priority:0
+#: selection:project.issue.report,priority:0
+msgid "Normal"
+msgstr ""
+
+#. module: project_issue
+#: field:project.project,issue_count:0
+msgid "unknown"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Category:"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "June"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "New Issues"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,day_close:0
+msgid "Days to Close"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,state:0
+msgid ""
+"The status is set to 'Draft', when a case is created. "
+"If the case is in progress the status is set to 'Open'. "
+"When the case is over, the status is set to 'Done'. If "
+"the case needs to be reviewed then the status is set "
+"to 'Pending'."
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,active:0
+#: field:project.issue.version,active:0
+msgid "Active"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "November"
+msgstr ""
+
+#. module: project_issue
+#: code:addons/project_issue/project_issue.py:479
+#, python-format
+msgid "Warning!"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+msgid "Search"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "October"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,days_since_creation:0
+msgid "Difference in days between creation date and current date"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "January"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Feature Tracker Tree"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,email_from:0
+msgid "These people will receive email."
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,date:0
+msgid "Date"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,user_id:0
+#: view:project.issue.report:0
+#: field:project.issue.report,user_id:0
+msgid "Assigned to"
+msgstr ""
+
+#. module: project_issue
+#: view:project.config.settings:0
+msgid "Configure"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,description:project_issue.mt_issue_closed
+msgid "Issue closed"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Current Features"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.version:0
+msgid "Issue Version"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.version,name:0
+msgid "Version Number"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Cancel"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,state:0
+msgid "Open"
+msgstr ""
+
+#. module: project_issue
+#: field:account.analytic.account,use_issues:0
+#: model:ir.actions.act_window,name:project_issue.act_project_project_2_project_issue_all
+#: model:ir.actions.act_window,name:project_issue.project_issue_categ_act0
+#: model:ir.ui.menu,name:project_issue.menu_project_confi
+#: model:ir.ui.menu,name:project_issue.menu_project_issue_track
+#: view:project.issue:0
+#: view:project.project:0
+msgid "Issues"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: selection:project.issue,state:0
+msgid "In Progress"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: view:project.issue.report:0
+msgid "To Do"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.model,name:project_issue.model_project_issue
+#: view:project.issue.report:0
+msgid "Project Issue"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Creation Month"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,progress:0
+msgid "Computed as: Time Spent / Total Time."
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: selection:project.issue,kanban_state:0
+msgid "Ready for next stage"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+#: field:project.issue.report,section_id:0
+msgid "Sale Team"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: view:project.issue.report:0
+#: field:project.issue.report,month:0
+msgid "Month"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+#: field:project.issue,name:0
+#: view:project.project:0
+msgid "Issue"
+msgstr ""
+
+#. module: project_issue
+#: model:project.category,name:project_issue.project_issue_category_02
+msgid "PBCK"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Feature Tracker Search"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Description"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,section_id:0
+msgid "Sales Team"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "May"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.model,name:project_issue.model_project_config_settings
+msgid "project.config.settings"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,name:project_issue.mt_issue_closed
+#: model:mail.message.subtype,name:project_issue.mt_project_issue_closed
+msgid "Issue Closed"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+#: field:project.issue.report,email:0
+msgid "# Emails"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,name:project_issue.mt_issue_new
+#: model:mail.message.subtype,name:project_issue.mt_project_issue_new
+msgid "Issue Created"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,name:project_issue.mt_issue_blocked
+#: model:mail.message.subtype,name:project_issue.mt_project_issue_blocked
+msgid "Issue Blocked"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "February"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,description:project_issue.mt_issue_stage
+#: model:mail.message.subtype,description:project_issue.mt_project_issue_stage
+msgid "Stage changed"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "Feature description"
+msgstr ""
+
+#. module: project_issue
+#: field:project.project,project_escalation_id:0
+msgid "Project Escalation"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.actions.act_window,help:project_issue.project_issue_version_action
+msgid ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" Click to add a new version.\n"
+" </p><p>\n"
+" Define here the different versions of your products on "
+"which\n"
+" you can work on issues.\n"
+" </p>\n"
+" "
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue,section_id:0
+msgid ""
+"Sales team to which Case belongs to. Define "
+"Responsible user and Email account for mail gateway."
+msgstr ""
+
+#. module: project_issue
+#: view:board.board:0
+msgid "My Issues"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue.report,delay_open:0
+msgid "Number of Days to open the project issue."
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue.report,month:0
+msgid "April"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "⇒ Escalate"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue:0
+msgid "References"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,description:project_issue.mt_issue_new
+msgid "Issue created"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,working_hours_close:0
+msgid "Working Hours to Close the Issue"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,id:0
+msgid "ID"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,description:project_issue.mt_issue_blocked
+msgid "Issue blocked"
+msgstr ""
+
+#. module: project_issue
+#: model:ir.model,name:project_issue.model_project_issue_report
+msgid "project.issue.report"
+msgstr ""
+
+#. module: project_issue
+#: help:project.issue.report,delay_close:0
+msgid "Number of Days to close the project issue"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue.report,working_hours_close:0
+msgid "Avg. Working Hours to Close"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,name:project_issue.mt_issue_stage
+msgid "Stage Changed"
+msgstr ""
+
+#. module: project_issue
+#: selection:project.issue,priority:0
+#: selection:project.issue.report,priority:0
+msgid "High"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,date_deadline:0
+msgid "Deadline"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,date_action_last:0
+msgid "Last Action"
+msgstr ""
+
+#. module: project_issue
+#: view:project.issue.report:0
+#: field:project.issue.report,name:0
+msgid "Year"
+msgstr ""
+
+#. module: project_issue
+#: field:project.issue,duration:0
+msgid "Duration"
+msgstr ""
+
+#. module: project_issue
+#: model:mail.message.subtype,name:project_issue.mt_issue_started
+#: model:mail.message.subtype,name:project_issue.mt_project_issue_started
+msgid "Issue Started"
+msgstr ""
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index ace27f13dd1..81104985c1b 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -60,7 +60,6 @@ class project_issue(osv.Model):
}
def _get_default_partner(self, cr, uid, context=None):
- """ Override of base_stage to add project specific behavior """
project_id = self._get_default_project_id(cr, uid, context)
if project_id:
project = self.pool.get('project.project').browse(cr, uid, project_id, context=context)
diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml
index ae21934ce61..c02f19ced65 100644
--- a/addons/sale_crm/sale_crm_view.xml
+++ b/addons/sale_crm/sale_crm_view.xml
@@ -9,8 +9,8 @@
<field name="arch" type="xml">
<data>
<xpath expr="/form/header/button[@name='case_mark_lost']" position="after">
- <button states="done" string="Create Quotation" name="%(action_crm_make_sale)d" type="action"/>
- <button states="draft,open,pending" string="Convert to Quotation" name="%(action_crm_make_sale)d" type="action" class="oe_highlight"/>
+ <button attrs="{'invisible': [('probability', '&lt;', 100)]}" string="Create Quotation" name="%(action_crm_make_sale)d" type="action"/>
+ <button attrs="{'invisible': [('probability', '=', 100)]}" string="Convert to Quotation" name="%(action_crm_make_sale)d" type="action" class="oe_highlight"/>
</xpath>
</data>
</field>
diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py
index b74817059e4..829468e684f 100644
--- a/addons/sale_crm/wizard/crm_make_sale.py
+++ b/addons/sale_crm/wizard/crm_make_sale.py
@@ -112,7 +112,7 @@ class crm_make_sale(osv.osv_memory):
message = _("Opportunity has been <b>converted</b> to the quotation <em>%s</em>.") % (sale_order.name)
case.message_post(body=message)
if make.close:
- case_obj.case_close(cr, uid, data)
+ case_obj.case_mark_won(cr, uid, data, context=context)
if not new_ids:
return {'type': 'ir.actions.act_window_close'}
if len(new_ids)<=1:
diff --git a/addons/share/i18n/bs.po b/addons/share/i18n/bs.po
new file mode 100644
index 00000000000..7d3a0e10b80
--- /dev/null
+++ b/addons/share/i18n/bs.po
@@ -0,0 +1,629 @@
+# Bosnian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:06+0000\n"
+"PO-Revision-Date: 2013-08-08 22:26+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Bosnian <bs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-09 05:06+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:842
+#, python-format
+msgid "Invitation to collaborate about %s"
+msgstr "Poziv za razgovor o %s"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:780
+#, python-format
+msgid ""
+"The share engine has not been able to fetch a record_id for your invitation."
+msgstr ""
+"Sistem za dijeljenje nije bio u mogućnosti da uhvati record_id za vašu "
+"pozivnicu."
+
+#. module: share
+#: view:share.wizard:0
+msgid "Include an Optional Personal Message"
+msgstr "Uključi opcionalnu personalnu poruku"
+
+#. module: share
+#: field:share.wizard,embed_option_title:0
+msgid "Display title"
+msgstr "Prikaži naslov"
+
+#. module: share
+#: view:share.wizard:0
+msgid "Access granted!"
+msgstr "Pristup odobren!"
+
+#. module: share
+#: field:share.wizard,record_name:0
+msgid "Record name"
+msgstr "Ime zapisa"
+
+#. module: share
+#: help:share.wizard,message:0
+msgid ""
+"An optional personal message, to be included in the email notification."
+msgstr ""
+"Opcionalna personalna poruka, da bude uključena u email obavještenje."
+
+#. module: share
+#: field:share.wizard,user_type:0
+msgid "Sharing method"
+msgstr "Metoda djeljenja"
+
+#. module: share
+#: field:share.wizard,name:0
+msgid "Share Title"
+msgstr "Djeli naslov"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:848
+#: code:addons/share/wizard/share_wizard.py:877
+#, python-format
+msgid ""
+"The documents are not attached, you can view them online directly on my "
+"OpenERP server at:\n"
+" %s\n"
+"\n"
+msgstr ""
+"Ovi dokumenti nisu zakačeni, možete ih pregledati online direktno na mom "
+"OpenERP serveru na:\n"
+" %s\n"
+"\n"
+
+#. module: share
+#: model:ir.module.category,name:share.module_category_share
+msgid "Sharing"
+msgstr "Dijeljeno"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:843
+#: code:addons/share/wizard/share_wizard.py:875
+#, python-format
+msgid ""
+"Hello,\n"
+"\n"
+msgstr ""
+"Pozdrav,\n"
+"\n"
+
+#. module: share
+#: field:share.wizard,share_root_url:0
+msgid "Share Access URL"
+msgstr "Dijeli URL pristupa"
+
+#. module: share
+#: field:share.wizard,email_1:0
+#: field:share.wizard,email_2:0
+#: field:share.wizard,email_3:0
+msgid "New user email"
+msgstr "Novi korisnički email"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:887
+#, python-format
+msgid "You may use your current login (%s) and password to view them.\n"
+msgstr ""
+"Možete koristiti vašu trenutnu prijavu (%s) i šifru da ih pregledate..\n"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:621
+#, python-format
+msgid "(Modified)"
+msgstr "(promjenjeno)"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:665
+#, python-format
+msgid "You must be a member of the Share/User group to use the share wizard."
+msgstr ""
+"Morate biti član Dijeli/Korisnik grupe da bi ste koristili čarobnjak "
+"dijeljenja."
+
+#. module: share
+#. openerp-web
+#: code:addons/share/static/src/js/share.js:63
+#, python-format
+msgid "Embed"
+msgstr "Ugradi"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:599
+#, python-format
+msgid "Sharing filter created by user %s (%s) for group %s"
+msgstr "Djeljeni filter kreiran od strane korisnika %s (%s) za grupu %s"
+
+#. module: share
+#: field:share.wizard,embed_url:0
+#: field:share.wizard.result.line,share_url:0
+msgid "Share URL"
+msgstr "URL djeljenja"
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:849
+#: code:addons/share/wizard/share_wizard.py:881
+#, python-format
+msgid "These are your credentials to access this protected area:\n"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Access info"
+msgstr ""
+
+#. module: share
+#. openerp-web
+#: code:addons/share/static/src/js/share.js:60
+#: view:share.wizard:0
+#, python-format
+msgid "Share"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:571
+#, python-format
+msgid "(Duplicated for modified sharing permissions)"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:669
+#, python-format
+msgid ""
+"Please indicate the emails of the persons to share with, one per line."
+msgstr ""
+
+#. module: share
+#: help:share.wizard,domain:0
+msgid "Optional domain for further data filtering"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Next"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:662
+#, python-format
+msgid "Action and Access Mode are required to create a shared access."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:850
+#: code:addons/share/wizard/share_wizard.py:882
+#, python-format
+msgid "Username"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Sharing Options"
+msgstr ""
+
+#. module: share
+#. openerp-web
+#: code:addons/share/static/src/xml/share.xml:9
+#, python-format
+msgid "Invite"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Embedded code options"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Configuration"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid ""
+"Please select the action that opens the screen containing the data you want "
+"to share."
+msgstr ""
+
+#. module: share
+#: field:res.groups,share:0
+msgid "Share Group"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:835
+#: code:addons/share/wizard/share_wizard.py:866
+#, python-format
+msgid "Email required"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid ""
+"Optionally, you may specify an additional domain restriction that will be "
+"applied to the shared data."
+msgstr ""
+
+#. module: share
+#: view:res.groups:0
+msgid "Non-Share Groups"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid ""
+"An email notification with instructions has been sent to the following "
+"people:"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:77
+#, python-format
+msgid "Direct link or embed code"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:856
+#: code:addons/share/wizard/share_wizard.py:890
+#, python-format
+msgid ""
+"OpenERP is a powerful and user-friendly suite of Business Applications (CRM, "
+"Sales, HR, etc.)\n"
+"It is open source and can be found on http://www.openerp.com."
+msgstr ""
+
+#. module: share
+#: field:share.wizard,action_id:0
+msgid "Action to share"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,record_name:0
+msgid "Name of the shared record, if sharing a precise record"
+msgstr ""
+
+#. module: share
+#: field:res.users,share:0
+msgid "Share User"
+msgstr ""
+
+#. module: share
+#: field:share.wizard.result.line,user_id:0
+msgid "unknown"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:61
+#: code:addons/share/wizard/share_wizard.py:657
+#, python-format
+msgid "Sharing access cannot be created."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:780
+#, python-format
+msgid "Record id not found"
+msgstr ""
+
+#. module: share
+#: help:res.groups,share:0
+msgid "Group created to set access rights for sharing data with some users."
+msgstr ""
+
+#. module: share
+#: view:res.groups:0
+msgid "Share Groups"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,action_id:0
+msgid ""
+"The action that opens the screen containing the data you wish to share."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:546
+#, python-format
+msgid "(Copy for sharing)"
+msgstr ""
+
+#. module: share
+#: field:share.wizard.result.line,newly_created:0
+msgid "Newly created"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,name:0
+msgid "Title for the share (displayed to users as menu and shortcut name)"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:636
+#, python-format
+msgid "Indirect sharing filter created by user %s (%s) for group %s"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,share_root_url:0
+msgid "Main access page for users that are granted shared access"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:206
+#, python-format
+msgid ""
+"You must configure your email address in the user preferences before using "
+"the Share button."
+msgstr ""
+
+#. module: share
+#: model:res.groups,name:share.group_share_user
+msgid "User"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:658
+#, python-format
+msgid ""
+"Sorry, the current screen and filter you are trying to share are not "
+"supported at the moment.\n"
+"You may want to try a simpler filter."
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Use this link"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:852
+#: code:addons/share/wizard/share_wizard.py:884
+#, python-format
+msgid "Database"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Share with these People (one email per line)"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,domain:0
+msgid "Domain"
+msgstr ""
+
+#. module: share
+#: view:res.groups:0
+msgid "{'search_default_no_share':1}"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+#: field:share.wizard,result_line_ids:0
+msgid "Summary"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,embed_code:0
+msgid ""
+"Embed this code in your documents to provide a link to the shared document."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:513
+#, python-format
+msgid "Copied access for sharing"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:817
+#, python-format
+msgid "Invitation"
+msgstr ""
+
+#. module: share
+#: model:ir.actions.act_window,name:share.action_share_wizard_step1
+msgid "Share your documents"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Or insert the following code where you want to embed your documents"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:886
+#, python-format
+msgid ""
+"The documents have been automatically added to your current OpenERP "
+"documents.\n"
+msgstr ""
+
+#. module: share
+#: model:ir.model,name:share.model_share_wizard_result_line
+msgid "share.wizard.result.line"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,embed_code:0
+msgid "Code"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,user_type:0
+msgid "Select the type of user(s) you would like to share data with."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:844
+#, python-format
+msgid ""
+"I have shared %s (%s) with you!\n"
+"\n"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,view_type:0
+msgid "Current View Type"
+msgstr ""
+
+#. module: share
+#: selection:share.wizard,access_mode:0
+msgid "Can view"
+msgstr ""
+
+#. module: share
+#: selection:share.wizard,access_mode:0
+msgid "Can edit"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Cancel"
+msgstr ""
+
+#. module: share
+#: help:res.users,share:0
+msgid ""
+"External user with limited access, created only for the purpose of sharing "
+"data."
+msgstr ""
+
+#. module: share
+#: model:ir.actions.act_window,name:share.action_share_wizard
+#: model:ir.model,name:share.model_share_wizard
+#: field:share.wizard.result.line,share_wizard_id:0
+msgid "Share Wizard"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:793
+#, python-format
+msgid "Shared access created!"
+msgstr ""
+
+#. module: share
+#: model:res.groups,comment:share.group_share_user
+msgid ""
+"\n"
+"Members of this groups have access to the sharing wizard, which allows them "
+"to invite external users to view or edit some of their documents."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:853
+#, python-format
+msgid ""
+"The documents have been automatically added to your subscriptions.\n"
+"\n"
+msgstr ""
+
+#. module: share
+#: model:ir.model,name:share.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:876
+#, python-format
+msgid ""
+"I've shared %s with you!\n"
+"\n"
+msgstr ""
+
+#. module: share
+#: model:ir.model,name:share.model_res_groups
+msgid "Access Groups"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,invite:0
+msgid "Invite users to OpenSocial record"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:851
+#: code:addons/share/wizard/share_wizard.py:883
+#: field:share.wizard.result.line,password:0
+#, python-format
+msgid "Password"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:77
+#: field:share.wizard,new_users:0
+#, python-format
+msgid "Emails"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,embed_option_search:0
+msgid "Display search view"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,message:0
+msgid "Personal Message"
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:835
+#: code:addons/share/wizard/share_wizard.py:866
+#, python-format
+msgid ""
+"The current user must have an email address configured in User Preferences "
+"to be able to send outgoing emails."
+msgstr ""
+
+#. module: share
+#: code:addons/share/wizard/share_wizard.py:205
+#, python-format
+msgid "No email address configured"
+msgstr ""
+
+#. module: share
+#: field:share.wizard.result.line,login:0
+msgid "Login"
+msgstr ""
+
+#. module: share
+#: view:res.users:0
+msgid "Regular users only (no share user)"
+msgstr ""
+
+#. module: share
+#: field:share.wizard,access_mode:0
+msgid "Access Mode"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "Sharing: preparation"
+msgstr ""
+
+#. module: share
+#: model:ir.model,name:share.model_ir_model_access
+msgid "ir.model.access"
+msgstr ""
+
+#. module: share
+#: view:share.wizard:0
+msgid "or"
+msgstr ""
+
+#. module: share
+#: help:share.wizard,access_mode:0
+msgid "Access rights to be granted on the shared documents."
+msgstr ""
diff --git a/addons/stock/i18n/zh_CN.po b/addons/stock/i18n/zh_CN.po
index 407a76e63b7..add3ef9989b 100644
--- a/addons/stock/i18n/zh_CN.po
+++ b/addons/stock/i18n/zh_CN.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-12-09 05:05+0000\n"
-"Last-Translator: sum1201 <Unknown>\n"
+"PO-Revision-Date: 2013-08-06 09:26+0000\n"
+"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:00+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-08-07 04:46+0000\n"
+"X-Generator: Launchpad (build 16721)\n"
#. module: stock
#: field:stock.inventory.line.split,line_exist_ids:0
@@ -124,8 +124,8 @@ msgid "Product Moves"
msgstr "产品调拨"
#. module: stock
-#: code:addons/stock/stock.py:2519
-#: code:addons/stock/stock.py:2580
+#: code:addons/stock/stock.py:2524
+#: code:addons/stock/stock.py:2585
#, python-format
msgid "Please provide proper quantity."
msgstr "输入数量不正确"
@@ -251,7 +251,7 @@ msgstr "安排送货单"
#: code:addons/stock/wizard/stock_change_standard_price.py:107
#, python-format
msgid "Active ID is not set in Context."
-msgstr ""
+msgstr "Contex中没有 Active ID"
#. module: stock
#: selection:stock.picking,invoice_state:0
@@ -346,9 +346,9 @@ msgstr "保留复杂的摘要(消息数量,……等)。为了插入到看板视
#. module: stock
#: code:addons/stock/stock.py:768
-#: code:addons/stock/stock.py:2475
-#: code:addons/stock/stock.py:2519
-#: code:addons/stock/stock.py:2580
+#: code:addons/stock/stock.py:2473
+#: code:addons/stock/stock.py:2524
+#: code:addons/stock/stock.py:2585
#: code:addons/stock/wizard/stock_change_product_qty.py:91
#: code:addons/stock/wizard/stock_fill_inventory.py:124
#: code:addons/stock/wizard/stock_inventory_merge.py:43
@@ -476,6 +476,7 @@ msgstr "操作追溯 "
#: selection:stock.move,state:0
#: selection:stock.picking,state:0
#: selection:stock.picking.in,state:0
+#: report:stock.picking.list:0
#: selection:stock.picking.out,state:0
msgid "Waiting Availability"
msgstr "等待可用"
@@ -484,6 +485,7 @@ msgstr "等待可用"
#: selection:report.stock.inventory,state:0
#: selection:report.stock.move,state:0
#: selection:stock.move,state:0
+#: report:stock.picking.list:0
#: view:stock.production.lot:0
#: field:stock.production.lot,stock_available:0
msgid "Available"
@@ -574,7 +576,7 @@ msgstr "实物盘点表草稿"
msgid ""
"Quantities, Units of Measure, Products and Locations cannot be modified on "
"stock moves that have already been processed (except by the Administrator)."
-msgstr ""
+msgstr "已经被处理过的移库单中,数量,计量单位,产品和库位不能修改(除非是 管理员)"
#. module: stock
#: help:report.stock.move,type:0
@@ -614,7 +616,7 @@ msgstr "标签"
#: code:addons/stock/stock.py:1356
#, python-format
msgid "Back order <em>%s</em> has been <b>created</b>."
-msgstr "未交付清单<em>%s</em> 已经被 <b>创建</b>."
+msgstr "延期交货清单<em>%s</em> 已经被 <b>创建</b>."
#. module: stock
#: model:ir.model,name:stock.model_report_stock_move
@@ -684,7 +686,7 @@ msgstr "入库单"
#, python-format
msgid ""
"Serial number quantity %d of %s is larger than available quantity (%d)!"
-msgstr ""
+msgstr "系列号数量 %d ( %s ) 大于可用数量(%d)!"
#. module: stock
#: report:stock.picking.list:0
@@ -821,7 +823,7 @@ msgstr "6月"
msgid ""
"Forces to specify a Serial Number for all moves containing this product and "
"coming from a Supplier Location"
-msgstr ""
+msgstr "为包含该产品和来自供应商库位的所有移库单 强制指定一个 系列号"
#. module: stock
#: help:stock.config.settings,group_uos:0
@@ -831,6 +833,8 @@ msgid ""
" For instance, you can sell pieces of meat that you invoice "
"based on their weight."
msgstr ""
+"允许产品的销售和开票的单位不一致.\n"
+" 例如你可以按块卖,但发票按重量开."
#. module: stock
#: field:product.template,property_stock_procurement:0
@@ -866,7 +870,7 @@ msgstr "在进行实时库存核算时,库存调拨处理将自动登入这账
msgid ""
"Please define stock output account for this product or its category: \"%s\" "
"(id: %d)"
-msgstr ""
+msgstr "请为这个产品或者它的类别定义一个出库科目: \"%s\" (id: %d)"
#. module: stock
#: field:stock.picking,message_summary:0
@@ -895,7 +899,7 @@ msgid "Time"
msgstr "时间"
#. module: stock
-#: code:addons/stock/product.py:447
+#: code:addons/stock/product.py:449
#, python-format
msgid "Future Receptions"
msgstr "未来的入库"
@@ -948,7 +952,7 @@ msgstr "入库库位"
msgid ""
"This field is for internal purpose. It is used to decide if the column "
"production lot has to be shown on the moves or not."
-msgstr ""
+msgstr "这 字段是内部用途。用来决定 生产批号这一列 是否显示在移库单上面"
#. module: stock
#: selection:product.product,valuation:0
@@ -982,7 +986,7 @@ msgstr "公司间转移的中途库位"
msgid ""
"You cannot cancel the picking as some moves have been done. You should "
"cancel the picking lines."
-msgstr ""
+msgstr "您不能取消已经有部分移库完成的分拣单。您应该取消 分拣单行"
#. module: stock
#: field:stock.config.settings,decimal_precision:0
@@ -1000,7 +1004,7 @@ msgid "Change Product Quantity"
msgstr "更改产品数量"
#. module: stock
-#: code:addons/stock/product.py:463
+#: code:addons/stock/product.py:465
#, python-format
msgid "Future P&L"
msgstr "未来的产品和库位"
@@ -1027,13 +1031,13 @@ msgstr "盘点库位"
#. module: stock
#: constraint:stock.move:0
msgid "You must assign a serial number for this product."
-msgstr ""
+msgstr "你需要为该产品指定一个系列号"
#. module: stock
#: code:addons/stock/stock.py:2255
#, python-format
msgid "Please define journal on the product category: \"%s\" (id: %d)"
-msgstr ""
+msgstr "请为这个产品类型定义一个分类账: \"%s\" (id: %d)"
#. module: stock
#: view:stock.move:0
@@ -1043,7 +1047,7 @@ msgstr "详情"
#. module: stock
#: selection:stock.picking,state:0
msgid "Ready to Transfer"
-msgstr ""
+msgstr "准备转移"
#. module: stock
#: report:lot.stock.overview:0
@@ -1134,12 +1138,12 @@ msgstr "产品批次"
#. module: stock
#: view:stock.picking:0
msgid "Reverse Transfer"
-msgstr ""
+msgstr "反向转移"
#. module: stock
#: field:stock.config.settings,group_uos:0
msgid "Invoice products in a different unit of measure than the sales order"
-msgstr ""
+msgstr "开票产品的计量单位和销售订单不一致。"
#. module: stock
#: help:stock.location,active:0
@@ -1160,13 +1164,13 @@ msgstr "请在列表视图中选择多个待合并的盘点"
msgid ""
"No products to return (only lines in Done state and not fully returned yet "
"can be returned)!"
-msgstr ""
+msgstr "没有产品被退货(只有完成状态和未完全退货的 行能被退货)!"
#. module: stock
#: view:stock.picking:0
#: view:stock.picking.in:0
msgid "Back Orders"
-msgstr "子单"
+msgstr "延期交货"
#. module: stock
#: field:stock.location,stock_virtual:0
@@ -1208,7 +1212,7 @@ msgstr "生产库位"
#: code:addons/stock/product.py:121
#, python-format
msgid "Please define journal on the product category: \"%s\" (id: %d)."
-msgstr ""
+msgstr "请在产品分类 \"%s\" (id: %d) 上面定义一个分类账。"
#. module: stock
#: field:report.stock.lines.date,date:0
@@ -1267,17 +1271,17 @@ msgstr "建立者"
#, python-format
msgid ""
"You are moving %.2f %s but only %.2f %s available for this serial number."
-msgstr ""
+msgstr "你正在移动 %.2f %s ,但该系列号只有 %.2f %s 可用"
#. module: stock
#: report:stock.picking.list:0
msgid "Internal Shipment :"
-msgstr ""
+msgstr "内部装运:"
#. module: stock
#: view:stock.inventory.line:0
msgid "Split Inventory Line"
-msgstr ""
+msgstr "拆分存货清单行"
#. module: stock
#: selection:stock.location,chained_auto_packing:0
@@ -1298,7 +1302,7 @@ msgid "Supplier"
msgstr "供应商"
#. module: stock
-#: code:addons/stock/stock.py:2859
+#: code:addons/stock/stock.py:2864
#, python-format
msgid ""
"In order to cancel this inventory, you must first unpost related journal "
@@ -1309,7 +1313,7 @@ msgstr "为取消这个盘存,你必须要先取消相关的分录。"
#: code:addons/stock/product.py:113
#, python-format
msgid "Please specify company in Location."
-msgstr ""
+msgstr "请在库位里 指定公司"
#. module: stock
#: view:stock.move:0
@@ -1321,7 +1325,7 @@ msgstr "库存调拨可用(已准备好)"
msgid ""
"Allows you to create and manage your packaging dimensions and types you want "
"to be maintained in your system."
-msgstr ""
+msgstr "允许创建和管理你要在系统中保留的的包装尺寸和类型。"
#. module: stock
#: selection:report.stock.inventory,month:0
@@ -1346,7 +1350,7 @@ msgstr "实物盘点"
#: code:addons/stock/wizard/stock_move.py:214
#, python-format
msgid "Processing Error!"
-msgstr ""
+msgstr "处理错误!"
#. module: stock
#: help:stock.location,chained_company_id:0
@@ -1367,6 +1371,11 @@ msgid ""
"* Available: When products are reserved, it is set to 'Available'.\n"
"* Done: When the shipment is processed, the state is 'Done'."
msgstr ""
+"* 新建: 当移库单被创建还没被确实时。\n"
+"* 等待另外的移库: 当需要等待另外一个移库完成时,出现该状态。例如:链式物流.\n"
+"* 等待可用: 当需求还不能被直接了当地解决时,出现该状态。可能需要等调度程序被运行,有个部件在等待制造等等...\n"
+"* 可用: 当产品已经被保留了,状态就被设置为 可用。\n"
+"* 完成: 当这次装运被处理,状态就是“完成”。"
#. module: stock
#: model:stock.location,name:stock.stock_location_locations_partner
@@ -1423,6 +1432,13 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 创建一个新的凭证。\n"
+" </p><p>\n"
+" 根据所执行操作的类型 或者 工人/团队 将要执行的操作,库存凭证系统允许你指定每个库存操作对应到指定的凭证。\n"
+" 例如库存凭证可以是:质量控制,分拣单,包装 等等。\n"
+" </p>\n"
+" "
#. module: stock
#: help:stock.location,chained_auto_packing:0
@@ -1462,7 +1478,7 @@ msgstr "等待其它调拨"
#: help:stock.change.product.qty,new_quantity:0
msgid ""
"This quantity is expressed in the Default Unit of Measure of the product."
-msgstr ""
+msgstr "此数量以该产品的默认计量单位表示"
#. module: stock
#: help:stock.move,price_unit:0
@@ -1475,7 +1491,7 @@ msgstr "用户在确认分拣时设置期间,字段用于记录产品的成本
#: code:addons/stock/stock.py:1890
#, python-format
msgid "Warning: No Back Order"
-msgstr ""
+msgstr "警告: 没有 延期交货清单"
#. module: stock
#: model:ir.model,name:stock.model_stock_move
@@ -1494,7 +1510,7 @@ msgid "To be refunded/invoiced"
msgstr "已开票或退票"
#. module: stock
-#: code:addons/stock/stock.py:2450
+#: code:addons/stock/stock.py:2448
#, python-format
msgid "You can only delete draft moves."
msgstr "您只能删除草稿状态的调拨。"
@@ -1503,12 +1519,12 @@ msgstr "您只能删除草稿状态的调拨。"
#: code:addons/stock/stock.py:1665
#, python-format
msgid "You cannot move product %s to a location of type view %s."
-msgstr ""
+msgstr "您不能移动产品%s到视图类型的库位%s。"
#. module: stock
#: view:stock.inventory:0
msgid "Split in serial numbers"
-msgstr ""
+msgstr "拆分系列号"
#. module: stock
#: view:stock.move:0
@@ -1537,10 +1553,10 @@ msgid "Additional Info"
msgstr "附加信息"
#. module: stock
-#: code:addons/stock/stock.py:2648
+#: code:addons/stock/stock.py:2653
#, python-format
msgid "Missing partial picking data for move #%s."
-msgstr ""
+msgstr "移库单 #%s 丢失了部分分拣的数据。"
#. module: stock
#: field:stock.location.product,from_date:0
@@ -1631,6 +1647,9 @@ msgstr ""
#. module: stock
#: field:stock.inventory,date:0
#: field:stock.move,create_date:0
+#: field:stock.picking,date:0
+#: field:stock.picking.in,date:0
+#: field:stock.picking.out,date:0
#: field:stock.production.lot,date:0
#: field:stock.tracking,date:0
msgid "Creation Date"
@@ -1731,7 +1750,7 @@ msgstr "上级库位"
#: code:addons/stock/product.py:168
#, python-format
msgid "Please define stock output account for this product: \"%s\" (id: %d)."
-msgstr ""
+msgstr "请为产品 \"%s\" (id: %d) 定义出库科目"
#. module: stock
#: help:stock.location,company_id:0
@@ -1754,15 +1773,15 @@ msgid "Stock Invoice Onshipping"
msgstr "发票未到"
#. module: stock
-#: code:addons/stock/stock.py:2475
+#: code:addons/stock/stock.py:2473
#, python-format
msgid "Please provide a positive quantity to scrap."
-msgstr ""
+msgstr "请提供一个正数给报废库位。"
#. module: stock
#: model:stock.location,name:stock.stock_location_shop1
msgid "Your Company, Birmingham shop"
-msgstr ""
+msgstr "你的公司,伯明翰商店"
#. module: stock
#: view:product.product:0
@@ -1781,7 +1800,7 @@ msgstr "单位成本的币别"
#: selection:stock.picking.in,move_type:0
#: selection:stock.picking.out,move_type:0
msgid "Partial"
-msgstr ""
+msgstr "部分"
#. module: stock
#: selection:report.stock.inventory,month:0
@@ -1792,7 +1811,7 @@ msgstr "9月"
#. module: stock
#: view:product.product:0
msgid "days"
-msgstr ""
+msgstr "天"
#. module: stock
#: model:ir.model,name:stock.model_report_stock_inventory
@@ -1809,13 +1828,13 @@ msgstr "月计划"
#: help:stock.picking.in,origin:0
#: help:stock.picking.out,origin:0
msgid "Reference of the document"
-msgstr ""
+msgstr "文档的参照"
#. module: stock
#: view:stock.picking:0
#: view:stock.picking.in:0
msgid "Is a Back Order"
-msgstr "是子单"
+msgstr "是一个延期交货清单"
#. module: stock
#: report:stock.picking.list:0
@@ -1830,7 +1849,7 @@ msgstr "库存核算科目(出仓)"
#. module: stock
#: view:stock.return.picking.memory:0
msgid "Return Picking Memory"
-msgstr ""
+msgstr "退回分拣存储区"
#. module: stock
#: model:ir.actions.act_window,name:stock.action_move_form2
@@ -1847,7 +1866,7 @@ msgstr "库存调拨"
msgid ""
"Check this option to select existing serial numbers in the list below, "
"otherwise you should enter new ones line by line."
-msgstr ""
+msgstr "点击此项从下面列表中选择一个已有的系列号,否则你要逐行输入新的"
#. module: stock
#: selection:report.stock.move,type:0
@@ -1873,14 +1892,14 @@ msgstr "取消可用"
#: code:addons/stock/wizard/stock_location_product.py:49
#, python-format
msgid "Current Inventory"
-msgstr ""
+msgstr "当前库存清单"
#. module: stock
#: help:product.template,property_stock_production:0
msgid ""
"This stock location will be used, instead of the default one, as the source "
"location for stock moves generated by manufacturing orders."
-msgstr ""
+msgstr "该库位将被使用以替换默认的,同样的,库存移位的源库位将根据制造单生成。"
#. module: stock
#: help:stock.move,date_expected:0
@@ -1903,10 +1922,10 @@ msgid "Shelf 2"
msgstr "货架 2"
#. module: stock
-#: code:addons/stock/stock.py:529
+#: code:addons/stock/stock.py:528
#, python-format
msgid "You cannot remove a lot line."
-msgstr ""
+msgstr "您不能移除一个批号"
#. module: stock
#: help:stock.location,posx:0
@@ -1927,7 +1946,7 @@ msgid "Localization"
msgstr "本地化"
#. module: stock
-#: code:addons/stock/product.py:459
+#: code:addons/stock/product.py:461
#, python-format
msgid "Delivered Qty"
msgstr "已配送数量"
@@ -1935,14 +1954,14 @@ msgstr "已配送数量"
#. module: stock
#: view:stock.partial.picking:0
msgid "Transfer Products"
-msgstr ""
+msgstr "转让产品"
#. module: stock
#: help:product.template,property_stock_inventory:0
msgid ""
"This stock location will be used, instead of the default one, as the source "
"location for stock moves generated when you do an inventory."
-msgstr ""
+msgstr "该库位将被使用以替换默认的,同样当你做盘点时,库存移位的源库位将被生成。"
#. module: stock
#: help:product.template,property_stock_account_output:0
@@ -1998,7 +2017,7 @@ msgstr "日期"
#: field:stock.picking.in,message_is_follower:0
#: field:stock.picking.out,message_is_follower:0
msgid "Is a Follower"
-msgstr ""
+msgstr "是一个关注者"
#. module: stock
#: view:report.stock.inventory:0
@@ -2009,13 +2028,13 @@ msgstr "增加筛选条件"
#. module: stock
#: field:stock.warehouse,lot_stock_id:0
msgid "Location Stock"
-msgstr "库位库存"
+msgstr "库存库位"
#. module: stock
#: code:addons/stock/wizard/stock_partial_picking.py:97
#, python-format
msgid "_Deliver"
-msgstr ""
+msgstr "_Deliver"
#. module: stock
#: code:addons/stock/wizard/stock_inventory_merge.py:64
@@ -2058,7 +2077,7 @@ msgstr "批号"
#: model:ir.actions.act_window,name:stock.action_deliver_move
#: view:product.product:0
msgid "Deliveries"
-msgstr ""
+msgstr "已交付"
#. module: stock
#: model:ir.actions.act_window,help:stock.action_reception_picking_move
@@ -2109,7 +2128,7 @@ msgstr "退回分拣"
#: model:ir.actions.act_window,name:stock.act_stock_return_picking_in
#: model:ir.actions.act_window,name:stock.act_stock_return_picking_out
msgid "Return Shipment"
-msgstr ""
+msgstr "退回件"
#. module: stock
#: model:ir.model,name:stock.model_stock_inventory_merge
@@ -2161,7 +2180,7 @@ msgstr "默认作为您接收当前业务伙伴产品的源库位"
#: sql_constraint:stock.production.lot:0
msgid ""
"The combination of Serial Number and internal reference must be unique !"
-msgstr ""
+msgstr "系列号和内部参考号的组合必须是唯一的"
#. module: stock
#: field:stock.warehouse,partner_id:0
@@ -2179,7 +2198,7 @@ msgstr "调拨分析让您轻松检查和分析您公司的库存调拨.在您åˆ
#. module: stock
#: constraint:stock.move:0
msgid "You try to assign a lot which is not from the same product."
-msgstr ""
+msgstr "你试图分配一个不是该产品的批次"
#. module: stock
#: field:report.stock.move,day_diff1:0
@@ -2194,20 +2213,20 @@ msgstr "价格"
#. module: stock
#: field:stock.config.settings,module_stock_invoice_directly:0
msgid "Create and open the invoice when the user finish a delivery order"
-msgstr ""
+msgstr "当用户完成一个发运单后,创建并打开发票"
#. module: stock
#: model:ir.model,name:stock.model_stock_return_picking_memory
msgid "stock.return.picking.memory"
-msgstr ""
+msgstr "stock.return.picking.memory"
#. module: stock
#: field:stock.config.settings,group_stock_inventory_valuation:0
msgid "Generate accounting entries per stock movement"
-msgstr ""
+msgstr "对每个移库动作生成账务分录"
#. module: stock
-#: code:addons/stock/product.py:449
+#: code:addons/stock/product.py:451
#, python-format
msgid "Received Qty"
msgstr "已接收数量"
@@ -2215,7 +2234,7 @@ msgstr "已接收数量"
#. module: stock
#: field:stock.production.lot,ref:0
msgid "Internal Reference"
-msgstr "内部单号"
+msgstr "编号"
#. module: stock
#: help:stock.production.lot,prefix:0
@@ -2229,7 +2248,7 @@ msgstr "显示这序列号时的可选前缀: PREFIX/SERIAL [INT_REF]"
msgid ""
"Forces to specify a Serial Number for all moves containing this product and "
"generated by a Manufacturing Order"
-msgstr ""
+msgstr "强制对包含该产品的所有移库单指定一个系列号,并生成一个制造单"
#. module: stock
#: model:ir.model,name:stock.model_stock_fill_inventory
@@ -2246,7 +2265,7 @@ msgstr "名称"
#. module: stock
#: report:stock.picking.list:0
msgid "Supplier Address :"
-msgstr ""
+msgstr "供应商地址:"
#. module: stock
#: view:stock.inventory.line:0
@@ -2274,28 +2293,28 @@ msgid "Customer Locations"
msgstr "客户库位"
#. module: stock
-#: code:addons/stock/stock.py:2449
-#: code:addons/stock/stock.py:2858
+#: code:addons/stock/stock.py:2448
+#: code:addons/stock/stock.py:2863
#, python-format
msgid "User Error!"
-msgstr ""
+msgstr "用户错误!"
#. module: stock
#: view:stock.partial.picking:0
msgid "Stock partial Picking"
-msgstr ""
+msgstr "库存部分分拣"
#. module: stock
#: view:stock.picking:0
msgid "Create Invoice/Refund"
-msgstr ""
+msgstr "创建发票/退款"
#. module: stock
#: help:stock.picking,message_ids:0
#: help:stock.picking.in,message_ids:0
#: help:stock.picking.out,message_ids:0
msgid "Messages and communication history"
-msgstr ""
+msgstr "消息和通信记录"
#. module: stock
#: view:report.stock.inventory:0
@@ -2320,7 +2339,7 @@ msgstr "供货商库位"
#. module: stock
#: view:stock.location.product:0
msgid "View Products Inventory"
-msgstr ""
+msgstr "查看产品库存"
#. module: stock
#: view:stock.move:0
@@ -2331,7 +2350,7 @@ msgstr "创建"
#: code:addons/stock/stock.py:1776
#, python-format
msgid "Operation forbidden !"
-msgstr ""
+msgstr "操作被禁止"
#. module: stock
#: view:report.stock.inventory:0
@@ -2355,12 +2374,12 @@ msgstr "入库科目"
#. module: stock
#: view:report.stock.move:0
msgid "Shipping type specify, goods coming in or going out"
-msgstr ""
+msgstr "指定运输类型,商品进入或者发出"
#. module: stock
#: view:stock.config.settings:0
msgid "Accounting"
-msgstr ""
+msgstr "会计"
#. module: stock
#: model:ir.ui.menu,name:stock.menu_warehouse_config
@@ -2403,6 +2422,13 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 创建一个库存移库单。\n"
+" </p><p>\n"
+" 此菜单给你在一个特定产品上面的库存操作的完整的可追溯性。\n"
+" 你能过滤该产品,查看该产品所有已经发生和未发生的移库。\n"
+" </p>\n"
+" "
#. module: stock
#: view:stock.location:0
@@ -2429,26 +2455,26 @@ msgstr "计量单位"
#. module: stock
#: field:stock.config.settings,group_stock_multiple_locations:0
msgid "Manage multiple locations and warehouses"
-msgstr ""
+msgstr "管理多库位及仓库"
#. module: stock
#: field:stock.config.settings,group_stock_production_lot:0
msgid "Track serial number on products"
-msgstr ""
+msgstr "追溯产品批次"
#. module: stock
#: field:stock.picking,message_unread:0
#: field:stock.picking.in,message_unread:0
#: field:stock.picking.out,message_unread:0
msgid "Unread Messages"
-msgstr ""
+msgstr "未读消息"
#. module: stock
#: help:stock.production.lot,stock_available:0
msgid ""
"Current quantity of products with this Serial Number available in company "
"warehouses"
-msgstr ""
+msgstr "在 公司仓库中,该序列号的产品当前可用的数量。"
#. module: stock
#: view:stock.inventory:0
@@ -2470,7 +2496,7 @@ msgstr "批次"
#. module: stock
#: view:stock.partial.picking:0
msgid "_Transfer"
-msgstr ""
+msgstr "_Transfer"
#. module: stock
#: selection:report.stock.move,type:0
@@ -2499,7 +2525,7 @@ msgid "Warehouse board"
msgstr "仓库控制台"
#. module: stock
-#: code:addons/stock/product.py:469
+#: code:addons/stock/product.py:471
#, python-format
msgid "Future Qty"
msgstr "未来数量"
@@ -2507,7 +2533,7 @@ msgstr "未来数量"
#. module: stock
#: model:res.groups,name:stock.group_production_lot
msgid "Manage Serial Numbers"
-msgstr ""
+msgstr "管理系列号"
#. module: stock
#: field:stock.move,note:0
@@ -2520,7 +2546,7 @@ msgstr "备注"
#. module: stock
#: selection:stock.picking,state:0
msgid "Transferred"
-msgstr ""
+msgstr "已转运"
#. module: stock
#: report:lot.stock.overview:0
@@ -2541,7 +2567,7 @@ msgstr "移库单类型"
#. module: stock
#: view:stock.move:0
msgid "Process Partially"
-msgstr ""
+msgstr "处理部分"
#. module: stock
#: view:stock.move:0
@@ -2566,7 +2592,7 @@ msgstr "产品"
msgid ""
"Cannot create Journal Entry, Output Account of this product and Valuation "
"account on category of this product are same."
-msgstr ""
+msgstr "不能创建分类账分录,该产品的出库科目和其分类中的 估值科目是一样的"
#. module: stock
#: selection:stock.location,chained_location_type:0
@@ -2606,7 +2632,7 @@ msgstr "出仓产品"
msgid ""
"Please define stock input account for this product or its category: \"%s\" "
"(id: %d)"
-msgstr ""
+msgstr "请为产品 \"%s\" (id: %d) 或者他的类别 定义一个入库科目"
#. module: stock
#: view:report.stock.move:0
@@ -2621,7 +2647,7 @@ msgid "Move"
msgstr "调拨"
#. module: stock
-#: code:addons/stock/product.py:465
+#: code:addons/stock/product.py:467
#, python-format
msgid "P&L Qty"
msgstr "损益数量"
@@ -2629,7 +2655,7 @@ msgstr "损益数量"
#. module: stock
#: model:ir.model,name:stock.model_stock_config_settings
msgid "stock.config.settings"
-msgstr ""
+msgstr "stock.config.settings"
#. module: stock
#: view:stock.production.lot:0
@@ -2652,7 +2678,7 @@ msgstr ""
#. module: stock
#: model:stock.location,name:stock.stock_location_4
msgid "Big Suppliers"
-msgstr ""
+msgstr "大供应商"
#. module: stock
#: model:ir.actions.act_window,help:stock.action_stock_inventory_report
@@ -2678,7 +2704,7 @@ msgstr "创建"
#. module: stock
#: field:stock.change.product.qty,new_quantity:0
msgid "New Quantity on Hand"
-msgstr ""
+msgstr "在手库存调整"
#. module: stock
#: field:stock.move,priority:0
@@ -2728,7 +2754,7 @@ msgstr "取消盘点"
#. module: stock
#: field:stock.config.settings,group_product_variant:0
msgid "Support multiple variants per products "
-msgstr ""
+msgstr "支持每个产品的多个变体 "
#. module: stock
#: code:addons/stock/stock.py:2246
@@ -2736,7 +2762,7 @@ msgstr ""
msgid ""
"Cannot create Journal Entry, Input Account of this product and Valuation "
"account on category of this product are same."
-msgstr ""
+msgstr "不能创建分类账分录,该产品的入库科目和其分类中的 估值科目是一样的"
#. module: stock
#: model:ir.ui.menu,name:stock.menu_stock_unit_measure_stock
@@ -2752,7 +2778,7 @@ msgstr "固定库位"
#. module: stock
#: field:report.stock.inventory,scrap_location:0
msgid "scrap"
-msgstr ""
+msgstr "报废"
#. module: stock
#: code:addons/stock/stock.py:1891
@@ -2760,22 +2786,22 @@ msgstr ""
msgid ""
"By changing the quantity here, you accept the new quantity as complete: "
"OpenERP will not automatically generate a Back Order."
-msgstr ""
+msgstr "通过修改此处的数量,就是您已经收到完成的数量: OpenERP 将自动生成一个延期交货清单。"
#. module: stock
#: report:stock.inventory.move:0
msgid "Manual Quantity"
-msgstr ""
+msgstr "手动数量"
#. module: stock
#: view:product.product:0
msgid "On hand:"
-msgstr ""
+msgstr "在手:"
#. module: stock
#: model:ir.model,name:stock.model_stock_report_prodlots
msgid "Stock report by serial number"
-msgstr ""
+msgstr "按批次统计库库"
#. module: stock
#: selection:report.stock.inventory,month:0
@@ -2801,7 +2827,7 @@ msgstr "显示您产品的最后盘点并用特定的筛选规则去排序。如
#: code:addons/stock/wizard/stock_invoice_onshipping.py:112
#, python-format
msgid "Please create Invoices."
-msgstr ""
+msgstr "请创建发票"
#. module: stock
#: help:stock.config.settings,module_product_expiry:0
@@ -2814,12 +2840,20 @@ msgid ""
" - alert date.\n"
"This installs the module product_expiry."
msgstr ""
+"对产品和序列号跟踪不同的日期。\n"
+"下列日期可被跟踪:\n"
+" -寿命终止\n"
+" -最佳使用日期\n"
+" -搬运日期 \n"
+" -提醒日期\n"
+"\n"
+"这需要安装模块 product_expiry."
#. module: stock
#: code:addons/stock/wizard/stock_partial_picking.py:174
#, python-format
msgid "Please provide proper Quantity."
-msgstr ""
+msgstr "请提供适度的数量"
#. module: stock
#: model:ir.actions.report.xml,name:stock.report_product_history
@@ -2842,7 +2876,7 @@ msgstr "库存账簿"
#: code:addons/stock/wizard/stock_return_picking.py:174
#, python-format
msgid "%s-%s-return"
-msgstr ""
+msgstr "%s-%s-返回"
#. module: stock
#: code:addons/stock/wizard/stock_change_product_qty.py:82
@@ -2859,7 +2893,7 @@ msgstr "强制可用"
#. module: stock
#: field:product.template,loc_rack:0
msgid "Rack"
-msgstr ""
+msgstr "货架"
#. module: stock
#: model:ir.actions.act_window,name:stock.move_scrap
@@ -2870,7 +2904,7 @@ msgstr "损耗调拨"
#. module: stock
#: help:stock.move,prodlot_id:0
msgid "Serial number is used to put a serial number on the production"
-msgstr ""
+msgstr "用作在产品上放置一个系列号"
#. module: stock
#: code:addons/stock/wizard/stock_partial_picking.py:100
@@ -2916,7 +2950,7 @@ msgstr "完成日期"
#: code:addons/stock/stock.py:1663
#, python-format
msgid "You cannot move product %s from a location of type view %s."
-msgstr ""
+msgstr "您不能移动产品%s,因为它来自一个视图类型的库位 %s."
#. module: stock
#: model:stock.location,name:stock.stock_location_company
@@ -2969,6 +3003,13 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 添加一个库位。\n"
+" </p><p>\n"
+" 这是你的公司的仓库和库位的结构。\n"
+" 您能点击一个库位,获得产品的清单,和它们在每个库位及其子库位中的库存情况。\n"
+" </p>\n"
+" "
#. module: stock
#: field:stock.location,stock_real:0
@@ -2978,7 +3019,7 @@ msgstr "实际库存"
#. module: stock
#: field:stock.report.tracklots,tracking_id:0
msgid "Logistic Serial Number"
-msgstr ""
+msgstr "物流系列号"
#. module: stock
#: field:stock.production.lot.revision,date:0
@@ -2998,12 +3039,12 @@ msgstr "批次"
msgid ""
"Total quantity after split exceeds the quantity to split for this product: "
"\"%s\" (id: %d)."
-msgstr ""
+msgstr "产品 \"%s\" (id: %d) 分割后的数量总数超过了这个产品的数量"
#. module: stock
#: view:stock.partial.move.line:0
msgid "Stock Partial Move Line"
-msgstr ""
+msgstr "仓库局部 移库清单"
#. module: stock
#: field:stock.move,product_uos_qty:0
@@ -3025,13 +3066,13 @@ msgstr "联系地址:"
msgid ""
"When you select a serial number on product moves, you can get the upstream "
"or downstream traceability of that product."
-msgstr ""
+msgstr "当您在产品移库单选择了一个系列号,你就能得到该产品的上游或者下游的可追朔性"
#. module: stock
#: code:addons/stock/wizard/stock_partial_picking.py:95
#, python-format
msgid "_Receive"
-msgstr ""
+msgstr "_Receive"
#. module: stock
#: field:stock.incoterms,active:0
@@ -3069,7 +3110,7 @@ msgstr "贸易术语"
#. module: stock
#: model:ir.model,name:stock.model_stock_partial_picking_line
msgid "stock.partial.picking.line"
-msgstr ""
+msgstr "stock.partial.picking.line"
#. module: stock
#: report:lot.stock.overview:0
@@ -3099,6 +3140,14 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 单击为该产品登记一个收货单。\n"
+" </p><p>\n"
+" 这里可以找到该产品相关的所有收货记录,\n"
+" 以及所有你正在等待的来自供应商的\n"
+" 尚未到达的收货单。\n"
+" </p>\n"
+" "
#. module: stock
#: help:stock.fill.inventory,recursive:0
@@ -3111,7 +3160,7 @@ msgstr "如果选择将包括该库位子库位的产品。"
#: help:stock.config.settings,group_stock_inventory_valuation:0
msgid ""
"Allows to configure inventory valuations on products and product categories."
-msgstr ""
+msgstr "允许在产品或者产品分类配置存货估值。"
#. module: stock
#: help:stock.config.settings,module_stock_location:0
@@ -3123,6 +3172,10 @@ msgid ""
"needs, etc.\n"
" This installs the module stock_location."
msgstr ""
+"提供推送物流。这个特性的典型使用是:\n"
+" 管理产品的生产链,管理每个产品的默认库位,,\n"
+" 根据业务需要定义仓库的内路线等等。\n"
+"这需要安装模块 stock_location 。"
#. module: stock
#: view:stock.inventory:0
@@ -3163,7 +3216,7 @@ msgstr "修订版名称"
#. module: stock
#: model:res.groups,name:stock.group_tracking_lot
msgid "Manage Logistic Serial Numbers"
-msgstr ""
+msgstr "管理物流系列号"
#. module: stock
#: view:stock.inventory:0
@@ -3184,12 +3237,19 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 添加一个追踪号码。\n"
+" </p><p>\n"
+" 这是所有包装的一个列表。当你选择了一个包装,你\n"
+" 能获得包含在这个包装中的产品的上下游的可追踪性。\n"
+" </p>\n"
+" "
#. module: stock
-#: code:addons/stock/stock.py:2496
+#: code:addons/stock/stock.py:2501
#, python-format
msgid "%s %s %s has been <b>moved to</b> scrap."
-msgstr ""
+msgstr "%s %s %s 已被 <b>移动到</b> 报废仓."
#. module: stock
#: model:ir.actions.act_window,name:stock.action_picking_tree_out
@@ -3205,6 +3265,7 @@ msgstr "客户包装"
#: selection:stock.move,state:0
#: view:stock.picking:0
#: view:stock.picking.in:0
+#: report:stock.picking.list:0
msgid "Done"
msgstr "完成"
@@ -3242,14 +3303,14 @@ msgstr "如果想生成发票,请在分拣单上填写上业务伙伴."
#. module: stock
#: view:stock.picking.in:0
msgid "Confirm & Receive"
-msgstr ""
+msgstr "确认并接收"
#. module: stock
#: field:stock.picking,origin:0
#: field:stock.picking.in,origin:0
#: field:stock.picking.out,origin:0
msgid "Source Document"
-msgstr ""
+msgstr "源单据"
#. module: stock
#: selection:stock.move,priority:0
@@ -3259,7 +3320,7 @@ msgstr "不紧急"
#. module: stock
#: view:stock.move:0
msgid "Scheduled"
-msgstr ""
+msgstr "排程"
#. module: stock
#: model:ir.actions.act_window,name:stock.action_warehouse_form
@@ -3275,14 +3336,14 @@ msgstr "负责人"
#. module: stock
#: view:stock.move:0
msgid "Process Entirely"
-msgstr ""
+msgstr "处理分录"
#. module: stock
#: help:product.template,property_stock_procurement:0
msgid ""
"This stock location will be used, instead of the default one, as the source "
"location for stock moves generated by procurements."
-msgstr ""
+msgstr "该库位将被使用以替换默认的,同样的,库存移位的源库位将根据需求单生成。"
#. module: stock
#: model:ir.actions.act_window,name:stock.action_stock_inventory_report
@@ -3306,7 +3367,7 @@ msgstr "库存"
#: code:addons/stock/wizard/stock_return_picking.py:222
#, python-format
msgid "Returned Picking"
-msgstr ""
+msgstr "退回的分拣"
#. module: stock
#: model:ir.model,name:stock.model_product_product
@@ -3352,6 +3413,13 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 单击开始一次盘点。\n"
+" </p><p>\n"
+" "
+"定期盘点通常用于清点每个库位的商品数量。你可以每年定期使用本功能一次来做总体盘点,也可以在任何你需要的时候进行以便符合当前某个产品的存量级别。\n"
+" </p>\n"
+" "
#. module: stock
#: view:stock.return.picking:0
@@ -3372,12 +3440,12 @@ msgstr "指定的内部调拨"
#: code:addons/stock/stock.py:790
#, python-format
msgid "You cannot process picking without stock moves."
-msgstr ""
+msgstr "没有移库单,您不能处理分拣。"
#. module: stock
#: field:stock.production.lot,move_ids:0
msgid "Moves for this serial number"
-msgstr ""
+msgstr "该系列号的移库"
#. module: stock
#: field:stock.move,product_uos:0
@@ -3414,7 +3482,7 @@ msgstr "通道(X)"
#. module: stock
#: field:stock.config.settings,group_stock_packaging:0
msgid "Allow to define several packaging methods on products"
-msgstr ""
+msgstr "允许产品定义多种包装方式"
#. module: stock
#: model:stock.location,name:stock.stock_location_7
@@ -3465,7 +3533,7 @@ msgstr "按库位划分产品"
#. module: stock
#: view:stock.config.settings:0
msgid "Logistic"
-msgstr ""
+msgstr "物流"
#. module: stock
#: model:ir.actions.act_window,help:stock.action_location_form
@@ -3511,7 +3579,7 @@ msgstr "货架 1"
#: help:stock.picking.in,date:0
#: help:stock.picking.out,date:0
msgid "Creation time, usually the time of the order."
-msgstr ""
+msgstr "创建时间,通常是下单的时间。"
#. module: stock
#: field:stock.tracking,name:0
@@ -3550,7 +3618,7 @@ msgstr "激活相关科目"
#. module: stock
#: field:stock.location.product,type:0
msgid "Analyse Type"
-msgstr ""
+msgstr "分析类型"
#. module: stock
#: model:ir.actions.act_window,help:stock.action_picking_tree4
@@ -3582,10 +3650,10 @@ msgstr "全部一次性"
#. module: stock
#: model:ir.actions.act_window,name:stock.act_product_stock_move_open
msgid "Inventory Move"
-msgstr ""
+msgstr "库存调拨"
#. module: stock
-#: code:addons/stock/product.py:475
+#: code:addons/stock/product.py:477
#, python-format
msgid "Future Productions"
msgstr "未来生产"
@@ -3615,7 +3683,7 @@ msgstr ""
#: model:ir.actions.act_window,name:stock.action_stock_config_settings
#: view:stock.config.settings:0
msgid "Configure Warehouse"
-msgstr ""
+msgstr "配置仓库"
#. module: stock
#: view:stock.picking:0
@@ -3643,7 +3711,7 @@ msgstr "盘点日期"
#: model:ir.actions.act_window,name:stock.action_receive_move
#: view:product.product:0
msgid "Receptions"
-msgstr ""
+msgstr "接收"
#. module: stock
#: view:report.stock.move:0
@@ -3678,7 +3746,7 @@ msgstr "公司"
#: field:stock.move.consume,product_uom:0
#: field:stock.move.scrap,product_uom:0
msgid "Product Unit of Measure"
-msgstr ""
+msgstr "产品计量单位"
#. module: stock
#: view:stock.move:0
@@ -3712,7 +3780,7 @@ msgstr "盘点批次"
#: field:stock.report.prodlots,prodlot_id:0
#: field:stock.return.picking.memory,prodlot_id:0
msgid "Serial Number"
-msgstr ""
+msgstr "序列号"
#. module: stock
#: model:ir.model,name:stock.model_stock_partial_picking
@@ -3756,7 +3824,7 @@ msgstr ""
#: field:stock.picking.in,message_ids:0
#: field:stock.picking.out,message_ids:0
msgid "Messages"
-msgstr ""
+msgstr "消息"
#. module: stock
#: model:stock.location,name:stock.stock_location_8
@@ -3772,7 +3840,7 @@ msgstr "非欧洲客户"
#: code:addons/stock/product.py:167
#: code:addons/stock/report/report_stock.py:78
#: code:addons/stock/report/report_stock.py:134
-#: code:addons/stock/stock.py:529
+#: code:addons/stock/stock.py:528
#: code:addons/stock/stock.py:790
#: code:addons/stock/stock.py:1190
#: code:addons/stock/stock.py:1199
@@ -3782,7 +3850,8 @@ msgstr "非欧洲客户"
#: code:addons/stock/stock.py:2252
#: code:addons/stock/stock.py:2255
#: code:addons/stock/stock.py:2258
-#: code:addons/stock/stock.py:2585
+#: code:addons/stock/stock.py:2481
+#: code:addons/stock/stock.py:2590
#: code:addons/stock/wizard/stock_fill_inventory.py:59
#: code:addons/stock/wizard/stock_invoice_onshipping.py:112
#: code:addons/stock/wizard/stock_splitinto.py:53
@@ -3798,6 +3867,10 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 单击 定义一个新的仓库。\n"
+" </p>\n"
+" "
#. module: stock
#: selection:report.stock.inventory,state:0
@@ -3834,12 +3907,12 @@ msgstr "这分拣单不需要开发票。"
msgid ""
"The unit of measure rounding does not allow you to ship \"%s %s\", only "
"roundings of \"%s %s\" is accepted by the Unit of Measure."
-msgstr ""
+msgstr "计量单位取整不允许你的运送 \"%s %s\",只有\"%s %s\" 取整才被该计量单位接受。"
#. module: stock
#: model:stock.location,name:stock.stock_location_shop0
msgid "Your Company, Chicago shop"
-msgstr ""
+msgstr "Your Company, Chicago shop"
#. module: stock
#: selection:report.stock.move,type:0
@@ -3877,12 +3950,12 @@ msgstr ""
msgid ""
"By changing this quantity here, you accept the new quantity as complete: "
"OpenERP will not automatically generate a back order."
-msgstr ""
+msgstr "通过修改此处的数量,就是您已经收到完成的数量: OpenERP 将自动生成一个延期交货清单。"
#. module: stock
#: view:stock.production.lot.revision:0
msgid "Serial Number Revisions"
-msgstr ""
+msgstr "序列号修订版"
#. module: stock
#: model:ir.actions.act_window,name:stock.action_picking_tree
@@ -3900,7 +3973,7 @@ msgstr "送货单已处理"
#. module: stock
#: field:product.template,loc_case:0
msgid "Case"
-msgstr ""
+msgstr "案例"
#. module: stock
#: selection:report.stock.inventory,state:0
@@ -3941,20 +4014,20 @@ msgstr "这选项允许这库位能不能放置废料"
#: field:stock.picking.in,message_follower_ids:0
#: field:stock.picking.out,message_follower_ids:0
msgid "Followers"
-msgstr ""
+msgstr "关注者"
#. module: stock
-#: code:addons/stock/stock.py:2585
+#: code:addons/stock/stock.py:2590
#, python-format
msgid "Cannot consume a move with negative or zero quantity."
-msgstr ""
+msgstr "消耗的移库数量不能小于等于0。"
#. module: stock
#: help:stock.config.settings,decimal_precision:0
msgid ""
"As an example, a decimal precision of 2 will allow weights like: 9.99 kg, "
"whereas a decimal precision of 4 will allow weights like: 0.0231 kg."
-msgstr ""
+msgstr "作为一个例子,十进制精度为2允许重量是这样的:9.99千克,而一个十进制精度为4,将允许重量是这样的,如:0.0231千克。"
#. module: stock
#: view:report.stock.move:0
@@ -3967,7 +4040,7 @@ msgstr "总出库数量"
#: field:stock.picking.in,backorder_id:0
#: field:stock.picking.out,backorder_id:0
msgid "Back Order of"
-msgstr "分单"
+msgstr "之延期交货清单。"
#. module: stock
#: help:stock.partial.move.line,cost:0
@@ -3987,7 +4060,7 @@ msgstr "产品类别"
#. module: stock
#: view:stock.move:0
msgid "Serial Number"
-msgstr ""
+msgstr "序列号"
#. module: stock
#: view:stock.invoice.onshipping:0
@@ -4007,7 +4080,7 @@ msgstr "设置"
#. module: stock
#: model:res.groups,name:stock.group_locations
msgid "Manage Multiple Locations and Warehouses"
-msgstr ""
+msgstr "管理多个库位和仓库"
#. module: stock
#: help:stock.change.standard.price,new_price:0
@@ -4022,10 +4095,10 @@ msgstr ""
"如果成本价减少,库存核算科目为贷方,入库科目为借方。"
#. module: stock
-#: code:addons/stock/stock.py:2811
+#: code:addons/stock/stock.py:2816
#, python-format
msgid "INV:"
-msgstr ""
+msgstr "INV:"
#. module: stock
#: help:stock.config.settings,module_stock_invoice_directly:0
@@ -4034,6 +4107,8 @@ msgid ""
" to be invoiced when you send or deliver goods.\n"
" This installs the module stock_invoice_directly."
msgstr ""
+"当您发送或交付货物,如果交付要开票,将能自动运行开票向导。\n"
+"这需要安装模块 stock_invoice_directly。"
#. module: stock
#: field:stock.location,chained_journal_id:0
@@ -4074,7 +4149,7 @@ msgstr ""
"用于实时库存核算。当设定在一个虚拟库位(而不是内部类型)时,这科目将用于记录从内部库位调拨产品的估值。一般代替这产品的出库科目。它不影响内部库位。"
#. module: stock
-#: code:addons/stock/product.py:457
+#: code:addons/stock/product.py:459
#, python-format
msgid "Future Deliveries"
msgstr "未来送货"
@@ -4100,7 +4175,7 @@ msgstr "自动审核"
#: code:addons/stock/stock.py:1821
#, python-format
msgid "Insufficient Stock for Serial Number !"
-msgstr ""
+msgstr "该序列号的库存不足!"
#. module: stock
#: model:ir.model,name:stock.model_product_template
@@ -4144,13 +4219,13 @@ msgstr "字段用于记录用户确认在分拣期间所用的币别(用于计ç®
#. module: stock
#: help:stock.production.lot,name:0
msgid "Unique Serial Number, will be displayed as: PREFIX/SERIAL [INT_REF]"
-msgstr ""
+msgstr "唯一序列号将被显示为: PREFIX/SERIAL [INT_REF]"
#. module: stock
#: code:addons/stock/product.py:142
#, python-format
msgid "Please define stock input account for this product: \"%s\" (id: %d)."
-msgstr ""
+msgstr "请为产品 \"%s\" (id: %d) 定义一个入库科目。"
#. module: stock
#: model:ir.actions.act_window,name:stock.action_reception_picking_move
@@ -4161,7 +4236,7 @@ msgstr "入库产品"
#. module: stock
#: view:product.product:0
msgid "update"
-msgstr ""
+msgstr "更新"
#. module: stock
#: view:stock.change.product.qty:0
@@ -4180,7 +4255,7 @@ msgstr ""
#: view:stock.return.picking:0
#: view:stock.split.into:0
msgid "or"
-msgstr ""
+msgstr "或"
#. module: stock
#: selection:stock.picking,invoice_state:0
@@ -4232,7 +4307,7 @@ msgstr "自动分拣"
#. module: stock
#: report:stock.picking.list:0
msgid "Customer Address :"
-msgstr ""
+msgstr "客户地址:"
#. module: stock
#: field:stock.location,chained_auto_packing:0
@@ -4288,7 +4363,7 @@ msgstr "你真的要合并盘点?"
#. module: stock
#: view:stock.picking.out:0
msgid "Date of Delivery"
-msgstr ""
+msgstr "发运日期"
#. module: stock
#: field:stock.location,posy:0
@@ -4301,18 +4376,18 @@ msgstr "货架(Y)"
msgid ""
"Please define inventory valuation account on the product category: \"%s\" "
"(id: %d)"
-msgstr ""
+msgstr "请在产品类别 \"%s\" (id: %d) 中定义一个存货估值 科目"
#. module: stock
#: model:ir.model,name:stock.model_stock_production_lot_revision
msgid "Serial Number Revision"
-msgstr ""
+msgstr "序列号版本"
#. module: stock
#: code:addons/stock/product.py:96
#, python-format
msgid "Specify valuation Account for Product Category: %s."
-msgstr ""
+msgstr "为产品分类 %s 指定估值科目。"
#. module: stock
#: help:stock.config.settings,module_claim_from_delivery:0
@@ -4320,12 +4395,14 @@ msgid ""
"Adds a Claim link to the delivery order.\n"
" This installs the module claim_from_delivery."
msgstr ""
+"为发运单添加一个 索赔链接。\n"
+"这需要安装模块claim_from_delivery."
#. module: stock
#: code:addons/stock/wizard/stock_return_picking.py:208
#, python-format
msgid "Please specify at least one non-zero quantity."
-msgstr ""
+msgstr "请指定至少一个非0的数值。"
#. module: stock
#: field:stock.fill.inventory,set_stock_zero:0
@@ -4340,7 +4417,7 @@ msgstr "用户"
#. module: stock
#: field:stock.config.settings,module_stock_location:0
msgid "Create push/pull logistic rules"
-msgstr ""
+msgstr "创建推拉物流规则"
#. module: stock
#: code:addons/stock/wizard/stock_invoice_onshipping.py:98
@@ -4355,7 +4432,7 @@ msgid "November"
msgstr "11月"
#. module: stock
-#: code:addons/stock/product.py:471
+#: code:addons/stock/product.py:473
#, python-format
msgid "Unplanned Qty"
msgstr "计划外数量"
@@ -4379,7 +4456,7 @@ msgstr "1月"
#. module: stock
#: constraint:stock.move:0
msgid "You cannot move products from or to a location of the type view."
-msgstr ""
+msgstr "不能将视图类型的库位作为移库单的源库位或者目标库位"
#. module: stock
#: help:stock.config.settings,group_stock_production_lot:0
@@ -4387,14 +4464,14 @@ msgid ""
"This allows you to manage products by using serial numbers. When you select "
"a serial number on product moves, you can get the upstream or downstream "
"traceability of that product."
-msgstr ""
+msgstr "允许你使用序列号管理产品。当你在产品移库时选择了一个序列号,你能获得对产品的上游和下游的可追溯性。"
#. module: stock
#: code:addons/stock/wizard/stock_fill_inventory.py:124
#, python-format
msgid ""
"No product in this location. Please select a location in the product form."
-msgstr ""
+msgstr "该库位没有产品。请从产品表单选择一个库位。"
#. module: stock
#: model:ir.actions.act_window,name:stock.act_product_stock_move_futur_open
@@ -4407,7 +4484,7 @@ msgid "Move History (parent moves)"
msgstr "调拨日志(上级调拨)"
#. module: stock
-#: code:addons/stock/product.py:453
+#: code:addons/stock/product.py:455
#, python-format
msgid "Future Stock"
msgstr "未来库存"
@@ -4446,6 +4523,12 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 单击新增一个产品的发货单。\n"
+" </p><p>\n"
+" 你在此处会发现该产品相关的所有调拨历史,以及所有你需要发货给客户的产品。\n"
+" </p>\n"
+" "
#. module: stock
#: model:ir.actions.act_window,name:stock.action_location_form
@@ -4462,7 +4545,7 @@ msgstr "库位"
msgid ""
"If this shipment was split, then this field links to the shipment which "
"contains the already processed part."
-msgstr ""
+msgstr "如果这个装运单被分割,该字段将连接到包括了已经处理的部分的装运单。"
#. module: stock
#: view:stock.inventory:0
@@ -4481,7 +4564,7 @@ msgstr "前缀"
#: view:stock.move:0
#: view:stock.move.split:0
msgid "Split in Serial Numbers"
-msgstr ""
+msgstr "分开进系列号"
#. module: stock
#: help:product.template,property_stock_account_input:0
@@ -4524,12 +4607,12 @@ msgstr "指定包装的属性如数量,类型等"
#. module: stock
#: view:product.product:0
msgid "Delays"
-msgstr ""
+msgstr "延迟"
#. module: stock
#: report:stock.picking.list:0
msgid "Schedule Date"
-msgstr ""
+msgstr "预定日期"
#. module: stock
#: field:stock.location.product,to_date:0
@@ -4580,7 +4663,7 @@ msgstr "5月"
#: code:addons/stock/product.py:110
#, python-format
msgid "No difference between standard price and new price!"
-msgstr ""
+msgstr "标准价和新价格之间没有不同!"
#. module: stock
#: view:stock.picking.out:0
@@ -4595,7 +4678,7 @@ msgstr "送货"
#. module: stock
#: view:stock.fill.inventory:0
msgid "Import the current inventory"
-msgstr ""
+msgstr "导入当前库存清单"
#. module: stock
#: model:ir.actions.act_window,name:stock.action5
@@ -4609,7 +4692,7 @@ msgid "Location Content"
msgstr "库位包含"
#. module: stock
-#: code:addons/stock/product.py:477
+#: code:addons/stock/product.py:479
#, python-format
msgid "Produced Qty"
msgstr "产品数量"
@@ -4631,7 +4714,7 @@ msgstr "连锁库位类型"
#: help:stock.picking.in,min_date:0
#: help:stock.picking.out,min_date:0
msgid "Scheduled time for the shipment to be processed"
-msgstr ""
+msgstr "该装运单被处理的计划时间"
#. module: stock
#: selection:report.stock.inventory,location_type:0
@@ -4676,19 +4759,19 @@ msgstr ""
#. module: stock
#: view:stock.picking.in:0
msgid "Date of Reception"
-msgstr ""
+msgstr "接收的日期"
#. module: stock
#: help:stock.config.settings,group_stock_multiple_locations:0
msgid ""
"This allows to configure and use multiple stock locations and warehouses,\n"
" instead of having a single default one."
-msgstr ""
+msgstr "允许配置和使用多个库位和仓库,替换默认的一个。"
#. module: stock
#: view:stock.picking:0
msgid "Confirm & Transfer"
-msgstr ""
+msgstr "确认并传递"
#. module: stock
#: field:stock.location,scrap_location:0
@@ -4734,6 +4817,12 @@ msgid ""
" </p>\n"
" "
msgstr ""
+"<p class=\"oe_view_nocontent_create\">\n"
+" 点击以创建一个送货单. \n"
+" </p><p>\n"
+" 这里是所有送货单的列表,它们是根据不同的销售订单和物流规则 被准备好的。\n"
+" </p>\n"
+" "
#. module: stock
#: help:stock.tracking,name:0
@@ -4799,7 +4888,7 @@ msgstr "准备处理"
#. module: stock
#: report:stock.picking.list:0
msgid "Warehouse Address :"
-msgstr ""
+msgstr "仓库地址:"
#~ msgid "["
#~ msgstr "["