[MERGE] addons.
bzr revid: vda@tinyerp.com-20120409092719-tbb06x3zndn8szb0
|
@ -178,6 +178,7 @@ class account_invoice(osv.osv):
|
|||
return invoice_ids
|
||||
|
||||
_name = "account.invoice"
|
||||
_inherit = ['mail.thread']
|
||||
_description = 'Invoice'
|
||||
_order = "id desc"
|
||||
|
||||
|
@ -355,12 +356,8 @@ class account_invoice(osv.osv):
|
|||
context = {}
|
||||
try:
|
||||
res = super(account_invoice, self).create(cr, uid, vals, context)
|
||||
for inv_id, name in self.name_get(cr, uid, [res], context=context):
|
||||
ctx = context.copy()
|
||||
if vals.get('type', 'in_invoice') in ('out_invoice', 'out_refund'):
|
||||
ctx = self.get_log_context(cr, uid, context=ctx)
|
||||
message = _("Invoice '%s' is waiting for validation.") % name
|
||||
self.log(cr, uid, inv_id, message, context=ctx)
|
||||
if res:
|
||||
self.create_send_note(cr, uid, [res], context=context)
|
||||
return res
|
||||
except Exception, e:
|
||||
if '"journal_id" viol' in e.args[0]:
|
||||
|
@ -373,9 +370,7 @@ class account_invoice(osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
self.write(cr, uid, ids, {'state':'paid'}, context=context)
|
||||
for inv_id, name in self.name_get(cr, uid, ids, context=context):
|
||||
message = _("Invoice '%s' is paid.") % name
|
||||
self.log(cr, uid, inv_id, message)
|
||||
self.confirm_paid_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
|
@ -943,6 +938,11 @@ class account_invoice(osv.osv):
|
|||
move_obj.post(cr, uid, [move_id], context=ctx)
|
||||
self._log_event(cr, uid, ids)
|
||||
return True
|
||||
|
||||
def invoice_validate(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {'state':'open'}, context=context)
|
||||
self.invoice_validate_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def line_get_convert(self, cr, uid, x, part, date, context=None):
|
||||
return {
|
||||
|
@ -1033,6 +1033,7 @@ class account_invoice(osv.osv):
|
|||
# will be automatically deleted too
|
||||
account_move_obj.unlink(cr, uid, move_ids, context=context)
|
||||
self._log_event(cr, uid, ids, -1.0, 'Cancel Invoice')
|
||||
self.invoice_cancel_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
###################
|
||||
|
@ -1240,7 +1241,36 @@ class account_invoice(osv.osv):
|
|||
# Update the stored value (fields.function), so we write to trigger recompute
|
||||
self.pool.get('account.invoice').write(cr, uid, ids, {}, context=context)
|
||||
return True
|
||||
|
||||
|
||||
# -----------------------------------------
|
||||
# OpenChatter notifications and need_action
|
||||
# -----------------------------------------
|
||||
|
||||
def _get_document_type(self, type):
|
||||
type_dict = {
|
||||
'out_invoice': 'Customer invoice',
|
||||
'in_invoice': 'Supplier invoice',
|
||||
'out_refund': 'Customer Refund',
|
||||
'in_refund': 'Supplier Refund',
|
||||
}
|
||||
return type_dict.get(type, 'Invoice')
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
self.message_append_note(cr, uid, [obj.id],body=_("%s <b>created</b>.") % (self._get_document_type(obj.type)), context=context)
|
||||
|
||||
def invoice_validate_send_note(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
self.message_append_note(cr, uid, [obj.id], body=_("%s <b>validated</b>.") % (self._get_document_type(obj.type)), context=context)
|
||||
|
||||
def confirm_paid_send_note(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
self.message_append_note(cr, uid, [obj.id], body=_("%s <b>paid</b>.") % (self._get_document_type(obj.type)), context=context)
|
||||
|
||||
def invoice_cancel_send_note(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
self.message_append_note(cr, uid, [obj.id], body=_("%s <b>cancelled</b>.") % (self._get_document_type(obj.type)), context=context)
|
||||
|
||||
account_invoice()
|
||||
|
||||
class account_invoice_line(osv.osv):
|
||||
|
|
|
@ -243,6 +243,7 @@
|
|||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -338,6 +339,7 @@
|
|||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<field name="action">action_date_assign()
|
||||
action_move_create()
|
||||
action_number()
|
||||
write({'state':'open'})</field>
|
||||
invoice_validate()</field>
|
||||
<field name="kind">function</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="act_open_test">
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2012-01-11 09:11+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 04:57+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <openerp-i18n-czech@lists.launchpad.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-02-09 07:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: account_asset
|
||||
|
@ -401,6 +401,8 @@ msgid ""
|
|||
"currency. You should remove the secondary currency on the account or select "
|
||||
"a multi-currency view on the journal."
|
||||
msgstr ""
|
||||
"Vybraný účet vašeho záznamu deníku vynucuje použití druhotné měny. Měli "
|
||||
"byste odstranit druhotnou měnu z účtu nebo vybrat více-měny."
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.asset.report:0
|
||||
|
@ -445,6 +447,8 @@ msgid ""
|
|||
"The date of your Journal Entry is not in the defined period! You should "
|
||||
"change the date or remove this constraint from the journal."
|
||||
msgstr ""
|
||||
"Datum vašeho záznamu deníku není v určeném období! Měli byste změnit datum "
|
||||
"nebo odstranit omezení z deníku."
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,note:0 field:account.asset.category,note:0
|
||||
|
@ -507,7 +511,7 @@ msgstr "Zaúčtované řádky odpisů"
|
|||
#. module: account_asset
|
||||
#: constraint:account.move.line:0
|
||||
msgid "Company must be the same for its related account and period."
|
||||
msgstr ""
|
||||
msgstr "Společnost musí být stejná pro své vztažené účty a období."
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,child_ids:0
|
||||
|
@ -537,7 +541,7 @@ msgstr "Majetek zakoupený v tomto měsíci"
|
|||
#. module: account_asset
|
||||
#: constraint:account.move.line:0
|
||||
msgid "You can not create journal items on an account of type view."
|
||||
msgstr ""
|
||||
msgstr "Nemůžete vytvořit položky deníku v účtu typu pohled."
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.asset.report:0
|
||||
|
@ -769,7 +773,7 @@ msgstr "Vytvořit pohyby majetku"
|
|||
#. module: account_asset
|
||||
#: constraint:account.move.line:0
|
||||
msgid "You can not create journal items on closed account."
|
||||
msgstr ""
|
||||
msgstr "Nemůžete vytvořit položky deníku v uzavřeném účtu."
|
||||
|
||||
#. module: account_asset
|
||||
#: model:ir.actions.act_window,help:account_asset.action_asset_asset_report
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 04:54+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: account_cancel
|
||||
#: view:account.invoice:0
|
||||
msgid "Cancel"
|
||||
msgstr "Zrušit"
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-06 04:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: account_check_writing
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# Japanese 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
|
||||
"PO-Revision-Date: 2012-04-08 05:16+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: 2012-04-09 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: field:analytic.user.funct.grid,product_id:0
|
||||
msgid "Product"
|
||||
msgstr "商品"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: model:ir.model,name:analytic_user_function.model_analytic_user_funct_grid
|
||||
msgid "Relation table between users and products on a analytic account"
|
||||
msgstr "分析アカウントのユーザと商品の関係テーブル"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: constraint:hr.analytic.timesheet:0
|
||||
msgid "You cannot modify an entry in a Confirmed/Done timesheet !."
|
||||
msgstr "確認済みのタイムシートの項目を変更することはできません。"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: field:analytic.user.funct.grid,account_id:0
|
||||
#: model:ir.model,name:analytic_user_function.model_account_analytic_account
|
||||
msgid "Analytic Account"
|
||||
msgstr "分析アカウント"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: view:account.analytic.account:0
|
||||
#: field:account.analytic.account,user_product_ids:0
|
||||
msgid "Users/Products Rel."
|
||||
msgstr "ユーザ・商品の関係"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: field:analytic.user.funct.grid,user_id:0
|
||||
msgid "User"
|
||||
msgstr "ユーザ"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: code:addons/analytic_user_function/analytic_user_function.py:96
|
||||
#: code:addons/analytic_user_function/analytic_user_function.py:131
|
||||
#, python-format
|
||||
msgid "There is no expense account define for this product: \"%s\" (id:%d)"
|
||||
msgstr "商品 \"%s\" (id:%d) のアカウントが定義されていません。"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: code:addons/analytic_user_function/analytic_user_function.py:95
|
||||
#: code:addons/analytic_user_function/analytic_user_function.py:130
|
||||
#, python-format
|
||||
msgid "Error !"
|
||||
msgstr "エラー"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: constraint:account.analytic.account:0
|
||||
msgid "Error! You can not create recursive analytic accounts."
|
||||
msgstr "エラー。反復した分析アカウントを作ることはできません"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: model:ir.model,name:analytic_user_function.model_hr_analytic_timesheet
|
||||
msgid "Timesheet Line"
|
||||
msgstr "タイムシートの行"
|
||||
|
||||
#. module: analytic_user_function
|
||||
#: view:analytic.user.funct.grid:0
|
||||
msgid "User's Product for this Analytic Account"
|
||||
msgstr "この分析アカウントのユーザの商品"
|
|
@ -0,0 +1,135 @@
|
|||
# Japanese 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2012-04-08 06:15+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: 2012-04-09 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: association
|
||||
#: field:profile.association.config.install_modules_wizard,wiki:0
|
||||
msgid "Wiki"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
msgid "Event Management"
|
||||
msgstr "イベント管理"
|
||||
|
||||
#. module: association
|
||||
#: field:profile.association.config.install_modules_wizard,project_gtd:0
|
||||
msgid "Getting Things Done"
|
||||
msgstr "物事を完了"
|
||||
|
||||
#. module: association
|
||||
#: model:ir.module.module,description:association.module_meta_information
|
||||
msgid "This module is to create Profile for Associates"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: field:profile.association.config.install_modules_wizard,progress:0
|
||||
msgid "Configuration Progress"
|
||||
msgstr "設定を進行中"
|
||||
|
||||
#. module: association
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
msgid ""
|
||||
"Here are specific applications related to the Association Profile you "
|
||||
"selected."
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
msgid "title"
|
||||
msgstr "タイトル"
|
||||
|
||||
#. module: association
|
||||
#: help:profile.association.config.install_modules_wizard,event_project:0
|
||||
msgid "Helps you to manage and organize your events."
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: field:profile.association.config.install_modules_wizard,config_logo:0
|
||||
msgid "Image"
|
||||
msgstr "画像"
|
||||
|
||||
#. module: association
|
||||
#: help:profile.association.config.install_modules_wizard,hr_expense:0
|
||||
msgid ""
|
||||
"Tracks and manages employee expenses, and can automatically re-invoice "
|
||||
"clients if the expenses are project-related."
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: help:profile.association.config.install_modules_wizard,project_gtd:0
|
||||
msgid ""
|
||||
"GTD is a methodology to efficiently organise yourself and your tasks. This "
|
||||
"module fully integrates GTD principle with OpenERP's project management."
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
msgid "Resources Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: model:ir.module.module,shortdesc:association.module_meta_information
|
||||
msgid "Association profile"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: field:profile.association.config.install_modules_wizard,hr_expense:0
|
||||
msgid "Expenses Tracking"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: model:ir.actions.act_window,name:association.action_config_install_module
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
msgid "Association Application Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: help:profile.association.config.install_modules_wizard,wiki:0
|
||||
msgid ""
|
||||
"Lets you create wiki pages and page groups in order to keep track of "
|
||||
"business knowledge and share it with and between your employees."
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: help:profile.association.config.install_modules_wizard,project:0
|
||||
msgid ""
|
||||
"Helps you manage your projects and tasks by tracking them, generating "
|
||||
"plannings, etc..."
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: model:ir.model,name:association.model_profile_association_config_install_modules_wizard
|
||||
msgid "profile.association.config.install_modules_wizard"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: field:profile.association.config.install_modules_wizard,event_project:0
|
||||
msgid "Events"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
#: field:profile.association.config.install_modules_wizard,project:0
|
||||
msgid "Project Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: association
|
||||
#: view:profile.association.config.install_modules_wizard:0
|
||||
msgid "Configure"
|
||||
msgstr ""
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-06 04:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. #-#-#-#-# auth_openid.pot (OpenERP Server 6.1rc1) #-#-#-#-#
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 05:20+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: base_crypt
|
||||
#: model:ir.model,name:base_crypt.model_res_users
|
||||
msgid "res.users"
|
||||
msgstr "res.users"
|
||||
|
||||
#. module: base_crypt
|
||||
#: sql_constraint:res.users:0
|
||||
msgid "You can not have two users with the same login !"
|
||||
msgstr "Nemůžete mít dva uživatele se stejným přihlašovacím jménem !"
|
||||
|
||||
#. module: base_crypt
|
||||
#: constraint:res.users:0
|
||||
msgid "The chosen company is not in the allowed companies for this user"
|
||||
msgstr ""
|
||||
"Vybraná společnost není v povolených společnostech pro tohoto uživatele"
|
||||
|
||||
#. module: base_crypt
|
||||
#: code:addons/base_crypt/crypt.py:140
|
||||
#, python-format
|
||||
msgid "Please specify the password !"
|
||||
msgstr "Prosíme zadejte heslo!"
|
||||
|
||||
#. module: base_crypt
|
||||
#: code:addons/base_crypt/crypt.py:140
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Chyba"
|
|
@ -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-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2010-08-03 01:50+0000\n"
|
||||
"Last-Translator: Mantavya Gajjar (Open ERP) <Unknown>\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:16+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\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: 2012-02-09 06:01+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: base_iban
|
||||
#: constraint:res.partner.bank:0
|
||||
|
@ -23,27 +23,30 @@ msgid ""
|
|||
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
|
||||
"valid payments"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Prosíme určete kód BIC/Swift u banky pro IBAN účet bankovního typu k ověření "
|
||||
"plateb"
|
||||
|
||||
#. module: base_iban
|
||||
#: code:addons/base_iban/base_iban.py:139
|
||||
#, python-format
|
||||
msgid "This IBAN does not pass the validation check, please verify it"
|
||||
msgstr ""
|
||||
msgstr "Tento IBAN neprošel testem ověření, prosíme zkontrolujte jej"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type,format_layout:base_iban.bank_iban
|
||||
msgid "%(bank_name)s: IBAN %(acc_number)s - BIC %(bank_bic)s"
|
||||
msgstr ""
|
||||
msgstr "%(bank_name)s: IBAN %(acc_number)s - BIC %(bank_bic)s"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type.field,name:base_iban.bank_swift_field
|
||||
msgid "bank_bic"
|
||||
msgstr ""
|
||||
msgstr "bank_bic"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type.field,name:base_iban.bank_zip_field
|
||||
msgid "zip"
|
||||
msgstr "zip"
|
||||
msgstr "psč"
|
||||
|
||||
#. module: base_iban
|
||||
#: help:res.partner.bank,iban:0
|
||||
|
@ -53,12 +56,12 @@ msgstr "Mezinárodní Bankovní Číslo Účtu"
|
|||
#. module: base_iban
|
||||
#: model:ir.model,name:base_iban.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr ""
|
||||
msgstr "Bankovní účty"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type.field,name:base_iban.bank_country_field
|
||||
msgid "country_id"
|
||||
msgstr "id_státu"
|
||||
msgstr "country_id"
|
||||
|
||||
#. module: base_iban
|
||||
#: code:addons/base_iban/base_iban.py:136
|
||||
|
@ -66,7 +69,7 @@ msgstr "id_státu"
|
|||
msgid ""
|
||||
"The IBAN does not seem to be correct. You should have entered something like "
|
||||
"this %s"
|
||||
msgstr ""
|
||||
msgstr "IBAN nevypadá jako správný. Měli byste zadat něco jako toto %s"
|
||||
|
||||
#. module: base_iban
|
||||
#: field:res.partner.bank,iban:0
|
||||
|
@ -77,7 +80,7 @@ msgstr "IBAN"
|
|||
#: code:addons/base_iban/base_iban.py:140
|
||||
#, python-format
|
||||
msgid "The IBAN is invalid, it should begin with the country code"
|
||||
msgstr ""
|
||||
msgstr "IBAN je neplatný, měl by začínat kódem země"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type,name:base_iban.bank_iban
|
||||
|
@ -87,7 +90,7 @@ msgstr "Účet IBAN"
|
|||
#. module: base_iban
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid "The RIB and/or IBAN is not valid"
|
||||
msgstr ""
|
||||
msgstr "RIB a/nebo IBAN není platný"
|
||||
|
||||
#~ msgid "Invalid XML for View Architecture!"
|
||||
#~ msgstr "Invalidní XML pro zobrazení architektury!"
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
# Japanese 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-08 06:11+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: 2012-04-09 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: base_iban
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid ""
|
||||
"\n"
|
||||
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
|
||||
"valid payments"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: code:addons/base_iban/base_iban.py:139
|
||||
#, python-format
|
||||
msgid "This IBAN does not pass the validation check, please verify it"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type,format_layout:base_iban.bank_iban
|
||||
msgid "%(bank_name)s: IBAN %(acc_number)s - BIC %(bank_bic)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type.field,name:base_iban.bank_swift_field
|
||||
msgid "bank_bic"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type.field,name:base_iban.bank_zip_field
|
||||
msgid "zip"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: help:res.partner.bank,iban:0
|
||||
msgid "International Bank Account Number"
|
||||
msgstr "国際銀行口座番号"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:ir.model,name:base_iban.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr "銀行口座"
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type.field,name:base_iban.bank_country_field
|
||||
msgid "country_id"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: code:addons/base_iban/base_iban.py:136
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The IBAN does not seem to be correct. You should have entered something like "
|
||||
"this %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: field:res.partner.bank,iban:0
|
||||
msgid "IBAN"
|
||||
msgstr "国際銀行口座番号"
|
||||
|
||||
#. module: base_iban
|
||||
#: code:addons/base_iban/base_iban.py:140
|
||||
#, python-format
|
||||
msgid "The IBAN is invalid, it should begin with the country code"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: model:res.partner.bank.type,name:base_iban.bank_iban
|
||||
msgid "IBAN Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_iban
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid "The RIB and/or IBAN is not valid"
|
||||
msgstr "銀行情報のRIBまたはIBANが正しくありません。"
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-09-09 10:24+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 05:26+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-02-09 06:14+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: base_module_record
|
||||
|
@ -90,6 +90,9 @@ msgid ""
|
|||
"publish it on http://www.openerp.com, in the 'Modules' section. You can do "
|
||||
"it through the website or using features of the 'base_module_publish' module."
|
||||
msgstr ""
|
||||
"Pokud myslíte, že váš modul může zajímat jiné lidi, byli bychom rádi, abyste "
|
||||
"jej zveřejnili v sekci 'Moduly' na http://www.openerp.com. Můžete to provést "
|
||||
"přes webové stránky nebo použitím schopnosti modulu 'base_module_publish'."
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_data,init,check_date:0
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:17+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: base_tools
|
||||
#: model:ir.module.module,shortdesc:base_tools.module_meta_information
|
||||
msgid "Common base for tools modules"
|
||||
msgstr "Obecný základ pro nástrojové moduly"
|
||||
|
||||
#. module: base_tools
|
||||
#: model:ir.module.module,description:base_tools.module_meta_information
|
||||
msgid ""
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" "
|
|
@ -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-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-08-07 19:04+0000\n"
|
||||
"Last-Translator: Jan B. Krejčí <Unknown>\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:22+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\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: 2012-02-09 06:15+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: base_vat
|
||||
#: code:addons/base_vat/base_vat.py:141
|
||||
|
@ -23,31 +23,33 @@ msgid ""
|
|||
"This VAT number does not seem to be valid.\n"
|
||||
"Note: the expected format is %s"
|
||||
msgstr ""
|
||||
"Toto DIČ nevypadá jako platné.\n"
|
||||
"Poznámka: očekávaný formát je %s"
|
||||
|
||||
#. module: base_vat
|
||||
#: sql_constraint:res.company:0
|
||||
msgid "The company name must be unique !"
|
||||
msgstr ""
|
||||
msgstr "Jméno společnosti musí být jedinečné !"
|
||||
|
||||
#. module: base_vat
|
||||
#: constraint:res.partner:0
|
||||
msgid "Error ! You cannot create recursive associated members."
|
||||
msgstr ""
|
||||
msgstr "Chyba ! Nemůžete vytvořit rekurzivní přidružené členy."
|
||||
|
||||
#. module: base_vat
|
||||
#: field:res.company,vat_check_vies:0
|
||||
msgid "VIES VAT Check"
|
||||
msgstr ""
|
||||
msgstr "Kontrola DIČ přes VIES"
|
||||
|
||||
#. module: base_vat
|
||||
#: model:ir.model,name:base_vat.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
msgstr "Společnosti"
|
||||
|
||||
#. module: base_vat
|
||||
#: constraint:res.company:0
|
||||
msgid "Error! You can not create recursive companies."
|
||||
msgstr ""
|
||||
msgstr "Chyba! Nemůžete vytvořit rekurzivní společnosti."
|
||||
|
||||
#. module: base_vat
|
||||
#: help:res.partner,vat_subjected:0
|
||||
|
@ -55,11 +57,13 @@ msgid ""
|
|||
"Check this box if the partner is subjected to the VAT. It will be used for "
|
||||
"the VAT legal statement."
|
||||
msgstr ""
|
||||
"Zaškrtněte toto políčko, pokud partner podléhá DPH. Toto bude použito pro "
|
||||
"přiznání k DPH."
|
||||
|
||||
#. module: base_vat
|
||||
#: model:ir.model,name:base_vat.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
msgstr "Partner"
|
||||
|
||||
#. module: base_vat
|
||||
#: help:res.company,vat_check_vies:0
|
||||
|
@ -67,6 +71,8 @@ msgid ""
|
|||
"If checked, Partners VAT numbers will be fully validated against EU's VIES "
|
||||
"service rather than via a simple format validation (checksum)."
|
||||
msgstr ""
|
||||
"Pokud je zaškrtnuto, DIČ partnera bude plně ověřeno proti službě VIES EU "
|
||||
"raději než přes jednoduché ověření formátu (kontrolní součet)."
|
||||
|
||||
#. module: base_vat
|
||||
#: field:res.partner,vat_subjected:0
|
||||
|
|
|
@ -186,45 +186,4 @@ class board_line(osv.osv):
|
|||
'position': lambda *args: 'left'
|
||||
}
|
||||
|
||||
class res_log_report(osv.osv):
|
||||
""" Log Report """
|
||||
_name = "res.log.report"
|
||||
_auto = False
|
||||
_description = "Log Report"
|
||||
_columns = {
|
||||
'name': fields.char('Year', size=64, required=False, readonly=True),
|
||||
'month':fields.selection([('01', 'January'), ('02', 'February'), \
|
||||
('03', 'March'), ('04', 'April'),\
|
||||
('05', 'May'), ('06', 'June'), \
|
||||
('07', 'July'), ('08', 'August'),\
|
||||
('09', 'September'), ('10', 'October'),\
|
||||
('11', 'November'), ('12', 'December')], 'Month', readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'creation_date': fields.date('Creation Date', readonly=True),
|
||||
'res_model': fields.char('Object', size=128),
|
||||
'nbr': fields.integer('# of Entries', readonly=True)
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
"""
|
||||
Log Report
|
||||
@param cr: the current row, from the database cursor
|
||||
"""
|
||||
tools.drop_view_if_exists(cr,'res_log_report')
|
||||
cr.execute("""
|
||||
CREATE OR REPLACE VIEW res_log_report AS (
|
||||
SELECT
|
||||
l.id as id,
|
||||
1 as nbr,
|
||||
to_char(l.create_date, 'YYYY') as name,
|
||||
to_char(l.create_date, 'MM') as month,
|
||||
to_char(l.create_date, 'YYYY-MM-DD') as day,
|
||||
to_char(l.create_date, 'YYYY-MM-DD') as creation_date,
|
||||
l.res_model as res_model,
|
||||
date_trunc('day',l.create_date) as create_date
|
||||
FROM
|
||||
res_log l
|
||||
)""")
|
||||
res_log_report()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data>
|
||||
|
||||
<!-- User Connection -->
|
||||
<record model="ir.ui.view" id="view_user_connection_tree">
|
||||
<field name="name">user.connection.tree</field>
|
||||
|
@ -21,115 +22,11 @@
|
|||
<field name="view_id" ref="view_user_connection_tree"></field>
|
||||
</record>
|
||||
|
||||
<!-- Latest Activities -->
|
||||
<record model="ir.actions.act_window" id="action_latest_activities_tree">
|
||||
<field name="name">Latest Activities</field>
|
||||
<field name="res_model">res.log</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<!-- Log report search view -->
|
||||
<record id="view_res_log_report_filter" model="ir.ui.view">
|
||||
<field name="name">res.log.report.select</field>
|
||||
<field name="model">res.log.report</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Log Analysis">
|
||||
<group>
|
||||
<filter icon="terp-go-year" string=" Year "
|
||||
domain="[('create_date','<=', time.strftime('%%Y-%%m-%%d')),('create_date','>=',time.strftime('%%Y-01-01'))]"
|
||||
help="Log created in current year"/>
|
||||
<filter icon="terp-go-month" string=" Month "
|
||||
name="month"
|
||||
domain="[('create_date','<=',(datetime.date.today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('create_date','>=',(datetime.date.today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Log created in current month"/>
|
||||
<filter icon="terp-go-month"
|
||||
string=" Month-1 "
|
||||
domain="[('create_date','<=', (datetime.date.today() - relativedelta(day=31, months=1)).strftime('%%Y-%%m-%%d')),('create_date','>=',(datetime.date.today() - relativedelta(day=1,months=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Log created in last month"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="1" string="Group By...">
|
||||
<filter string="Model" icon="terp-go-home" context="{'group_by':'res_model'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Day" icon="terp-go-today"
|
||||
domain="[]" context="{'group_by':'day'}"/>
|
||||
<filter string="Month" icon="terp-go-month"
|
||||
domain="[]" context="{'group_by':'month'}" />
|
||||
<filter string="Year" icon="terp-go-year"
|
||||
domain="[]" context="{'group_by':'name'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Log report Tree view -->
|
||||
<record id="view_res_log_report_tree" model="ir.ui.view">
|
||||
<field name="name">res.log.report.tree</field>
|
||||
<field name="model">res.log.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Log Analysis">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="day" invisible="1"/>
|
||||
<field name="res_model" invisible="1"/>
|
||||
<field name="nbr" />
|
||||
<field name="creation_date" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="board_config_overview" model="ir.actions.client">
|
||||
<field name="name">Configuration Overview</field>
|
||||
<field name="tag">board.config.overview</field>
|
||||
</record>
|
||||
|
||||
<!-- Monthly Activity per Document -->
|
||||
<record id="board_res_log_report_graph" model="ir.ui.view">
|
||||
<field name="name">board.res.log.report.graph</field>
|
||||
<field name="model">res.log.report</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Monthly Activity per Document" type="bar">
|
||||
<field name="res_model"/>
|
||||
<field name="nbr" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record id="board_monthly_res_log_report_action" model="ir.actions.act_window">
|
||||
<field name="name">Monthly Activity per Document</field>
|
||||
<field name="res_model">res.log.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,tree</field>
|
||||
<field name="domain">[('create_date','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="context">{'group_by':['res_model'],'group_by_no_leaf':1}</field>
|
||||
<field name="view_id" ref="board_res_log_report_graph"></field>
|
||||
</record>
|
||||
|
||||
<!-- Weekly Global Activity -->
|
||||
<record id="board_weekly_res_log_report_graph" model="ir.ui.view">
|
||||
<field name="name">board.weekly.res.log.report.graph</field>
|
||||
<field name="model">res.log.report</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Weekly Global Activity" type="bar">
|
||||
<field name="day"/>
|
||||
<field name="nbr" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record id="board_weekly_res_log_report_action" model="ir.actions.act_window">
|
||||
<field name="name">Weekly Global Activity</field>
|
||||
<field name="res_model">res.log.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,tree</field>
|
||||
<field name="domain">[('create_date','>',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="context">{'group_by':['day'],'group_by_no_leaf':1}</field>
|
||||
<field name="view_id" ref="board_weekly_res_log_report_graph"></field>
|
||||
</record>
|
||||
|
||||
<record id="board_administration_form" model="ir.ui.view">
|
||||
<field name="name">board.administration.form</field>
|
||||
<field name="model">board.board</field>
|
||||
|
@ -164,5 +61,5 @@
|
|||
<menuitem id="base.menu_dashboard" name="Dashboards" parent="base.menu_reporting_board" sequence="0"/>
|
||||
<menuitem id="base.menu_dashboard_admin" action="open_board_administration_form" parent="base.menu_dashboard" icon="terp-graph"/>
|
||||
|
||||
</data>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -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-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2009-12-23 20:43+0000\n"
|
||||
"Last-Translator: Kuvaly [LCT] <kuvaly@seznam.cz>\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:15+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\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: 2012-02-09 06:40+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: board
|
||||
|
@ -40,13 +40,13 @@ msgstr "Poslední spojení"
|
|||
#. module: board
|
||||
#: view:res.log.report:0
|
||||
msgid "Log created in last month"
|
||||
msgstr ""
|
||||
msgstr "Záznam vytvořený minulý měsíc"
|
||||
|
||||
#. module: board
|
||||
#: view:board.board:0
|
||||
#: model:ir.actions.act_window,name:board.open_board_administration_form
|
||||
msgid "Administration Dashboard"
|
||||
msgstr "Správa nástěnky"
|
||||
msgstr "Nástěnka správy"
|
||||
|
||||
#. module: board
|
||||
#: view:res.log.report:0
|
||||
|
@ -56,7 +56,7 @@ msgstr "Seskupit podle..."
|
|||
#. module: board
|
||||
#: view:res.log.report:0
|
||||
msgid "Log created in current year"
|
||||
msgstr ""
|
||||
msgstr "Záznam vytvořený v tomto roce"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_board
|
||||
|
@ -93,7 +93,7 @@ msgstr "Měsíc"
|
|||
#. module: board
|
||||
#: view:res.log.report:0
|
||||
msgid "Log created in current month"
|
||||
msgstr ""
|
||||
msgstr "Záznam vytvořený v tomto měsíci"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.board_monthly_res_log_report_action
|
||||
|
@ -104,7 +104,7 @@ msgstr "Měsíční činnosti dle dokumentu"
|
|||
#. module: board
|
||||
#: view:board.board:0
|
||||
msgid "Configuration Overview"
|
||||
msgstr ""
|
||||
msgstr "Přehled nastavení"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.action_view_board_list_form
|
||||
|
@ -212,7 +212,7 @@ msgstr "Leden"
|
|||
#. module: board
|
||||
#: view:board.board:0
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
msgstr "Uživatelé"
|
||||
|
||||
#. module: board
|
||||
#: selection:res.log.report,month:0
|
||||
|
@ -265,7 +265,7 @@ msgstr "Model"
|
|||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.board_homepage_action
|
||||
msgid "Home Page"
|
||||
msgstr ""
|
||||
msgstr "Domovská stránka"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.action_latest_activities_tree
|
||||
|
|
|
@ -3,4 +3,3 @@ access_board_board all,board.board,model_board_board,,1,0,0,0
|
|||
access_board_board_line all,board.board.line,model_board_board_line,,1,0,0,0
|
||||
access_board_board system,board.board system,model_board_board,base.group_system,1,1,1,1
|
||||
access_board_board_line system,board.board.line system,model_board_board_line,base.group_system,1,1,1,1
|
||||
access_res_log_report all,res.log.report,model_res_log_report,,1,0,0,0
|
||||
|
|
|
|
@ -0,0 +1,23 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 04:57+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: claim_from_delivery
|
||||
#: model:ir.actions.act_window,name:claim_from_delivery.action_claim_from_delivery
|
||||
msgid "Claim"
|
||||
msgstr "Pohledávka"
|
|
@ -127,7 +127,7 @@ class crm_case_section(osv.osv):
|
|||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
"""Overrides orm name_get method"""
|
||||
if not isinstance(ids, list) :
|
||||
if not isinstance(ids, list) :
|
||||
ids = [ids]
|
||||
res = []
|
||||
if not ids:
|
||||
|
@ -256,7 +256,40 @@ class crm_base(object):
|
|||
data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
|
||||
return {'value': data}
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return ''
|
||||
|
||||
def case_open_send_note(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
msg = '%s has been <b>opened</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], body=msg, context=context)
|
||||
return True
|
||||
|
||||
def case_close_send_note(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
msg = '%s has been <b>closed</b>.'% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], body=msg, context=context)
|
||||
return True
|
||||
|
||||
def case_cancel_send_note(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
msg = '%s has been <b>canceled</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], body=msg, context=context)
|
||||
return True
|
||||
|
||||
def case_pending_send_note(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
msg = '%s is now <b>pending</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], body=msg, context=context)
|
||||
return True
|
||||
|
||||
def case_reset_send_note(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
msg = '%s has been <b>renewed</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], body=msg, context=context)
|
||||
return True
|
||||
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
"""Opens Case
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
|
@ -265,12 +298,13 @@ class crm_base(object):
|
|||
data = {'state': 'open', 'active': True}
|
||||
if not case.user_id:
|
||||
data['user_id'] = uid
|
||||
self.write(cr, uid, case.id, data)
|
||||
|
||||
self.write(cr, uid, [case.id], data)
|
||||
self.case_open_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'open')
|
||||
|
||||
return True
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
def case_close(self, cr, uid, ids, context=None):
|
||||
"""Closes Case
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
|
@ -278,10 +312,11 @@ class crm_base(object):
|
|||
cases[0].state # to fill the browse record cache
|
||||
self.write(cr, uid, ids, {'state': 'done', 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'), })
|
||||
# We use the cache of cases to keep the old case state
|
||||
self.case_close_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'done')
|
||||
return True
|
||||
|
||||
def case_cancel(self, cr, uid, ids, *args):
|
||||
def case_cancel(self, cr, uid, ids, context=None):
|
||||
"""Cancels Case
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
|
@ -289,26 +324,29 @@ class crm_base(object):
|
|||
cases[0].state # to fill the browse record cache
|
||||
self.write(cr, uid, ids, {'state': 'cancel', 'active': True})
|
||||
# We use the cache of cases to keep the old case state
|
||||
self.case_cancel_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'cancel')
|
||||
return True
|
||||
|
||||
def case_pending(self, cr, uid, ids, *args):
|
||||
def case_pending(self, cr, uid, ids, context=None):
|
||||
"""Marks case as pending
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.write(cr, uid, ids, {'state': 'pending', 'active': True})
|
||||
self.case_pending_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'pending')
|
||||
return True
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
def case_reset(self, cr, uid, ids, context=None):
|
||||
"""Resets case as draft
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.write(cr, uid, ids, {'state': 'draft', 'active': True})
|
||||
self.case_reset_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'draft')
|
||||
return True
|
||||
|
||||
|
@ -323,12 +361,12 @@ class crm_base(object):
|
|||
return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context)
|
||||
|
||||
class crm_case(crm_base):
|
||||
""" A simple python class to be used for common functions
|
||||
""" A simple python class to be used for common functions
|
||||
Object that inherit from this class should inherit from mailgate.thread
|
||||
And need a stage_id field
|
||||
And object that inherit (orm inheritance) from a class the overwrite copy
|
||||
And object that inherit (orm inheritance) from a class the overwrite copy
|
||||
"""
|
||||
|
||||
|
||||
def stage_find(self, cr, uid, section_id, domain=[], order='sequence'):
|
||||
domain = list(domain)
|
||||
if section_id:
|
||||
|
@ -387,34 +425,45 @@ class crm_case(crm_base):
|
|||
default.update({ 'date_open': False })
|
||||
return super(crm_case, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def case_escalate_send_note(self, cr, uid, ids, new_section=None, context=None):
|
||||
for id in ids:
|
||||
if new_section:
|
||||
msg = '%s has been <b>escalated</b> to <b>%s</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context), new_section.name)
|
||||
else:
|
||||
msg = '%s has been <b>escalated</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], 'System Notification', msg, context=context)
|
||||
return True
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return ''
|
||||
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
"""Opens Case"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
self.message_append(cr, uid, cases, _('Open'))
|
||||
for case in cases:
|
||||
data = {'state': 'open', 'active': True }
|
||||
if not case.user_id:
|
||||
data['user_id'] = uid
|
||||
self.write(cr, uid, case.id, data)
|
||||
self.write(cr, uid, [case.id], data)
|
||||
self.case_open_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'open')
|
||||
return True
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
def case_close(self, cr, uid, ids, context=None):
|
||||
"""Closes Case"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.message_append(cr, uid, cases, _('Close'))
|
||||
self.write(cr, uid, ids, {'state': 'done',
|
||||
'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
})
|
||||
#
|
||||
# We use the cache of cases to keep the old case state
|
||||
#
|
||||
self.case_close_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'done')
|
||||
return True
|
||||
|
||||
def case_escalate(self, cr, uid, ids, *args):
|
||||
def case_escalate(self, cr, uid, ids, context=None):
|
||||
"""Escalates case to parent level"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
for case in cases:
|
||||
|
@ -427,42 +476,37 @@ class crm_case(crm_base):
|
|||
else:
|
||||
raise osv.except_osv(_('Error !'), _('You can not escalate, you are already at the top level regarding your sales-team category.'))
|
||||
self.write(cr, uid, [case.id], data)
|
||||
case.case_escalate_send_note(case.section_id.parent_id)
|
||||
cases = self.browse(cr, uid, ids)
|
||||
self.message_append(cr, uid, cases, _('Escalate'))
|
||||
self._action(cr, uid, cases, 'escalate')
|
||||
return True
|
||||
|
||||
def case_cancel(self, cr, uid, ids, *args):
|
||||
def case_cancel(self, cr, uid, ids, context=None):
|
||||
"""Cancels Case"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.message_append(cr, uid, cases, _('Cancel'))
|
||||
self.write(cr, uid, ids, {'state': 'cancel',
|
||||
'active': True})
|
||||
self.case_cancel_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'cancel')
|
||||
for case in cases:
|
||||
message = _("The case '%s' has been cancelled.") % (case.name,)
|
||||
self.log(cr, uid, case.id, message)
|
||||
return True
|
||||
|
||||
def case_pending(self, cr, uid, ids, *args):
|
||||
def case_pending(self, cr, uid, ids, context=None):
|
||||
"""Marks case as pending"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.message_append(cr, uid, cases, _('Pending'))
|
||||
self.write(cr, uid, ids, {'state': 'pending', 'active': True})
|
||||
self.case_pending_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, 'pending')
|
||||
return True
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
def case_reset(self, cr, uid, ids, context=None):
|
||||
"""Resets case as draft"""
|
||||
state = 'draft'
|
||||
if 'crm.phonecall' in args:
|
||||
state = 'open'
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.message_append(cr, uid, cases, _('Draft'))
|
||||
self.write(cr, uid, ids, {'state': state, 'active': True})
|
||||
self.case_reset_send_note(cr, uid, ids, context=context)
|
||||
self._action(cr, uid, cases, state)
|
||||
return True
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
_name = "crm.lead"
|
||||
_description = "Lead/Opportunity"
|
||||
_order = "priority,date_action,id desc"
|
||||
_inherit = ['mail.thread','res.partner']
|
||||
_inherit = ['ir.needaction_mixin', 'mail.thread','res.partner']
|
||||
|
||||
def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
|
||||
access_rights_uid = access_rights_uid or uid
|
||||
|
@ -183,7 +183,6 @@ class crm_lead(crm_case, osv.osv):
|
|||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64),
|
||||
|
||||
|
||||
# Only used for type opportunity
|
||||
'probability': fields.float('Probability (%)',group_operator="avg"),
|
||||
'planned_revenue': fields.float('Expected Revenue'),
|
||||
|
@ -215,6 +214,19 @@ class crm_lead(crm_case, osv.osv):
|
|||
'color': 0,
|
||||
}
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids, [])
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
# salesman must perform an action when in draft mode
|
||||
if obj.state == 'draft' and obj.user_id:
|
||||
result[obj.id] = [obj.user_id.id]
|
||||
return result
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(crm_lead, self).create(cr, uid, vals, context)
|
||||
self.create_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def on_change_optin(self, cr, uid, ids, optin):
|
||||
return {'value':{'optin':optin,'optout':False}}
|
||||
|
||||
|
@ -248,75 +260,58 @@ class crm_lead(crm_case, osv.osv):
|
|||
def stage_find_won(self, cr, uid, section_id):
|
||||
return self.stage_find_percent(cr, uid, 100.0, section_id)
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
for l in self.browse(cr, uid, ids):
|
||||
# When coming from draft override date and stage otherwise just set state
|
||||
if l.state == 'draft':
|
||||
if l.type == 'lead':
|
||||
message = _("The lead '%s' has been opened.") % l.name
|
||||
elif l.type == 'opportunity':
|
||||
message = _("The opportunity '%s' has been opened.") % l.name
|
||||
else:
|
||||
message = _("The case '%s' has been opened.") % l.name
|
||||
self.log(cr, uid, l.id, message)
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
for lead in self.browse(cr, uid, ids, context=context):
|
||||
if lead.state == 'draft':
|
||||
value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}
|
||||
self.write(cr, uid, [l.id], value)
|
||||
if l.type == 'opportunity' and not l.stage_id:
|
||||
stage_id = self.stage_find(cr, uid, l.section_id.id or False, [('sequence','>',0)])
|
||||
self.write(cr, uid, [lead.id], value)
|
||||
if lead.type == 'opportunity' and not lead.stage_id:
|
||||
stage_id = self.stage_find(cr, uid, lead.section_id.id or False, [('sequence','>',0)])
|
||||
if stage_id:
|
||||
self.stage_set(cr, uid, [l.id], stage_id)
|
||||
res = super(crm_lead, self).case_open(cr, uid, ids, *args)
|
||||
self.stage_set(cr, uid, [lead.id], stage_id)
|
||||
res = super(crm_lead, self).case_open(cr, uid, ids, context)
|
||||
return res
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
|
||||
def case_close(self, cr, uid, ids, context=None):
|
||||
res = super(crm_lead, self).case_close(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
for case in self.browse(cr, uid, ids):
|
||||
if case.type == 'lead':
|
||||
message = _("The lead '%s' has been closed.") % case.name
|
||||
else:
|
||||
message = _("The case '%s' has been closed.") % case.name
|
||||
self.log(cr, uid, case.id, message)
|
||||
return res
|
||||
|
||||
def case_cancel(self, cr, uid, ids, *args):
|
||||
def case_cancel(self, cr, uid, ids, context=None):
|
||||
"""Overrides cancel for crm_case for setting probability
|
||||
"""
|
||||
res = super(crm_lead, self).case_cancel(cr, uid, ids, args)
|
||||
res = super(crm_lead, self).case_cancel(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'probability' : 0.0})
|
||||
return res
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
def case_reset(self, cr, uid, ids, context=None):
|
||||
"""Overrides reset as draft in order to set the stage field as empty
|
||||
"""
|
||||
res = super(crm_lead, self).case_reset(cr, uid, ids, *args)
|
||||
res = super(crm_lead, self).case_reset(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'stage_id': False, 'probability': 0.0})
|
||||
return res
|
||||
|
||||
def case_mark_lost(self, cr, uid, ids, *args):
|
||||
def case_mark_lost(self, cr, uid, ids, context=None):
|
||||
"""Mark the case as lost: state = done and probability = 0%
|
||||
"""
|
||||
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
|
||||
res = super(crm_lead, self).case_close(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'probability' : 0.0})
|
||||
for l in self.browse(cr, uid, ids):
|
||||
stage_id = self.stage_find_lost(cr, uid, l.section_id.id or False)
|
||||
for lead in self.browse(cr, uid, ids):
|
||||
stage_id = self.stage_find_lost(cr, uid, lead.section_id.id or False)
|
||||
if stage_id:
|
||||
self.stage_set(cr, uid, [l.id], stage_id)
|
||||
message = _("The opportunity '%s' has been marked as lost.") % l.name
|
||||
self.log(cr, uid, l.id, message)
|
||||
self.stage_set(cr, uid, [lead.id], stage_id)
|
||||
return res
|
||||
|
||||
def case_mark_won(self, cr, uid, ids, *args):
|
||||
def case_mark_won(self, cr, uid, ids, context=None):
|
||||
"""Mark the case as lost: state = done and probability = 0%
|
||||
"""
|
||||
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
|
||||
res = super(crm_lead, self).case_close(cr, uid, ids, context=None)
|
||||
self.write(cr, uid, ids, {'probability' : 100.0})
|
||||
for l in self.browse(cr, uid, ids):
|
||||
stage_id = self.stage_find_won(cr, uid, l.section_id.id or False)
|
||||
for lead in self.browse(cr, uid, ids):
|
||||
stage_id = self.stage_find_won(cr, uid, lead.section_id.id or False)
|
||||
if stage_id:
|
||||
self.stage_set(cr, uid, [l.id], stage_id)
|
||||
message = _("The opportunity '%s' has been been won.") % l.name
|
||||
self.log(cr, uid, l.id, message)
|
||||
self.stage_set(cr, uid, [lead.id], stage_id)
|
||||
self.case_mark_won_send_note(cr, uid, [lead.id], context=context)
|
||||
return res
|
||||
|
||||
def set_priority(self, cr, uid, ids, priority):
|
||||
|
@ -324,12 +319,12 @@ class crm_lead(crm_case, osv.osv):
|
|||
"""
|
||||
return self.write(cr, uid, ids, {'priority' : priority})
|
||||
|
||||
def set_high_priority(self, cr, uid, ids, *args):
|
||||
def set_high_priority(self, cr, uid, ids, context=None):
|
||||
"""Set lead priority to high
|
||||
"""
|
||||
return self.set_priority(cr, uid, ids, '1')
|
||||
|
||||
def set_normal_priority(self, cr, uid, ids, *args):
|
||||
def set_normal_priority(self, cr, uid, ids, context=None):
|
||||
"""Set lead priority to normal
|
||||
"""
|
||||
return self.set_priority(cr, uid, ids, '3')
|
||||
|
@ -422,7 +417,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
|
||||
subject = subject[0] + ", ".join(subject[1:])
|
||||
details = "\n\n".join(details)
|
||||
return self.message_append(cr, uid, [opportunity_id], subject, body_text=details, context=context)
|
||||
return self.message_append_note(cr, uid, [opportunity_id], subject=subject, body=details)
|
||||
|
||||
def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None):
|
||||
message = self.pool.get('mail.message')
|
||||
|
@ -529,13 +524,6 @@ class crm_lead(crm_case, osv.osv):
|
|||
'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
}
|
||||
|
||||
def _convert_opportunity_notification(self, cr, uid, lead, context=None):
|
||||
success_message = _("Lead '%s' has been converted to an opportunity.") % lead.name
|
||||
self.message_append(cr, uid, [lead.id], success_message, body_text=success_message, context=context)
|
||||
self.log(cr, uid, lead.id, success_message)
|
||||
self._send_mail_to_salesman(cr, uid, lead, context=context)
|
||||
return True
|
||||
|
||||
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
|
||||
partner = self.pool.get('res.partner')
|
||||
mail_message = self.pool.get('mail.message')
|
||||
|
@ -551,7 +539,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
|
||||
self.write(cr, uid, [lead.id], vals, context=context)
|
||||
|
||||
self._convert_opportunity_notification(cr, uid, lead, context=context)
|
||||
self.convert_opportunity_send_note(cr, uid, lead, context=context)
|
||||
#TOCHECK: why need to change partner details in all messages of lead ?
|
||||
if lead.partner_id:
|
||||
msg_ids = [ x.id for x in lead.message_ids]
|
||||
|
@ -605,6 +593,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id.id or False})
|
||||
contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
|
||||
res = lead.write({'partner_id' : partner_id, }, context=context)
|
||||
self._lead_set_partner_send_note(cr, uid, [lead.id], context)
|
||||
return res
|
||||
|
||||
def convert_partner(self, cr, uid, ids, action='create', partner_id=False, context=None):
|
||||
|
@ -684,12 +673,12 @@ class crm_lead(crm_case, osv.osv):
|
|||
'partner_mobile' : lead.partner_id and lead.partner_id.mobile or False,
|
||||
'priority': lead.priority,
|
||||
}
|
||||
|
||||
new_id = phonecall.create(cr, uid, vals, context=context)
|
||||
phonecall.case_open(cr, uid, [new_id])
|
||||
phonecall.case_open(cr, uid, [new_id], context=context)
|
||||
if action == 'log':
|
||||
phonecall.case_close(cr, uid, [new_id])
|
||||
phonecall.case_close(cr, uid, [new_id], context=context)
|
||||
phonecall_dict[lead.id] = new_id
|
||||
self.schedule_phonecall_send_note(cr, uid, [lead.id], new_id, action, context=context)
|
||||
return phonecall_dict
|
||||
|
||||
|
||||
|
@ -767,7 +756,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
#re-open
|
||||
values.update(state=crm.AVAILABLE_STATES[1][0])
|
||||
if not case.date_open:
|
||||
values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
res = self.write(cr, uid, [case.id], values, context=context)
|
||||
return res
|
||||
|
||||
|
@ -831,17 +820,59 @@ class crm_lead(crm_case, osv.osv):
|
|||
# change probability of lead(s) if required by stage
|
||||
if not vals.get('probability') and stage.on_change:
|
||||
vals['probability'] = stage.probability
|
||||
text = _("Changed Stage to: %s") % stage.name
|
||||
self.message_append(cr, uid, ids, text, body_text=text, context=context)
|
||||
for case in self.browse(cr, uid, ids, context=context):
|
||||
if case.type == 'lead' or context.get('stage_type') == 'lead':
|
||||
message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage.name)
|
||||
self.log(cr, uid, case.id, message)
|
||||
elif case.type == 'opportunity':
|
||||
message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage.name)
|
||||
self.log(cr, uid, case.id, message)
|
||||
|
||||
message = _("Stage changed to <b>%s</b>.") % (stage.name)
|
||||
case.message_append_note(body=message)
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context)
|
||||
|
||||
# ----------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
# ----------------------------------------
|
||||
|
||||
def message_get_subscribers(self, cr, uid, ids, context=None):
|
||||
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context)
|
||||
# add salesman to the subscribers
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.user_id:
|
||||
sub_ids.append(obj.user_id.id)
|
||||
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, lead, context=None):
|
||||
if isinstance(lead, (int, long)):
|
||||
lead = self.browse(cr, uid, [lead], context=context)[0]
|
||||
return ('Opportunity' if lead.type == 'opportunity' else 'Lead')
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
message = _("%s has been <b>created</b>.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
|
||||
self.message_append_note(cr, uid, [id], body=message, context=context)
|
||||
return True
|
||||
|
||||
def case_mark_lost_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Opportunity has been <b>lost</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def case_mark_won_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Opportunity has been <b>won</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None):
|
||||
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0]
|
||||
if action == 'log': prefix = 'Logged'
|
||||
else: prefix = 'Scheduled'
|
||||
message = _("<b>%s a call</b> for the <em>%s</em>.") % (prefix, phonecall.date)
|
||||
return self. message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def _lead_set_partner_send_note(self, cr, uid, ids, context=None):
|
||||
for lead in self.browse(cr, uid, ids, context=context):
|
||||
message = _("%s <b>partner</b> is now set to <em>%s</em>." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name))
|
||||
lead.message_append_note(body=message)
|
||||
return True
|
||||
|
||||
def convert_opportunity_send_note(self, cr, uid, lead, context=None):
|
||||
message = _("Lead has been <b>converted to an opportunity</b>.")
|
||||
lead.message_append_note(body=message)
|
||||
return True
|
||||
|
||||
crm_lead()
|
||||
|
||||
|
|
|
@ -220,21 +220,21 @@
|
|||
</record>
|
||||
|
||||
<!-- Call Function to Open the leads-->
|
||||
<function model="crm.lead" name="case_open">
|
||||
<value eval="[ref('crm_case_electonicgoodsdealer0'), ref('crm_case_company_partnership0'), ref('crm_case_webvisitor0'), ref('crm_case_business_card0'), ref('crm.crm_case_employee0')]"/>
|
||||
</function>
|
||||
<function model="crm.lead" name="case_open"
|
||||
eval="[ref('crm_case_electonicgoodsdealer0'), ref('crm_case_company_partnership0'), ref('crm_case_webvisitor0'), ref('crm_case_business_card0'), ref('crm.crm_case_employee0')], {'install_mode': True}"
|
||||
/>
|
||||
<!-- Call Function to mark the lead as Pending-->
|
||||
<function model="crm.lead" name="case_pending">
|
||||
<value eval="[ref('crm_case_itdeveloper0')]"/>
|
||||
</function>
|
||||
<function model="crm.lead" name="case_pending"
|
||||
eval="[ref('crm_case_itdeveloper0')], {'install_mode': True}"
|
||||
/>
|
||||
<!-- Call Function to Close the leads-->
|
||||
<function model="crm.lead" name="case_close">
|
||||
<value eval="[ref('crm_case_vpoperations0'), ref('crm_case_developingwebapplications0'), ref('crm_case_webvisitor0')]"/>
|
||||
</function>
|
||||
<function model="crm.lead" name="case_close"
|
||||
eval="[ref('crm_case_vpoperations0'), ref('crm_case_developingwebapplications0'), ref('crm_case_webvisitor0')], {'install_mode': True}"
|
||||
/>
|
||||
<!-- Call Function to Cancel the leads-->
|
||||
<function model="crm.lead" name="case_cancel">
|
||||
<value eval="[ref('crm_case_mgroperations0'), ref('crm_case_imported_contact0')]"/>
|
||||
</function>
|
||||
<function model="crm.lead" name="case_cancel"
|
||||
eval="[ref('crm_case_mgroperations0'), ref('crm_case_imported_contact0')], {'install_mode': True}"
|
||||
/>
|
||||
|
||||
<!-- Demo Opportunities -->
|
||||
<record id="crm_case_construstazunits0" model="crm.lead">
|
||||
|
|
|
@ -143,29 +143,6 @@
|
|||
type="object" icon="gtk-convert" />
|
||||
</group>
|
||||
</page>
|
||||
<page string="Communication & History" groups="base.group_extended">
|
||||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" widget="char" size="512"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Extra Info" groups="base.group_extended">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Categorization" colspan="2" col="2"/>
|
||||
|
@ -176,13 +153,6 @@
|
|||
<field name="channel_id" select="1" widget="selection"/>
|
||||
<field name="referred"/>
|
||||
</group>
|
||||
<group colspan="2" col="2" groups="base.group_no_one">
|
||||
<separator string="Dates" colspan="2" col="2"/>
|
||||
<field name="create_date"/>
|
||||
<field name="write_date"/>
|
||||
<field name="date_open"/>
|
||||
<field name="date_closed"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Mailings" colspan="2" col="2"/>
|
||||
<field name="optin" on_change="on_change_optin(optin)"/>
|
||||
|
@ -195,6 +165,7 @@
|
|||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -545,37 +516,7 @@
|
|||
<field name="optout" on_change="on_change_optout(optout)"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Communication & History" groups="base.group_extended">
|
||||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" widget="char" size="512"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Extra Info" groups="base.group_extended">
|
||||
<group col="2" colspan="2" groups="base.group_no_one">
|
||||
<separator string="Dates" colspan="2"/>
|
||||
<field name="create_date"/>
|
||||
<field name="write_date"/>
|
||||
<field name="date_closed"/>
|
||||
<field name="date_open"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Misc" colspan="2"/>
|
||||
<field name="active"/>
|
||||
|
@ -588,6 +529,7 @@
|
|||
<field name="ref2"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -42,7 +42,7 @@ class crm_meeting(crm_base, osv.osv):
|
|||
_name = 'crm.meeting'
|
||||
_description = "Meeting"
|
||||
_order = "id desc"
|
||||
_inherit = "calendar.event"
|
||||
_inherit = ["calendar.event", 'ir.needaction_mixin', "mail.thread"]
|
||||
_columns = {
|
||||
# From crm.case
|
||||
'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
|
||||
|
@ -78,7 +78,55 @@ class crm_meeting(crm_base, osv.osv):
|
|||
'user_id': lambda self, cr, uid, ctx: uid,
|
||||
}
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(crm_meeting, self).create(cr, uid, vals, context=context)
|
||||
self.create_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids, [])
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if (obj.state == 'draft' and obj.user_id):
|
||||
result[obj.id] = [obj.user_id.id]
|
||||
return result
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return 'Meeting'
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
# update context: if come from phonecall, default state values can make the message_append_note crash
|
||||
context.pop('default_state', False)
|
||||
for meeting in self.browse(cr, uid, ids, context=context):
|
||||
message = _("A meeting has been <b>scheduled</b> on <em>%s</em>.") % (meeting.date)
|
||||
if meeting.opportunity_id: # meeting can be create from phonecalls or opportunities, therefore checking for the parent
|
||||
lead = meeting.opportunity_id
|
||||
parent_message = _("Meeting linked to the opportunity <em>%s</em> has been <b>created</b> and <b>cscheduled</b> on <em>%s</em>.") % (lead.name, meeting.date)
|
||||
lead.message_append_note(_('System Notification'), message)
|
||||
elif meeting.phonecall_id:
|
||||
phonecall = meeting.phonecall_id
|
||||
parent_message = _("Meeting linked to the phonecall <em>%s</em> has been <b>created</b> and <b>cscheduled</b> on <em>%s</em>.") % (phonecall.name, meeting.date)
|
||||
phonecall.message_append_note(body=message)
|
||||
else:
|
||||
parent_message = message
|
||||
if parent_message:
|
||||
meeting.message_append_note(body=parent_message)
|
||||
return True
|
||||
|
||||
def case_close_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Meeting has been <b>done</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def case_open_send_note(self, cr, uid, ids, context=None):
|
||||
for meeting in self.browse(cr, uid, ids, context=context):
|
||||
if meeting.state != 'draft':
|
||||
return False
|
||||
message = _("Meeting has been <b>confirmed</b>.")
|
||||
meeting.message_append_note(body=message)
|
||||
return True
|
||||
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
"""Confirms meeting
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
|
@ -86,11 +134,9 @@ class crm_meeting(crm_base, osv.osv):
|
|||
@param ids: List of Meeting Ids
|
||||
@param *args: Tuple Value for additional Params
|
||||
"""
|
||||
res = super(crm_meeting, self).case_open(cr, uid, ids, args)
|
||||
res = super(crm_meeting, self).case_open(cr, uid, ids, context)
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _("The meeting '%s' has been confirmed.") % name
|
||||
id=base_calendar.base_calendar_id2real_id(id)
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
crm_meeting()
|
||||
|
|
|
@ -212,6 +212,7 @@
|
|||
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -32,6 +32,7 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
_name = "crm.phonecall"
|
||||
_description = "Phonecall"
|
||||
_order = "id desc"
|
||||
_inherit = ['ir.needaction_mixin', 'mail.thread']
|
||||
_columns = {
|
||||
# From crm.case
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
|
@ -47,12 +48,12 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'description': fields.text('Description'),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('open', 'Todo'),
|
||||
('cancel', 'Cancelled'),
|
||||
('done', 'Held'),
|
||||
('draft', 'Draft'),
|
||||
('open', 'Todo'),
|
||||
('cancel', 'Cancelled'),
|
||||
('done', 'Held'),
|
||||
('pending', 'Not Held'),
|
||||
], 'State', size=16, readonly=True,
|
||||
], 'State', size=16, readonly=True,
|
||||
help='The state is set to \'Todo\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the call is over, the state is set to \'Held\'.\
|
||||
|
@ -67,9 +68,9 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
}
|
||||
|
||||
|
@ -80,13 +81,20 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
|
||||
_defaults = {
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'priority': crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'state': _get_default_state,
|
||||
'priority': crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'state': _get_default_state,
|
||||
'user_id': lambda self,cr,uid,ctx: uid,
|
||||
'active': 1,
|
||||
}
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(crm_phonecall, self).create(cr, uid, vals, context)
|
||||
for phonecall in self.browse(cr, uid, [obj_id], context=context):
|
||||
if not phonecall.opportunity_id:
|
||||
self.case_open_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def case_close(self, cr, uid, ids, context=None):
|
||||
"""Overrides close for crm_case for setting close date
|
||||
"""
|
||||
res = True
|
||||
|
@ -96,22 +104,22 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
if phone.duration <=0:
|
||||
duration = datetime.now() - datetime.strptime(phone.date, '%Y-%m-%d %H:%M:%S')
|
||||
data.update({'duration': duration.seconds/float(60)})
|
||||
res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], args)
|
||||
res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], context)
|
||||
self.write(cr, uid, [phone_id], data)
|
||||
return res
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
def case_reset(self, cr, uid, ids, context=None):
|
||||
"""Resets case as Todo
|
||||
"""
|
||||
res = super(crm_phonecall, self).case_reset(cr, uid, ids, args, 'crm.phonecall')
|
||||
res = super(crm_phonecall, self).case_reset(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'duration': 0.0, 'state':'open'})
|
||||
return res
|
||||
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
"""Overrides cancel for crm_case for setting Open Date
|
||||
"""
|
||||
res = super(crm_phonecall, self).case_open(cr, uid, ids, *args)
|
||||
res = super(crm_phonecall, self).case_open(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
return res
|
||||
|
||||
|
@ -143,9 +151,7 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
'partner_mobile' : call.partner_mobile,
|
||||
'priority': call.priority,
|
||||
}
|
||||
|
||||
new_id = self.create(cr, uid, vals, context=context)
|
||||
self.case_open(cr, uid, [new_id])
|
||||
if action == 'log':
|
||||
self.case_close(cr, uid, [new_id])
|
||||
phonecall_dict[call.id] = new_id
|
||||
|
@ -162,7 +168,9 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
return partner_id
|
||||
|
||||
def _call_set_partner(self, cr, uid, ids, partner_id, context=None):
|
||||
return self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
|
||||
write_res = self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
|
||||
self._call_set_partner_send_note(cr, uid, ids, context)
|
||||
return write_res
|
||||
|
||||
def _call_create_partner_address(self, cr, uid, phonecall, partner_id, context=None):
|
||||
address = self.pool.get('res.partner')
|
||||
|
@ -231,7 +239,7 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
'section_id': call.section_id and call.section_id.id or False,
|
||||
'description': call.description or False,
|
||||
'priority': call.priority,
|
||||
'type': 'opportunity',
|
||||
'type': 'opportunity',
|
||||
'phone': call.partner_phone or False,
|
||||
'email_from': default_contact and default_contact.email,
|
||||
})
|
||||
|
@ -243,7 +251,7 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
self.case_close(cr, uid, [call.id])
|
||||
opportunity.case_open(cr, uid, [opportunity_id])
|
||||
opportunity_dict[call.id] = opportunity_id
|
||||
return opportunity_dict
|
||||
return opportunity_dict
|
||||
|
||||
def action_make_meeting(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
|
@ -289,6 +297,41 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
}
|
||||
|
||||
return value
|
||||
|
||||
# ----------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
# ----------------------------------------
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids)
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
result[obj.id] = []
|
||||
if (obj.state == 'draft' and obj.user_id):
|
||||
result[obj.id] = [obj.user_id.id]
|
||||
return result
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return 'Phonecall'
|
||||
|
||||
def case_reset_send_note(self, cr, uid, ids, context=None):
|
||||
message = _('Phonecall has been <b>reset and set as open</b>.')
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def case_open_send_note(self, cr, uid, ids, context=None):
|
||||
lead_obj = self.pool.get('crm.lead')
|
||||
for phonecall in self.browse(cr, uid, ids, context=context):
|
||||
phonecall.message_subscribe([phonecall.user_id.id], context=context)
|
||||
if phonecall.opportunity_id:
|
||||
lead = phonecall.opportunity_id
|
||||
message = _("Phonecall linked to the opportunity <em>%s</em> has been <b>created</b> and <b>scheduled</b> on <em>%s</em>.") % (lead.name, phonecall.date)
|
||||
else:
|
||||
message = _("Phonecall has been <b>created and opened</b>.")
|
||||
phonecall.message_append_note(body=message)
|
||||
return True
|
||||
|
||||
def _call_set_partner_send_note(self, cr, uid, ids, context=None):
|
||||
return self.message_append_note(cr, uid, ids, body=_("Partner has been <b>created</b>"), context=context)
|
||||
|
||||
|
||||
crm_phonecall()
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@
|
|||
states="cancel" type="object"
|
||||
icon="gtk-convert" />
|
||||
</group>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<menuitem icon="terp-partner" id="base.menu_base_partner" name="Sales" sequence="0"
|
||||
<menuitem icon="terp-partner" id="base.menu_base_partner" name="Sales" sequence="1"
|
||||
groups="base.group_sale_manager,base.group_sale_salesman"/>
|
||||
|
||||
<menuitem id="base.menu_crm_config_lead" name="Leads & Opportunities"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 07:00+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: crm_caldav
|
||||
#: model:ir.actions.act_window,name:crm_caldav.action_caldav_browse
|
||||
msgid "Caldav Browse"
|
||||
msgstr "Procházet Caldav"
|
||||
|
||||
#. module: crm_caldav
|
||||
#: model:ir.ui.menu,name:crm_caldav.menu_caldav_browse
|
||||
msgid "Synchronize This Calendar"
|
||||
msgstr "Synchronizovat tento kalendář"
|
||||
|
||||
#. module: crm_caldav
|
||||
#: model:ir.model,name:crm_caldav.model_crm_meeting
|
||||
msgid "Meeting"
|
||||
msgstr "Setkání"
|
|
@ -95,6 +95,9 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
'active': lambda *a: 1
|
||||
}
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return 'Claim'
|
||||
|
||||
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
|
||||
|
|
|
@ -125,7 +125,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
if email_to not in new_cc:
|
||||
new_cc.append(to)
|
||||
update_vals = {'email_cc' : ', '.join(new_cc) }
|
||||
lead.write(cr, uid, case.id, update_vals, context=context)
|
||||
lead.write(cr, uid, [case.id], update_vals, context=context)
|
||||
return res
|
||||
|
||||
def _get_info_body_text(self, cr, uid, lead, context=None):
|
||||
|
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-06 04:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: crm_todo
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 05:28+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: field:decimal.precision,digits:0
|
||||
msgid "Digits"
|
||||
msgstr "Číslice"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: model:ir.actions.act_window,name:decimal_precision.action_decimal_precision_form
|
||||
#: model:ir.ui.menu,name:decimal_precision.menu_decimal_precision_form
|
||||
msgid "Decimal Accuracy"
|
||||
msgstr "Desetinná přesnost"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: field:decimal.precision,name:0
|
||||
msgid "Usage"
|
||||
msgstr "Použití"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: sql_constraint:decimal.precision:0
|
||||
msgid "Only one value can be defined for each given usage!"
|
||||
msgstr "Pro každé dané použití může být zadána jen jedna hodnota."
|
||||
|
||||
#. module: decimal_precision
|
||||
#: view:decimal.precision:0
|
||||
msgid "Decimal Precision"
|
||||
msgstr "Desetinná přesnost"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: model:ir.model,name:decimal_precision.model_decimal_precision
|
||||
msgid "decimal.precision"
|
||||
msgstr "decimal.precision"
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-09-05 17:16+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:26+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-02-09 06:48+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: document
|
||||
|
@ -152,7 +152,7 @@ msgstr "Název adresáře musí být unikátní!"
|
|||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Filter on my documents"
|
||||
msgstr ""
|
||||
msgstr "Filtr nad mými dokumenty"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.attachment,index_content:0
|
||||
|
@ -171,7 +171,7 @@ msgstr ""
|
|||
#. module: document
|
||||
#: model:ir.actions.todo.category,name:document.category_knowledge_mgmt_config
|
||||
msgid "Knowledge Management"
|
||||
msgstr ""
|
||||
msgstr "Správa znalostí"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
|
@ -385,6 +385,8 @@ msgid ""
|
|||
"When executing this wizard, it will configure your directories automatically "
|
||||
"according to modules installed."
|
||||
msgstr ""
|
||||
"Když je tento průvodce vykonán, nastaví automaticky vaše adresáře podle "
|
||||
"instalovaných modulů."
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,directory_id:0
|
||||
|
@ -520,7 +522,7 @@ msgstr ""
|
|||
#: view:document.configuration:0
|
||||
#: model:ir.actions.act_window,name:document.action_config_auto_directory
|
||||
msgid "Configure Directories"
|
||||
msgstr ""
|
||||
msgstr "Nastavit adresáře"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,include_name:0
|
||||
|
@ -674,7 +676,7 @@ msgstr "Pouze ke čtení"
|
|||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_document_directory_form
|
||||
msgid "Document Directory"
|
||||
msgstr ""
|
||||
msgstr "Adresář dokumentů"
|
||||
|
||||
#. module: document
|
||||
#: sql_constraint:document.directory:0
|
||||
|
@ -700,6 +702,10 @@ msgid ""
|
|||
"attached to the document, or to print and download any report. This tool "
|
||||
"will create directories automatically according to modules installed."
|
||||
msgstr ""
|
||||
"Systém správy dokumentů OpenERP podporuje mapování virtuálních složek s "
|
||||
"dokumenty. Virtuální složka dokumentů může být použita pro správu souborů "
|
||||
"přiložených k dokumentům nebo k vytištění a stažení jakéhokoliv výkazu. "
|
||||
"Tento nástroj vytvoří automaticky adresář podle instalovaných modulů."
|
||||
|
||||
#. module: document
|
||||
#: view:board.board:0
|
||||
|
@ -793,7 +799,7 @@ msgstr "Měsíc"
|
|||
#. module: document
|
||||
#: view:report.document.user:0
|
||||
msgid "This Months Files"
|
||||
msgstr ""
|
||||
msgstr "Soubory za tyto měsíce"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_reporting
|
||||
|
@ -859,7 +865,7 @@ msgstr "Soubory podle partnerů"
|
|||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Indexed Content - experimental"
|
||||
msgstr ""
|
||||
msgstr "Indexovaný obsah - pokusné"
|
||||
|
||||
#. module: document
|
||||
#: view:report.document.user:0
|
||||
|
@ -874,7 +880,7 @@ msgstr "Poznámky"
|
|||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_configuration
|
||||
msgid "Directory Configuration"
|
||||
msgstr ""
|
||||
msgstr "Nastavení adresáře"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,type:0
|
||||
|
@ -977,7 +983,7 @@ msgstr "MIME typ"
|
|||
#. module: document
|
||||
#: view:report.document.user:0
|
||||
msgid "All Months Files"
|
||||
msgstr ""
|
||||
msgstr "Soubory za všechny měsíce"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,name:0
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-05-09 08:15+0000\n"
|
||||
"Last-Translator: Jan B. Krejčí <Unknown>\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:13+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-02-09 07:06+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: document_ftp
|
||||
#: model:ir.model,name:document_ftp.model_document_ftp_configuration
|
||||
|
@ -31,6 +31,10 @@ msgid ""
|
|||
"format is HOST:PORT and the default host (localhost) is only suitable for "
|
||||
"access from the server machine itself.."
|
||||
msgstr ""
|
||||
"Značí adresu sítě, na které by měl být pro koncové uživatel dostupný váš "
|
||||
"OpenERP server. To závisí na vaší síťové topologii a nastavení a ovlivní to "
|
||||
"pouze odkazy zobrazené uživatelům. Formát je POĆÍTAČ:PORT a výchozí počítač "
|
||||
"(localhost) je vhodný pouze pro přístup ze samotného serveru."
|
||||
|
||||
#. module: document_ftp
|
||||
#: model:ir.actions.url,name:document_ftp.action_document_browse
|
||||
|
@ -67,6 +71,8 @@ msgstr "_Procházet"
|
|||
msgid ""
|
||||
"Server address or IP and port to which users should connect to for DMS access"
|
||||
msgstr ""
|
||||
"Adresa serveru nebo IP a port, ke kterému by se měli uživatelé připojit pro "
|
||||
"přístup DMS"
|
||||
|
||||
#. module: document_ftp
|
||||
#: model:ir.ui.menu,name:document_ftp.menu_document_browse
|
||||
|
@ -91,27 +97,27 @@ msgstr "název"
|
|||
#. module: document_ftp
|
||||
#: model:ir.model,name:document_ftp.model_document_ftp_browse
|
||||
msgid "Document FTP Browse"
|
||||
msgstr ""
|
||||
msgstr "Procházení FTP dokumentů"
|
||||
|
||||
#. module: document_ftp
|
||||
#: view:document.ftp.configuration:0
|
||||
msgid "Knowledge Application Configuration"
|
||||
msgstr ""
|
||||
msgstr "Nastavení aplikace znalostí"
|
||||
|
||||
#. module: document_ftp
|
||||
#: model:ir.actions.act_window,name:document_ftp.action_ftp_browse
|
||||
msgid "Document Browse"
|
||||
msgstr ""
|
||||
msgstr "Procházení dokumentů"
|
||||
|
||||
#. module: document_ftp
|
||||
#: view:document.ftp.browse:0
|
||||
msgid "Browse Document"
|
||||
msgstr ""
|
||||
msgstr "Procházet dokument"
|
||||
|
||||
#. module: document_ftp
|
||||
#: view:document.ftp.configuration:0
|
||||
msgid "res_config_contents"
|
||||
msgstr ""
|
||||
msgstr "res_config_contents"
|
||||
|
||||
#~ msgid "Integrated FTP Server with Document Management System"
|
||||
#~ msgstr "FTP server integrovaný s Document Management Systémem"
|
||||
|
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-06 04:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: edi
|
||||
|
|
|
@ -387,6 +387,7 @@
|
|||
</group>
|
||||
</page>
|
||||
<page string="Emails" groups="base.group_extended">
|
||||
<!--
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
|
@ -398,6 +399,7 @@
|
|||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
</field>
|
||||
-->
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" context= '{"default_email_to":email}' type="action"/>
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
action="action_email_server_tree"
|
||||
name="Incoming Mail Servers"
|
||||
sequence="14"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
|
||||
<record model="ir.ui.view" id="email_message_tree_view">
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# Japanese 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-08 05:43+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: 2012-04-09 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: fetchmail_crm_claim
|
||||
#: model:ir.actions.act_window,help:fetchmail_crm_claim.action_create_crm_claims_from_email_account
|
||||
msgid ""
|
||||
"You can connect your email account with claims in OpenERP. A new email sent "
|
||||
"to this account (example: support@mycompany.com) will automatically create a "
|
||||
"claim for the followup in OpenERP. The whole communication by email will be "
|
||||
"attached to the claim automatically to keep track of the history."
|
||||
msgstr ""
|
||||
"あなたのEメールアカウントをOpenERPのクレームに関連づけることはできません。このアカウントに送られた新しいEメールはOpenERPのフォローアップの"
|
||||
"ためのクレームを自動的に作成します。Eメールによる全てのコミュニケーションは、履歴を記録するために、自動的にクレームに関連づけられます。"
|
||||
|
||||
#. module: fetchmail_crm_claim
|
||||
#: model:ir.actions.act_window,name:fetchmail_crm_claim.action_create_crm_claims_from_email_account
|
||||
msgid "Create Claims from Email Account"
|
||||
msgstr "Eメールアカウントからクレームを作成"
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-06 04:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: google_base_account
|
||||
|
|
|
@ -189,6 +189,7 @@
|
|||
<field name="name">Minh Tran</field>
|
||||
<field name="user_id" ref="base.user_mit"/>
|
||||
<field name="department_id" ref="dep_rd"/>
|
||||
<field name="parent_id" ref="employee_al"/>
|
||||
<field name="job_id" ref="hr.job_developer"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -202,6 +203,7 @@
|
|||
<field name="name">Nicolas Vanhoren</field>
|
||||
<field name="user_id" ref="base.user_niv"/>
|
||||
<field name="department_id" ref="dep_rd"/>
|
||||
<field name="parent_id" ref="employee_al"/>
|
||||
<field name="job_id" ref="hr.job_developer"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -214,6 +216,7 @@
|
|||
<field name="name">Stéphane Wirtel</field>
|
||||
<field name="user_id" ref="base.user_stw"/>
|
||||
<field name="department_id" ref="dep_rd"/>
|
||||
<field name="parent_id" ref="employee_al"/>
|
||||
<field name="job_id" ref="hr.job_developer"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -226,6 +229,7 @@
|
|||
<field name="name">Christophe Simonis</field>
|
||||
<field name="user_id" ref="base.user_chs"/>
|
||||
<field name="department_id" ref="dep_rd"/>
|
||||
<field name="parent_id" ref="employee_al"/>
|
||||
<field name="job_id" ref="hr.job_developer"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -238,6 +242,7 @@
|
|||
<field name="name">Quentin De Paoli</field>
|
||||
<field name="user_id" ref="base.user_qdp"/>
|
||||
<field name="department_id" ref="dep_rd"/>
|
||||
<field name="parent_id" ref="employee_al"/>
|
||||
<field name="job_id" ref="hr.job_developer"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -249,6 +254,7 @@
|
|||
<field name="name">Fabien Meghazi</field>
|
||||
<field name="user_id" ref="base.user_fme"/>
|
||||
<field name="department_id" ref="dep_rd"/>
|
||||
<field name="parent_id" ref="employee_al"/>
|
||||
<field name="job_id" ref="hr.job_developer"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -260,6 +266,7 @@
|
|||
<field name="name">Francois Pietquin</field>
|
||||
<field name="user_id" ref="base.user_fpi"/>
|
||||
<field name="department_id" ref="dep_ps"/>
|
||||
<field name="parent_id" ref="employee_fp"/>
|
||||
<field name="job_id" ref="hr.job_consultant"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -272,6 +279,7 @@
|
|||
<field name="name">Julien Thewys</field>
|
||||
<field name="user_id" ref="base.user_jth"/>
|
||||
<field name="department_id" ref="dep_ps"/>
|
||||
<field name="parent_id" ref="employee_fp"/>
|
||||
<field name="job_id" ref="hr.job_consultant"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
@ -284,6 +292,7 @@
|
|||
<field name="name">Nicoleta Gherlea</field>
|
||||
<field name="user_id" ref="base.user_ngh"/>
|
||||
<field name="department_id" ref="dep_sales"/>
|
||||
<field name="parent_id" ref="employee_fp"/>
|
||||
<field name="job_id" ref="hr.job_marketing"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Auderghem</field>
|
||||
|
@ -296,6 +305,7 @@
|
|||
<field name="name">Valérie Descamps</field>
|
||||
<field name="user_id" ref="base.user_vad"/>
|
||||
<field name="department_id" ref="dep_administration"/>
|
||||
<field name="parent_id" ref="employee_fp"/>
|
||||
<field name="job_id" ref="hr.job_hrm"/>
|
||||
<field name="category_ids" eval="[(6, 0, [ref('category_employee')])]"/>
|
||||
<field name="work_location">Grand-Rosière</field>
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2011-09-16 16:27+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:28+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\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: 2012-02-09 06:42+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: hr
|
||||
|
@ -57,7 +57,7 @@ msgstr "Seskupit podle..."
|
|||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.view_department_form_installer
|
||||
msgid "Create Your Departments"
|
||||
msgstr ""
|
||||
msgstr "Vytvořit vaše oddělení"
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.action_hr_job
|
||||
|
@ -109,7 +109,7 @@ msgstr "Očekáván v náboru"
|
|||
#. module: hr
|
||||
#: model:ir.actions.todo.category,name:hr.category_hr_management_config
|
||||
msgid "HR Management"
|
||||
msgstr ""
|
||||
msgstr "Správa lidských zdrojů"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,partner_id:0
|
||||
|
@ -162,7 +162,7 @@ msgstr ""
|
|||
#. module: hr
|
||||
#: field:hr.employee,color:0
|
||||
msgid "Color Index"
|
||||
msgstr ""
|
||||
msgstr "Index barvy"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_employeeuser0
|
||||
|
@ -191,12 +191,12 @@ msgstr "Žena"
|
|||
#. module: hr
|
||||
#: help:hr.job,expected_employees:0
|
||||
msgid "Required number of employees in total for that job."
|
||||
msgstr ""
|
||||
msgstr "Celkový požadovaný počet zaměstnanců pro úlohu."
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
|
||||
msgid "Attendance"
|
||||
msgstr ""
|
||||
msgstr "Docházka"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
|
@ -349,7 +349,7 @@ msgstr "hr.department"
|
|||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.action_create_hr_employee_installer
|
||||
msgid "Create your Employees"
|
||||
msgstr ""
|
||||
msgstr "Vytvořit vaše zaměstnance"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,name:0
|
||||
|
@ -431,7 +431,7 @@ msgstr "neznámé"
|
|||
#. module: hr
|
||||
#: help:hr.job,no_of_employee:0
|
||||
msgid "Number of employees with that job."
|
||||
msgstr ""
|
||||
msgstr "Počet zaměstnanců v této úlože"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,ssnid:0
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-09-16 09:10+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 04:58+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <openerp-i18n-czech@lists.launchpad.net >\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-02-09 06:45+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: czech\n"
|
||||
|
||||
#. module: hr_attendance
|
||||
|
@ -197,7 +197,7 @@ msgstr "Vyhledávání v docházce"
|
|||
#. module: hr_attendance
|
||||
#: model:ir.actions.act_window,name:hr_attendance.action_hr_attendance_week
|
||||
msgid "Attendances By Week"
|
||||
msgstr ""
|
||||
msgstr "Docházka podle týdne"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: constraint:hr.attendance:0
|
||||
|
@ -263,7 +263,7 @@ msgstr "Měsíc"
|
|||
#. module: hr_attendance
|
||||
#: field:hr.action.reason,action_type:0
|
||||
msgid "Action Type"
|
||||
msgstr ""
|
||||
msgstr "Typ akce"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: report:report.hr.timesheet.attendance.error:0
|
||||
|
@ -275,7 +275,7 @@ msgstr ""
|
|||
#. module: hr_attendance
|
||||
#: view:hr.attendance:0
|
||||
msgid "My Attendance"
|
||||
msgstr ""
|
||||
msgstr "Moje docházka"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: help:hr.attendance,action_desc:0
|
||||
|
@ -312,7 +312,7 @@ msgstr "hr.sign.out.ask"
|
|||
#. module: hr_attendance
|
||||
#: view:hr.attendance.week:0
|
||||
msgid "Print Attendance Report Weekly"
|
||||
msgstr ""
|
||||
msgstr "Tisknout týdenní výkaz docházky"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.month,month:0
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openeobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-09-20 07:48+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 05:09+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <openerp-i18n-czech@lists.launchpad.net >\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-02-09 06:38+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: hr_contract
|
||||
|
@ -25,7 +25,7 @@ msgstr "Mzda"
|
|||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
msgstr "Informace"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
|
@ -87,7 +87,7 @@ msgstr "Hledat smlouvu"
|
|||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
msgid "Contracts in progress"
|
||||
msgstr ""
|
||||
msgstr "Smlouvy v běhu"
|
||||
|
||||
#. module: hr_contract
|
||||
#: field:hr.employee,vehicle_distance:0
|
||||
|
@ -111,7 +111,7 @@ msgstr "Osobní informace"
|
|||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
msgid "Contracts whose end date already passed"
|
||||
msgstr ""
|
||||
msgstr "Smlouvy jejichž datum ukončení již uplynul"
|
||||
|
||||
#. module: hr_contract
|
||||
#: help:hr.employee,contract_id:0
|
||||
|
@ -163,7 +163,7 @@ msgstr "Datum ukončení"
|
|||
#. module: hr_contract
|
||||
#: help:hr.contract,wage:0
|
||||
msgid "Basic Salary of the employee"
|
||||
msgstr ""
|
||||
msgstr "Základní plat zaměstnance"
|
||||
|
||||
#. module: hr_contract
|
||||
#: field:hr.contract,name:0
|
||||
|
@ -184,7 +184,7 @@ msgstr "Poznámky"
|
|||
#. module: hr_contract
|
||||
#: field:hr.contract,permit_no:0
|
||||
msgid "Work Permit No"
|
||||
msgstr ""
|
||||
msgstr "Č. pracovního povolení"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
|
@ -217,7 +217,7 @@ msgstr "Pracovní informace"
|
|||
#. module: hr_contract
|
||||
#: field:hr.contract,visa_expire:0
|
||||
msgid "Visa Expire Date"
|
||||
msgstr ""
|
||||
msgstr "Datum vypršení víza"
|
||||
|
||||
#. module: hr_contract
|
||||
#: field:hr.contract,job_id:0
|
||||
|
@ -242,7 +242,7 @@ msgstr "Chyba! Počáteční datum smlouvy musí být nižší než konečné da
|
|||
#. module: hr_contract
|
||||
#: field:hr.contract,visa_no:0
|
||||
msgid "Visa No"
|
||||
msgstr ""
|
||||
msgstr "Č. víza"
|
||||
|
||||
#. module: hr_contract
|
||||
#: field:hr.employee,place_of_birth:0
|
||||
|
|
|
@ -93,6 +93,7 @@ class hr_holidays(osv.osv):
|
|||
_name = "hr.holidays"
|
||||
_description = "Leave"
|
||||
_order = "type desc, date_from asc"
|
||||
_inherit = ['ir.needaction_mixin', 'mail.thread']
|
||||
|
||||
def _employee_get(self, cr, uid, context=None):
|
||||
ids = self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
|
||||
|
@ -150,7 +151,12 @@ class hr_holidays(osv.osv):
|
|||
('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be before the end date !"),
|
||||
('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0 !"),
|
||||
]
|
||||
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(hr_holidays, self).create(cr, uid, vals, context=context)
|
||||
self.create_notificate(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def _create_resource_leave(self, cr, uid, leaves, context=None):
|
||||
'''This method will create entry in resource calendar leave object at the time of holidays validated '''
|
||||
obj_res_leave = self.pool.get('resource.calendar.leaves')
|
||||
|
@ -250,6 +256,7 @@ class hr_holidays(osv.osv):
|
|||
obj_emp = self.pool.get('hr.employee')
|
||||
ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
|
||||
manager = ids2 and ids2[0] or False
|
||||
self.holidays_validate_notificate(cr, uid, ids, context=context)
|
||||
return self.write(cr, uid, ids, {'state':'validate1', 'manager_id': manager})
|
||||
|
||||
def holidays_validate2(self, cr, uid, ids, context=None):
|
||||
|
@ -301,11 +308,13 @@ class hr_holidays(osv.osv):
|
|||
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'validate', cr)
|
||||
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'second_validate', cr)
|
||||
if holiday_ids:
|
||||
self.holidays_valid2_notificate(self, cr, uid, [holiday_ids], context=context)
|
||||
self.write(cr, uid, holiday_ids, {'manager_id2': manager})
|
||||
return True
|
||||
|
||||
def holidays_confirm(self, cr, uid, ids, context=None):
|
||||
self.check_holidays(cr, uid, ids, context=context)
|
||||
self.holidays_confirm_notificate(cr, uid, ids, context=context)
|
||||
return self.write(cr, uid, ids, {'state':'confirm'})
|
||||
|
||||
def holidays_refuse(self, cr, uid, ids, approval, context=None):
|
||||
|
@ -316,6 +325,7 @@ class hr_holidays(osv.osv):
|
|||
self.write(cr, uid, ids, {'state': 'refuse', 'manager_id': manager})
|
||||
else:
|
||||
self.write(cr, uid, ids, {'state': 'refuse', 'manager_id2': manager})
|
||||
self.holidays_refuse_notificate(cr, uid, ids, approval, context=context)
|
||||
self.holidays_cancel(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
|
@ -343,6 +353,69 @@ class hr_holidays(osv.osv):
|
|||
if leaves_rest < record.number_of_days_temp:
|
||||
raise osv.except_osv(_('Warning!'),_('You cannot validate leaves for employee %s: too few remaining days (%s).') % (record.employee_id.name, leaves_rest))
|
||||
return True
|
||||
|
||||
# -----------------------------
|
||||
# OpenChatter and notifications
|
||||
# -----------------------------
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids, [])
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.state == 'confirm' and obj.employee_id.parent_id:
|
||||
result[obj.id] = [obj.employee_id.parent_id.user_id.id]
|
||||
elif obj.state == 'validate1':
|
||||
# get group_hr_manager: everyone will be warned of second validation
|
||||
res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_manager') or False
|
||||
obj_id = res and res[1] or False
|
||||
if obj_id:
|
||||
hr_manager_group = self.pool.get('res.groups').read(cr, uid, [obj_id], ['users'], context=context)[0]
|
||||
result[obj.id] = hr_manager_group['users']
|
||||
return result
|
||||
|
||||
def message_get_subscribers(self, cr, uid, ids, context=None):
|
||||
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
|
||||
# add the employee and its manager if specified to the subscribed users
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.employee_id.parent_id:
|
||||
sub_ids.append(obj.employee_id.parent_id.user_id.id)
|
||||
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
|
||||
|
||||
def create_notificate(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
self.message_append_note(cr, uid, ids, _('System notification'),
|
||||
_("The %s request has been <b>created</b> and is waiting confirmation")
|
||||
% ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
|
||||
return True
|
||||
|
||||
def holidays_confirm_notificate(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids):
|
||||
self.message_append_note(cr, uid, [obj.id], _('System notification'),
|
||||
_("The %s request has been <b>confirmed</b> and is waiting for validation by the manager.")
|
||||
% ('leave' if obj.type == 'remove' else 'allocation',), type='notification')
|
||||
|
||||
def holidays_validate_notificate(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids):
|
||||
if obj.holiday_status_id.double_validation:
|
||||
self.message_append_note(cr, uid, [obj.id], _('System notification'),
|
||||
_("The %s request has been <b>validated</b>. A second validation is necessary and is now pending.")
|
||||
% ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
|
||||
else:
|
||||
self.message_append_note(cr, uid, [obj.id], _('System notification'),
|
||||
_("The %s request has been <b>validated</b>. The validation process is now over.")
|
||||
% ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
|
||||
|
||||
def holidays_valid2_notificate(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids):
|
||||
self.message_append_note(cr, uid, [obj.id], _('System notification'),
|
||||
_("The %s request has been <b>double validated</b>. The validation process is now over.")
|
||||
% ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
|
||||
|
||||
def holidays_refuse_notificate(self, cr, uid, ids, approval, context=None):
|
||||
for obj in self.browse(cr, uid, ids):
|
||||
self.message_append_note(cr, uid, [obj.id], _('System notification'),
|
||||
_("The %s request has been <b>refused</b>. The validation process is now over.")
|
||||
% ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context)
|
||||
|
||||
hr_holidays()
|
||||
|
||||
class resource_calendar_leaves(osv.osv):
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
<button string="Approved" name="second_validate" states="validate1" type="workflow" icon="gtk-apply" groups="base.group_hr_user"/>
|
||||
<button string="Set to Draft" name="set_to_draft" states="refuse,validate" type="object" icon="gtk-convert" groups="base.group_hr_user"/>
|
||||
</group>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
@ -137,6 +138,7 @@
|
|||
<button string="Approved" name="second_validate" states="validate1" type="workflow" icon="gtk-apply" groups="base.group_hr_user"/>
|
||||
<button string="Set to Draft" name="set_to_draft" states="cancel,validate,refuse" type="object" icon="gtk-convert" groups="base.group_hr_user"/>
|
||||
</group>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
# Japanese 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-08 06:04+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: 2012-04-09 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.payslip,move_id:0
|
||||
msgid "Accounting Entry"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.salary.rule,account_tax_id:0
|
||||
msgid "Tax Code"
|
||||
msgstr "税金コード"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.payslip,journal_id:0
|
||||
#: field:hr.payslip.run,journal_id:0
|
||||
msgid "Expense Journal"
|
||||
msgstr "経費仕訳"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:157
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:173
|
||||
#, python-format
|
||||
msgid "Adjustment Entry"
|
||||
msgstr "調整項目"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.contract,analytic_account_id:0
|
||||
#: field:hr.salary.rule,analytic_account_id:0
|
||||
msgid "Analytic Account"
|
||||
msgstr "分析アカウント"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: model:ir.model,name:hr_payroll_account.model_hr_salary_rule
|
||||
msgid "hr.salary.rule"
|
||||
msgstr "hr.salary.rule"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: model:ir.model,name:hr_payroll_account.model_hr_payslip_run
|
||||
msgid "Payslip Batches"
|
||||
msgstr "給与明細書の束"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.contract,journal_id:0
|
||||
msgid "Salary Journal"
|
||||
msgstr "給与仕訳"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: model:ir.model,name:hr_payroll_account.model_hr_payslip
|
||||
msgid "Pay Slip"
|
||||
msgstr "給与明細書"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: constraint:hr.payslip:0
|
||||
msgid "Payslip 'Date From' must be before 'Date To'."
|
||||
msgstr "給与明細書の「開始日付」は「終了日付」の前でなければいけません。"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: help:hr.payslip,period_id:0
|
||||
msgid "Keep empty to use the period of the validation(Payslip) date."
|
||||
msgstr "給与明細書の発効日の期間を使うために、空白にしておいてください。"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:171
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The Expense Journal \"%s\" has not properly configured the Debit Account!"
|
||||
msgstr "経費仕訳 %s は、借方勘定科目を正しく設定していません。"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:155
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The Expense Journal \"%s\" has not properly configured the Credit Account!"
|
||||
msgstr "経費仕訳 %s は与信アカウントを正しく設定してありません。"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.salary.rule,account_debit:0
|
||||
msgid "Debit Account"
|
||||
msgstr "借方勘定科目"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:102
|
||||
#, python-format
|
||||
msgid "Payslip of %s"
|
||||
msgstr "%s の給与明細書"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: model:ir.model,name:hr_payroll_account.model_hr_contract
|
||||
msgid "Contract"
|
||||
msgstr "契約"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: constraint:hr.contract:0
|
||||
msgid "Error! contract start-date must be lower then contract end-date."
|
||||
msgstr "エラー。契約開始日は契約終了日の前でなければいけません。"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.payslip,period_id:0
|
||||
msgid "Force Period"
|
||||
msgstr "強制期間"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: field:hr.salary.rule,account_credit:0
|
||||
msgid "Credit Account"
|
||||
msgstr "貸方勘定科目"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: model:ir.model,name:hr_payroll_account.model_hr_payslip_employees
|
||||
msgid "Generate payslips for all selected employees"
|
||||
msgstr "選択した全ての従業員の給与明細書を作成する。"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:155
|
||||
#: code:addons/hr_payroll_account/hr_payroll_account.py:171
|
||||
#, python-format
|
||||
msgid "Configuration Error!"
|
||||
msgstr "設定エラー"
|
||||
|
||||
#. module: hr_payroll_account
|
||||
#: view:hr.contract:0
|
||||
#: view:hr.salary.rule:0
|
||||
msgid "Accounting"
|
||||
msgstr "会計"
|
|
@ -96,7 +96,7 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
_name = "hr.applicant"
|
||||
_description = "Applicant"
|
||||
_order = "id desc"
|
||||
_inherit = ['mail.thread']
|
||||
_inherit = ['ir.needaction_mixin', 'mail.thread']
|
||||
|
||||
def _compute_day(self, cr, uid, ids, fields, args, context=None):
|
||||
"""
|
||||
|
@ -179,6 +179,7 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
'day_close': fields.function(_compute_day, string='Days to Close', \
|
||||
multi='day_close', type="float", store=True),
|
||||
'color': fields.integer('Color Index'),
|
||||
'emp_id': fields.many2one('hr.employee', 'employee'),
|
||||
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
|
||||
}
|
||||
|
||||
|
@ -389,36 +390,33 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
self.message_append_dict(cr, uid, ids, msg, context=context)
|
||||
return res
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(hr_applicant, self).create(cr, uid, vals, context=context)
|
||||
self.create_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case's Ids
|
||||
@param *args: Give Tuple Value
|
||||
open Request of the applicant for the hr_recruitment
|
||||
"""
|
||||
res = super(hr_applicant, self).case_open(cr, uid, ids, *args)
|
||||
res = super(hr_applicant, self).case_open(cr, uid, ids, context)
|
||||
date = self.read(cr, uid, ids, ['date_open'])[0]
|
||||
if not date['date_open']:
|
||||
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),})
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _("The job request '%s' has been set 'in progress'.") % name
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
res = super(hr_applicant, self).case_close(cr, uid, ids, *args)
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _("Applicant '%s' is being hired.") % name
|
||||
self.log(cr, uid, id, message)
|
||||
def case_close(self, cr, uid, ids, context=None):
|
||||
res = super(hr_applicant, self).case_close(cr, uid, ids, context)
|
||||
return res
|
||||
|
||||
def case_close_with_emp(self, cr, uid, ids, *args):
|
||||
def case_close_with_emp(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
hr_employee = self.pool.get('hr.employee')
|
||||
model_data = self.pool.get('ir.model.data')
|
||||
act_window = self.pool.get('ir.actions.act_window')
|
||||
emp_id = False
|
||||
for applicant in self.browse(cr, uid, ids):
|
||||
for applicant in self.browse(cr, uid, ids, context=context):
|
||||
address_id = False
|
||||
if applicant.partner_id:
|
||||
address_id = applicant.partner_id.address_get(['contact'])['contact']
|
||||
|
@ -429,7 +427,8 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
'address_home_id': address_id,
|
||||
'department_id': applicant.department_id.id
|
||||
})
|
||||
self.case_close(cr, uid, [applicant.id], *args)
|
||||
self.write(cr, uid, [applicant.id], {'emp_id': emp_id}, context=context)
|
||||
self.case_close(cr, uid, [applicant.id], context)
|
||||
else:
|
||||
raise osv.except_osv(_('Warning!'),_('You must define Applied Job for this applicant.'))
|
||||
|
||||
|
@ -440,16 +439,23 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
dict_act_window['view_mode'] = 'form,tree'
|
||||
return dict_act_window
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
"""Resets case as draft
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case Ids
|
||||
@param *args: Tuple Value for additional Params
|
||||
def case_cancel(self, cr, uid, ids, context=None):
|
||||
"""Overrides cancel for crm_case for setting probability
|
||||
"""
|
||||
res = super(hr_applicant, self).case_cancel(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'probability' : 0.0})
|
||||
return res
|
||||
|
||||
res = super(hr_applicant, self).case_reset(cr, uid, ids, *args)
|
||||
def case_pending(self, cr, uid, ids, context=None):
|
||||
"""Marks case as pending"""
|
||||
res = super(hr_applicant, self).case_pending(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'probability' : 0.0})
|
||||
return res
|
||||
|
||||
def case_reset(self, cr, uid, ids, context=None):
|
||||
"""Resets case as draft
|
||||
"""
|
||||
res = super(hr_applicant, self).case_reset(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'date_open': False, 'date_closed': False})
|
||||
return res
|
||||
|
||||
|
@ -471,10 +477,58 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if 'stage_id' in vals and vals['stage_id']:
|
||||
stage = self.pool.get('hr.recruitment.stage').browse(cr, uid, vals['stage_id'], context=context)
|
||||
text = _("Changed Stage to: %s") % stage.name
|
||||
self.message_append(cr, uid, ids, text, body_text=text, context=context)
|
||||
self.message_append_note(cr, uid, ids, body=_("Stage changed to <b>%s</b>.") % stage.name, context=context)
|
||||
return super(hr_applicant,self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
# -------------------------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
# -------------------------------------------------------
|
||||
|
||||
def message_get_subscribers(self, cr, uid, ids, context=None):
|
||||
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.user_id:
|
||||
sub_ids.append(obj.user_id.id)
|
||||
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids, [])
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.state == 'draft' and obj.user_id:
|
||||
result[obj.id] = [obj.user_id.id]
|
||||
return result
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return 'Applicant'
|
||||
|
||||
def case_open_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Applicant has been set <b>in progress</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def case_close_send_note(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
for applicant in self.browse(cr, uid, ids, context=context):
|
||||
if applicant.emp_id:
|
||||
message = _("Applicant has been <b>hired</b> and created as an employee.")
|
||||
self.message_append_note(cr, uid, [applicant.id], body=message, context=context)
|
||||
else:
|
||||
message = _("Applicant has been <b>hired</b>.")
|
||||
self.message_append_note(cr, uid, [applicant.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
def case_cancel_send_note(self, cr, uid, ids, context=None):
|
||||
msg = 'Applicant <b>refused</b>.'
|
||||
return self.message_append_note(cr, uid, ids, body=msg, context=context)
|
||||
|
||||
def case_reset_send_note(self, cr, uid, ids, context=None):
|
||||
message =_("Applicant has been set as <b>new</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Applicant has been <b>created</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
hr_applicant()
|
||||
|
||||
class hr_job(osv.osv):
|
||||
|
|
|
@ -79,6 +79,9 @@
|
|||
<field name="partner_name"/>
|
||||
<field name="job_id" on_change="onchange_job(job_id)"/>
|
||||
<button name="action_makeMeeting" type="object" string="Meeting" icon="gtk-index"/>
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
<newline/>
|
||||
<field name="department_id" widget="selection" on_change="onchange_department_id(department_id)"/>
|
||||
<group colspan="2" col="4">
|
||||
|
@ -123,13 +126,6 @@
|
|||
<field name="source_id"/>
|
||||
<field name="reference"/>
|
||||
</group>
|
||||
<group col="2" colspan="2" groups="base.group_no_one">
|
||||
<separator colspan="2" string="Dates"/>
|
||||
<field name="create_date"/>
|
||||
<field name="write_date"/>
|
||||
<field name="date_closed"/>
|
||||
<field name="date_open"/>
|
||||
</group>
|
||||
<separator colspan="4" string="Status"/>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,open,done" statusbar_colors='{"pending":"blue"}'/>
|
||||
|
@ -140,33 +136,11 @@
|
|||
<button name="case_reset" string="Reset to New" states="done,cancel" type="object" icon="gtk-convert"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Communication & History" groups="base.group_extended">
|
||||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Notes">
|
||||
<field name="description" nolabel="1" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -63,7 +63,7 @@ class hr_recruitment_partner_create(osv.osv_memory):
|
|||
'email': case.email_from
|
||||
}, context=context)
|
||||
|
||||
case_obj.write(cr, uid, case.id, {
|
||||
case_obj.write(cr, uid, [case.id], {
|
||||
'partner_id': partner_id,
|
||||
}, context=context)
|
||||
if data['close']:
|
||||
|
@ -82,4 +82,4 @@ class hr_recruitment_partner_create(osv.osv_memory):
|
|||
|
||||
hr_recruitment_partner_create()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-09-20 08:48+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 05:13+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <openerp-i18n-czech@lists.launchpad.net >\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-02-09 06:31+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: hr_timesheet
|
||||
|
@ -107,7 +107,7 @@ msgstr "Pá"
|
|||
#. module: hr_timesheet
|
||||
#: field:hr.employee,uom_id:0
|
||||
msgid "UoM"
|
||||
msgstr ""
|
||||
msgstr "MJ"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: view:hr.sign.in.project:0
|
||||
|
@ -152,7 +152,7 @@ msgstr "Jméno zaměstnance"
|
|||
#. module: hr_timesheet
|
||||
#: field:hr.sign.out.project,account_id:0
|
||||
msgid "Project / Analytic Account"
|
||||
msgstr ""
|
||||
msgstr "Projekt / Analytický účet"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: model:ir.model,name:hr_timesheet.model_hr_analytical_timesheet_users
|
||||
|
@ -195,7 +195,7 @@ msgstr "Varování"
|
|||
#. module: hr_timesheet
|
||||
#: field:hr.analytic.timesheet,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
msgstr "Partner"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: view:hr.sign.in.project:0
|
||||
|
@ -220,7 +220,7 @@ msgstr "Ne"
|
|||
#. module: hr_timesheet
|
||||
#: view:hr.analytic.timesheet:0
|
||||
msgid "Analytic account"
|
||||
msgstr ""
|
||||
msgstr "Analytický účet"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: view:hr.analytical.timesheet.employee:0
|
||||
|
@ -263,7 +263,7 @@ msgstr "Kategorie"
|
|||
#. module: hr_timesheet
|
||||
#: constraint:hr.analytic.timesheet:0
|
||||
msgid "You cannot modify an entry in a Confirmed/Done timesheet !."
|
||||
msgstr ""
|
||||
msgstr "Nemůžete změnit údaj v Potvrzeném/Dokončeném časovém záznamu !."
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: help:hr.employee,product_id:0
|
||||
|
@ -314,7 +314,7 @@ msgstr "Popis práce"
|
|||
#. module: hr_timesheet
|
||||
#: view:account.analytic.account:0
|
||||
msgid "Invoice Analysis"
|
||||
msgstr ""
|
||||
msgstr "Analýza faktury"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: model:ir.actions.report.xml,name:hr_timesheet.report_user_timesheet
|
||||
|
@ -330,7 +330,7 @@ msgstr "Přihlášení / Odhlášení podle projektu"
|
|||
#. module: hr_timesheet
|
||||
#: model:ir.actions.act_window,name:hr_timesheet.action_define_analytic_structure
|
||||
msgid "Define your Analytic Structure"
|
||||
msgstr ""
|
||||
msgstr "Určit vaši analytickou strukturu"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: view:hr.sign.in.project:0
|
||||
|
@ -364,11 +364,14 @@ msgid ""
|
|||
"analyse costs and revenues. In OpenERP, analytic accounts are also used to "
|
||||
"track customer contracts."
|
||||
msgstr ""
|
||||
"Měli byste vytvořit strukturu analytických účtů závisejících na vašich "
|
||||
"potřebách k analýze cen a výnosů. Analytické účty jsou v OpenERP také "
|
||||
"použity pro sledování smluv zákazníků."
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: field:hr.analytic.timesheet,line_id:0
|
||||
msgid "Analytic Line"
|
||||
msgstr ""
|
||||
msgstr "Analytický řádek"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: code:addons/hr_timesheet/report/user_timesheet.py:40
|
||||
|
@ -515,6 +518,8 @@ msgid ""
|
|||
"Through this menu you can register and follow your workings hours by project "
|
||||
"every day."
|
||||
msgstr ""
|
||||
"Pomocí této nabídky můžete každý den registrovat a následovat vaše pracovní "
|
||||
"hodiny podle projektu."
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: field:hr.sign.in.project,server_date:0
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-10-17 08:27+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:33+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: openerp-i18n-czech <openerp-i18n-czech@lists.launchpad.net >\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-02-09 06:29+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: idea
|
||||
|
@ -26,7 +26,7 @@ msgstr ""
|
|||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "By States"
|
||||
msgstr ""
|
||||
msgstr "Podle stavů"
|
||||
|
||||
#. module: idea
|
||||
#: model:ir.actions.act_window,name:idea.action_idea_select
|
||||
|
@ -73,7 +73,7 @@ msgstr "Březen"
|
|||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "Accepted Ideas"
|
||||
msgstr ""
|
||||
msgstr "Schválené nápady"
|
||||
|
||||
#. module: idea
|
||||
#: code:addons/idea/wizard/idea_post_vote.py:94
|
||||
|
@ -84,7 +84,7 @@ msgstr "Nápad musí být ve stavu 'Otevřený' přes hlasováním pro tento ná
|
|||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
msgid "Open Date"
|
||||
msgstr ""
|
||||
msgstr "Datum otevření"
|
||||
|
||||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
|
@ -239,7 +239,7 @@ msgstr "Stav"
|
|||
#: view:idea.idea:0
|
||||
#: selection:idea.idea,state:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
msgstr "Nový"
|
||||
|
||||
#. module: idea
|
||||
#: selection:idea.idea,my_vote:0
|
||||
|
@ -273,12 +273,12 @@ msgstr ""
|
|||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "New Ideas"
|
||||
msgstr ""
|
||||
msgstr "Nové nápady"
|
||||
|
||||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
msgid "Idea Vote created last month"
|
||||
msgstr ""
|
||||
msgstr "Hlas nápadu vytvořený v posledním měsíci"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.category,visibility:0
|
||||
|
@ -289,7 +289,7 @@ msgstr "Otevřít nápad?"
|
|||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
msgid "Idea Vote created in current month"
|
||||
msgstr ""
|
||||
msgstr "Hlas nápadu vytvořený v tomto měsíci"
|
||||
|
||||
#. module: idea
|
||||
#: selection:report.vote,month:0
|
||||
|
@ -406,7 +406,7 @@ msgstr "Hlasy nápadů"
|
|||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "By Idea Category"
|
||||
msgstr ""
|
||||
msgstr "Podle kategorie nápadů"
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
|
@ -543,7 +543,7 @@ msgstr "Nastavte na jedničku, pokud požadujete pouze jeden hlas na uživatele"
|
|||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "By Creators"
|
||||
msgstr ""
|
||||
msgstr "Podle tvůrce"
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.post.vote:0
|
||||
|
@ -564,7 +564,7 @@ msgstr "Otevřít"
|
|||
#: view:idea.idea:0
|
||||
#: view:report.vote:0
|
||||
msgid "In Progress"
|
||||
msgstr ""
|
||||
msgstr "V běhu"
|
||||
|
||||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
|
@ -594,7 +594,7 @@ msgstr "Skóre"
|
|||
#. module: idea
|
||||
#: view:idea.idea:0
|
||||
msgid "Votes Statistics"
|
||||
msgstr ""
|
||||
msgstr "Statistika hlasů"
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.vote:0
|
||||
|
@ -632,7 +632,7 @@ msgstr "Únor"
|
|||
#. module: idea
|
||||
#: field:idea.category,complete_name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
msgstr "Jméno"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.vote.stat,nbr:0
|
||||
|
@ -642,7 +642,7 @@ msgstr "Počet hlasů"
|
|||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
msgid "Month-1"
|
||||
msgstr ""
|
||||
msgstr "Měsíc -1"
|
||||
|
||||
#. module: idea
|
||||
#: selection:report.vote,month:0
|
||||
|
@ -662,7 +662,7 @@ msgstr "Stav hlasu"
|
|||
#. module: idea
|
||||
#: view:report.vote:0
|
||||
msgid "Idea Vote created in current year"
|
||||
msgstr ""
|
||||
msgstr "Hlasy nápadu vytvořené v tomto roce"
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.idea,vote_avg:0
|
||||
|
@ -672,7 +672,7 @@ msgstr "Průměrné skóre"
|
|||
#. module: idea
|
||||
#: constraint:idea.category:0
|
||||
msgid "Error ! You cannot create recursive categories."
|
||||
msgstr ""
|
||||
msgstr "Chyba ! Nemůžete vytvořit rekurzivní Kategorie."
|
||||
|
||||
#. module: idea
|
||||
#: field:idea.comment,idea_id:0
|
||||
|
@ -706,7 +706,7 @@ msgstr "Rok"
|
|||
#: code:addons/idea/idea.py:274
|
||||
#, python-format
|
||||
msgid "You can not vote on a Draft/Accepted/Cancelled ideas."
|
||||
msgstr ""
|
||||
msgstr "Nemůžete hlasovat pro rozpracované/schválené/zrušené nápady."
|
||||
|
||||
#. module: idea
|
||||
#: view:idea.select:0
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
# Arabic 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 07:49+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Arabic <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: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:434
|
||||
#, python-format
|
||||
msgid "Import failed due to an unexpected error"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:461
|
||||
#, python-format
|
||||
msgid "started at %s and finished at %s \n"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:448
|
||||
#, python-format
|
||||
msgid "Import of your data finished at %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:463
|
||||
#, python-format
|
||||
msgid ""
|
||||
"but failed, in consequence no data were imported to keep database "
|
||||
"consistency \n"
|
||||
" error : \n"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:477
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The import of data \n"
|
||||
" instance name : %s \n"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:470
|
||||
#, python-format
|
||||
msgid "%s has been successfully imported from %s %s, %s \n"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:447
|
||||
#, python-format
|
||||
msgid "Data Import failed at %s due to an unexpected error"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:436
|
||||
#, python-format
|
||||
msgid "Import finished, notification email sended"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:190
|
||||
#, python-format
|
||||
msgid "%s is not a valid model name"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: model:ir.ui.menu,name:import_base.menu_import_crm
|
||||
msgid "Import"
|
||||
msgstr "إستيراد"
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:467
|
||||
#, python-format
|
||||
msgid "with no warning"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:469
|
||||
#, python-format
|
||||
msgid "with warning : %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: import_base
|
||||
#: code:addons/import_base/import_framework.py:191
|
||||
#, python-format
|
||||
msgid " fields imported : "
|
||||
msgstr ""
|
|
@ -0,0 +1,223 @@
|
|||
# Serbian Latin 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 13:42+0000\n"
|
||||
"Last-Translator: Milan Milosevic <Unknown>\n"
|
||||
"Language-Team: Serbian Latin <sr@latin@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: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: import_google
|
||||
#: help:synchronize.google.import,group_name:0
|
||||
msgid "Choose which group to import, By default it takes all."
|
||||
msgstr "Izaberite grupu za uvoz, po defaultu, uzima ih sve"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "Import Google Calendar Events"
|
||||
msgstr "Uvezi događaje iz Google-ovog kalendara"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "_Import Events"
|
||||
msgstr "_Uvezi događaje"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google_data.py:71
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No Google Username or password Defined for user.\n"
|
||||
"Please define in user view"
|
||||
msgstr ""
|
||||
"Nema određenog korisničkog imena ili lozinke za korisnika.\n"
|
||||
"Molimo odredite ih u korisničkom pregledu"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google_data.py:127
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Invalid login detail !\n"
|
||||
" Specify Username/Password."
|
||||
msgstr ""
|
||||
"Nevažeći detalji prijave !\n"
|
||||
" Odredite korisničko ime/ lozinku."
|
||||
|
||||
#. module: import_google
|
||||
#: field:synchronize.google.import,supplier:0
|
||||
msgid "Supplier"
|
||||
msgstr "Dobavljač"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "Import Options"
|
||||
msgstr "Opcije uvoza"
|
||||
|
||||
#. module: import_google
|
||||
#: field:synchronize.google.import,group_name:0
|
||||
msgid "Group Name"
|
||||
msgstr "Ime grupe"
|
||||
|
||||
#. module: import_google
|
||||
#: model:ir.model,name:import_google.model_crm_case_categ
|
||||
msgid "Category of Case"
|
||||
msgstr "Kategorija slučaja"
|
||||
|
||||
#. module: import_google
|
||||
#: model:ir.actions.act_window,name:import_google.act_google_login_contact_form
|
||||
#: model:ir.ui.menu,name:import_google.menu_sync_contact
|
||||
msgid "Import Google Contacts"
|
||||
msgstr "Uvezi Google kontakte"
|
||||
|
||||
#. module: import_google
|
||||
#: view:google.import.message:0
|
||||
msgid "Import Google Data"
|
||||
msgstr "Uvezi Google podatke"
|
||||
|
||||
#. module: import_google
|
||||
#: view:crm.meeting:0
|
||||
msgid "Meeting Type"
|
||||
msgstr "Tip sastanka"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google.py:38
|
||||
#: code:addons/import_google/wizard/import_google_data.py:28
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please install gdata-python-client from http://code.google.com/p/gdata-"
|
||||
"python-client/downloads/list"
|
||||
msgstr ""
|
||||
"Molimo instalirajte gdata-python-client from http://code.google.com/p/gdata-"
|
||||
"python-client/downloads/list"
|
||||
|
||||
#. module: import_google
|
||||
#: model:ir.model,name:import_google.model_google_login
|
||||
msgid "Google Contact"
|
||||
msgstr "Google kontakt"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "Import contacts from a google account"
|
||||
msgstr "Uvezi kontakte s Google naloga"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google_data.py:133
|
||||
#, python-format
|
||||
msgid "Please specify correct user and password !"
|
||||
msgstr "Molimo odredite tačnog korisnika i lozinku !"
|
||||
|
||||
#. module: import_google
|
||||
#: field:synchronize.google.import,customer:0
|
||||
msgid "Customer"
|
||||
msgstr "Mušterija"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "_Cancel"
|
||||
msgstr "_Otkaži"
|
||||
|
||||
#. module: import_google
|
||||
#: model:ir.model,name:import_google.model_synchronize_google_import
|
||||
msgid "synchronize.google.import"
|
||||
msgstr "synchronize.google.import"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "_Import Contacts"
|
||||
msgstr "_Uvezi kontakte"
|
||||
|
||||
#. module: import_google
|
||||
#: model:ir.actions.act_window,name:import_google.act_google_login_form
|
||||
#: model:ir.ui.menu,name:import_google.menu_sync_calendar
|
||||
msgid "Import Google Calendar"
|
||||
msgstr "Uvezi Google-ov kalendar"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google_data.py:50
|
||||
#, python-format
|
||||
msgid "Import google"
|
||||
msgstr "Uvezi Google"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google_data.py:127
|
||||
#: code:addons/import_google/wizard/import_google_data.py:133
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Greška"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google_data.py:71
|
||||
#, python-format
|
||||
msgid "Warning !"
|
||||
msgstr "Upozorenje !"
|
||||
|
||||
#. module: import_google
|
||||
#: field:synchronize.google.import,create_partner:0
|
||||
msgid "Options"
|
||||
msgstr "Opcije"
|
||||
|
||||
#. module: import_google
|
||||
#: view:google.import.message:0
|
||||
msgid "_Ok"
|
||||
msgstr "_Ok"
|
||||
|
||||
#. module: import_google
|
||||
#: code:addons/import_google/wizard/import_google.py:38
|
||||
#: code:addons/import_google/wizard/import_google_data.py:28
|
||||
#, python-format
|
||||
msgid "Google Contacts Import Error!"
|
||||
msgstr "Greška u uvozu kontakata s Google-a"
|
||||
|
||||
#. module: import_google
|
||||
#: model:ir.model,name:import_google.model_google_import_message
|
||||
msgid "Import Message"
|
||||
msgstr "Uvezi poruku"
|
||||
|
||||
#. module: import_google
|
||||
#: field:synchronize.google.import,calendar_name:0
|
||||
msgid "Calendar Name"
|
||||
msgstr "Ime kalendara"
|
||||
|
||||
#. module: import_google
|
||||
#: help:synchronize.google.import,supplier:0
|
||||
msgid "Check this box to set newly created partner as Supplier."
|
||||
msgstr "Označite ovu kućicu da biste novog partnera odredili kao Dobavljača."
|
||||
|
||||
#. module: import_google
|
||||
#: selection:synchronize.google.import,create_partner:0
|
||||
msgid "Import only address"
|
||||
msgstr "Uvezi samo adrese"
|
||||
|
||||
#. module: import_google
|
||||
#: field:crm.case.categ,user_id:0
|
||||
msgid "User"
|
||||
msgstr "Korisnik"
|
||||
|
||||
#. module: import_google
|
||||
#: view:synchronize.google.import:0
|
||||
msgid "Partner status for this group:"
|
||||
msgstr "Stanje partnera za ovu grupu:"
|
||||
|
||||
#. module: import_google
|
||||
#: field:google.import.message,name:0
|
||||
msgid "Message"
|
||||
msgstr "Poruka"
|
||||
|
||||
#. module: import_google
|
||||
#: selection:synchronize.google.import,create_partner:0
|
||||
msgid "Create partner for each contact"
|
||||
msgstr "Napravi partnera za svaki kontakt"
|
||||
|
||||
#. module: import_google
|
||||
#: help:synchronize.google.import,customer:0
|
||||
msgid "Check this box to set newly created partner as Customer."
|
||||
msgstr "Označite ovu kućicu da biste novog partnera odredili kao Mušteriju."
|
|
@ -0,0 +1,158 @@
|
|||
# Serbian Latin 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 13:53+0000\n"
|
||||
"Last-Translator: Milan Milosevic <Unknown>\n"
|
||||
"Language-Team: Serbian Latin <sr@latin@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: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: help:hr.employee,disabled_spouse_bool:0
|
||||
msgid "if recipient spouse is declared disabled by law"
|
||||
msgstr "Ako je primalac supružnik određen nevažeći po zakonu"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: help:hr.employee,disabled_children_bool:0
|
||||
msgid "if recipient children is/are declared disabled by law"
|
||||
msgstr "Ako je/su primalac/oci dete/deca određen/i nevažeći po zakonu"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,misc_onss_deduction:0
|
||||
msgid "Miscellaneous exempt ONSS "
|
||||
msgstr "Razni ONSS izuzeci "
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: model:ir.model,name:l10n_be_hr_payroll.model_hr_employee
|
||||
msgid "Employee"
|
||||
msgstr "Zaposleni"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.employee,disabled_spouse_bool:0
|
||||
msgid "Disabled Spouse"
|
||||
msgstr "Nevažeći supružnik"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,retained_net_amount:0
|
||||
msgid "Net retained "
|
||||
msgstr "Neto zadržano "
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.employee,resident_bool:0
|
||||
msgid "Nonresident"
|
||||
msgstr "Neboraveći"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: help:hr.employee,resident_bool:0
|
||||
msgid "if recipient lives in a foreign country"
|
||||
msgstr "Ako primalac živi u stranoj zemlji"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: view:hr.employee:0
|
||||
msgid "if spouse has professionnel income or not"
|
||||
msgstr "Ako supružnik ima prihod ili ne"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: view:hr.contract:0
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Razno"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,insurance_employee_deduction:0
|
||||
msgid "Insurance Group - by worker "
|
||||
msgstr "Osiguranička grupa - po radniku "
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: selection:hr.employee,spouse_fiscal_status:0
|
||||
msgid "With Income"
|
||||
msgstr "Sa primanjima"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: selection:hr.employee,spouse_fiscal_status:0
|
||||
msgid "Without Income"
|
||||
msgstr "Bez primanja"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.employee,disabled_children_number:0
|
||||
msgid "Number of disabled children"
|
||||
msgstr "Broj nevažeće dece"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,additional_net_amount:0
|
||||
msgid "Net supplements"
|
||||
msgstr "Neto dodaci"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: constraint:hr.employee:0
|
||||
msgid "Error ! You cannot create recursive Hierarchy of Employees."
|
||||
msgstr "Greška ! Ne možete praviti rekurzivnu hijerarhiju zaposlenih."
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,car_company_amount:0
|
||||
msgid "Company car employer"
|
||||
msgstr "Nadređeni za vozila preduzeća"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,misc_advantage_amount:0
|
||||
msgid "Benefits of various nature "
|
||||
msgstr "Prihodi razne prirode "
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,car_employee_deduction:0
|
||||
msgid "Company Car Deduction for Worker"
|
||||
msgstr "Odšteta preduzeća za vozila za radnika"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.employee,disabled_children_bool:0
|
||||
msgid "Disabled Children"
|
||||
msgstr "Nevažeća deca"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: model:ir.model,name:l10n_be_hr_payroll.model_hr_contract
|
||||
msgid "Contract"
|
||||
msgstr "Ugovor"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,meal_voucher_amount:0
|
||||
msgid "Check Value Meal "
|
||||
msgstr "Vrednost toplog obroka "
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,travel_reimbursement_amount:0
|
||||
msgid "Reimbursement of travel expenses"
|
||||
msgstr "Refundacija putnih troškova"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: constraint:hr.contract:0
|
||||
msgid "Error! contract start-date must be lower then contract end-date."
|
||||
msgstr "Greška! datum početka ugovora mora da bude pre datuma završetka."
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.employee,spouse_fiscal_status:0
|
||||
msgid "Tax status for spouse"
|
||||
msgstr "stanje poreza za supružnika"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: view:hr.contract:0
|
||||
msgid "by Worker"
|
||||
msgstr "po radniku"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: view:hr.employee:0
|
||||
msgid "number of dependent children declared as disabled"
|
||||
msgstr "broj zavisne dece proglašene nevažećim"
|
||||
|
||||
#. module: l10n_be_hr_payroll
|
||||
#: field:hr.contract,meal_voucher_employee_deduction:0
|
||||
msgid "Check Value Meal - by worker "
|
||||
msgstr "Vrednost toplog obroka - po radniku "
|
|
@ -0,0 +1,141 @@
|
|||
# Arabic 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 07:45+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Arabic <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: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: sql_constraint:account.invoice:0
|
||||
msgid "Invoice Number must be unique per Company!"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: model:ir.model,name:l10n_be_invoice_bba.model_account_invoice
|
||||
msgid "Invoice"
|
||||
msgstr "فاتورة"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: constraint:res.partner:0
|
||||
msgid "Error ! You cannot create recursive associated members."
|
||||
msgstr "خطأ ! لا يمكنك إنشاء أعضاء مرتبطين و متداخلين."
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: constraint:account.invoice:0
|
||||
msgid "Invalid BBA Structured Communication !"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: selection:res.partner,out_inv_comm_algorithm:0
|
||||
msgid "Random"
|
||||
msgstr "عشوائي"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: help:res.partner,out_inv_comm_type:0
|
||||
msgid "Select Default Communication Type for Outgoing Invoices."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: help:res.partner,out_inv_comm_algorithm:0
|
||||
msgid ""
|
||||
"Select Algorithm to generate the Structured Communication on Outgoing "
|
||||
"Invoices."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:114
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:140
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The daily maximum of outgoing invoices with an automatically generated BBA "
|
||||
"Structured Communications has been exceeded!\n"
|
||||
"Please create manually a unique BBA Structured Communication."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:155
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr "خطأ!"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:126
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The Partner should have a 3-7 digit Reference Number for the generation of "
|
||||
"BBA Structured Communications!\n"
|
||||
"Please correct the Partner record."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:113
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:125
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:139
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:167
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:177
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:202
|
||||
#, python-format
|
||||
msgid "Warning!"
|
||||
msgstr "تحذير!"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: selection:res.partner,out_inv_comm_algorithm:0
|
||||
msgid "Customer Reference"
|
||||
msgstr "مرجع العميل"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: field:res.partner,out_inv_comm_type:0
|
||||
msgid "Communication Type"
|
||||
msgstr "نوع الاتصال"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:178
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:203
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The BBA Structured Communication has already been used!\n"
|
||||
"Please create manually a unique BBA Structured Communication."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: selection:res.partner,out_inv_comm_algorithm:0
|
||||
msgid "Date"
|
||||
msgstr "التاريخ"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: model:ir.model,name:l10n_be_invoice_bba.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr "الشريك"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:156
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Unsupported Structured Communication Type Algorithm '%s' !\n"
|
||||
"Please contact your OpenERP support channel."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: field:res.partner,out_inv_comm_algorithm:0
|
||||
msgid "Communication Algorithm"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
#: code:addons/l10n_be_invoice_bba/invoice.py:168
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Empty BBA Structured Communication!\n"
|
||||
"Please fill in a unique BBA Structured Communication."
|
||||
msgstr ""
|
|
@ -8,45 +8,45 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2010-08-02 21:08+0000\n"
|
||||
"PO-Revision-Date: 2010-12-10 17:50+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 13:59+0000\n"
|
||||
"Last-Translator: Milan Milosevic <Unknown>\n"
|
||||
"Language-Team: Serbian latin <sr@latin@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: 2011-11-05 05:56+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_receivable
|
||||
msgid "Receivable"
|
||||
msgstr ""
|
||||
msgstr "Potraživanja"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.acct_type_asset_view
|
||||
msgid "Asset View"
|
||||
msgstr ""
|
||||
msgstr "Pregled sredstava"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:ir.module.module,description:l10n_ca.module_meta_information
|
||||
msgid ""
|
||||
"This is the module to manage the canadian accounting chart in OpenERP."
|
||||
msgstr ""
|
||||
msgstr "Ovo je modul za podešavanja kanadske obračunske tabele u OpenERP-u."
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.acct_type_expense_view
|
||||
msgid "Expense View"
|
||||
msgstr ""
|
||||
msgstr "Pregled troškova"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: constraint:account.account.template:0
|
||||
msgid "Error ! You can not create recursive account templates."
|
||||
msgstr ""
|
||||
msgstr "Greška ! Ne možete praviti rekurzivne obrasce naloga."
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.acct_type_income_view
|
||||
msgid "Income View"
|
||||
msgstr ""
|
||||
msgstr "Pregled prihoda"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:ir.module.module,shortdesc:l10n_ca.module_meta_information
|
||||
|
@ -56,17 +56,17 @@ msgstr "Kanada - Tabela Nalogâ"
|
|||
#. module: l10n_ca
|
||||
#: constraint:account.account.type:0
|
||||
msgid "Error ! You can not create recursive types."
|
||||
msgstr ""
|
||||
msgstr "Greška ! Ne možete praviti rekurzivne tipove."
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_tax
|
||||
msgid "Tax"
|
||||
msgstr ""
|
||||
msgstr "Porez"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_cash
|
||||
msgid "Cash"
|
||||
msgstr ""
|
||||
msgstr "Gotovina"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:ir.actions.todo,note:l10n_ca.config_call_account_template_ca
|
||||
|
@ -79,43 +79,50 @@ msgid ""
|
|||
"Management/Configuration/Financial Accounting/Financial Accounts/Generate "
|
||||
"Chart of Accounts from a Chart Template."
|
||||
msgstr ""
|
||||
"Generiše tabelu računâ iz šablona tabelâ. Bićete upitani za ime kompanije, "
|
||||
"šablon tabelâ koji ćete pratiti, broj cifara za generisanje koda za Vaše "
|
||||
"naloge i bankovni račun, valuta za pravljenje dnevnika. Na taj način se "
|
||||
"generiše čista kopija šablona tabelâ.\n"
|
||||
"\tTo je isti setup wizard koji se pokreće iz Financial "
|
||||
"Management/Configuration/Financial Accounting/Financial Accounts/Generate "
|
||||
"Chart of Accounts from a Chart Template."
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_payable
|
||||
msgid "Payable"
|
||||
msgstr ""
|
||||
msgstr "Plativo"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_asset
|
||||
msgid "Asset"
|
||||
msgstr ""
|
||||
msgstr "Sredstvo"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_equity
|
||||
msgid "Equity"
|
||||
msgstr ""
|
||||
msgstr "Kapital"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: constraint:account.tax.code.template:0
|
||||
msgid "Error ! You can not create recursive Tax Codes."
|
||||
msgstr ""
|
||||
msgstr "Greška ! Ne možete praviti rekurzivne porezne kodove."
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.acct_type_liability_view
|
||||
msgid "Liability View"
|
||||
msgstr ""
|
||||
msgstr "Pregled odgovornosti"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_expense
|
||||
msgid "Expense"
|
||||
msgstr ""
|
||||
msgstr "Trošak"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_income
|
||||
msgid "Income"
|
||||
msgstr ""
|
||||
msgstr "Prihod"
|
||||
|
||||
#. module: l10n_ca
|
||||
#: model:account.account.type,name:l10n_ca.account_type_view
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
msgstr "Pregled"
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
# Arabic 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 07:35+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Arabic <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: 2012-04-07 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid ""
|
||||
"\n"
|
||||
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
|
||||
"valid payments"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
|
||||
msgid "RIB and optional IBAN"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,rib_acc_number:0
|
||||
msgid "RIB account number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,bank_code:0
|
||||
msgid "Bank Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: code:addons/l10n_fr_rib/bank.py:54
|
||||
#, python-format
|
||||
msgid "The RIB key %s does not correspond to the other codes: %s %s %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_office_field
|
||||
msgid "office"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.bank,rib_code:0
|
||||
msgid "RIB Bank Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: code:addons/l10n_fr_rib/bank.py:58
|
||||
#, python-format
|
||||
msgid "The IBAN %s is not valid."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:ir.model,name:l10n_fr_rib.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr "الحسابات المصرفية"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,office:0
|
||||
msgid "Office Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
|
||||
msgid "bank_bic"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bank_code_field
|
||||
msgid "bank_code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_key_field
|
||||
msgid "key"
|
||||
msgstr "مفتاح"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_rib_acc_number_field
|
||||
msgid "rib_acc_number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: help:res.partner.bank,key:0
|
||||
msgid ""
|
||||
"The key is a number allowing to check the correctness of the other codes."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,key:0
|
||||
msgid "Key"
|
||||
msgstr "مفتاح"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: code:addons/l10n_fr_rib/bank.py:53
|
||||
#: code:addons/l10n_fr_rib/bank.py:58
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "خطأ"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type,format_layout:l10n_fr_rib.bank_rib
|
||||
msgid "%(bank_name)s: %(bank_code)s %(office)s %(rib_acc_number)s %(key)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid "The RIB and/or IBAN is not valid"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:ir.model,name:l10n_fr_rib.model_res_bank
|
||||
msgid "Bank"
|
||||
msgstr "مصرف"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_acc_number_field
|
||||
msgid "acc_number"
|
||||
msgstr "acc_number"
|
|
@ -0,0 +1,115 @@
|
|||
# Arabic 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-12-23 09:56+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 07:46+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Arabic <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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_receivable
|
||||
msgid "Receivable"
|
||||
msgstr "الدائنون"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_stocks
|
||||
msgid "Actif circulant"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_commitment
|
||||
msgid "Engagements"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_expense
|
||||
msgid "Expense"
|
||||
msgstr "مصروف"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_stock
|
||||
msgid "Stocks"
|
||||
msgstr "الأسهم"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_provision
|
||||
msgid "Provisions"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_income
|
||||
msgid "Income"
|
||||
msgstr "الدخل"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_tax
|
||||
msgid "Tax"
|
||||
msgstr "ضريبة"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_cash
|
||||
msgid "Cash"
|
||||
msgstr "نقدي"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_immobilisations
|
||||
msgid "Immobilisations"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_special
|
||||
msgid "Comptes spéciaux"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_payable
|
||||
msgid "Payable"
|
||||
msgstr "مدفوعات"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_asset
|
||||
msgid "Asset"
|
||||
msgstr "أصل"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_view
|
||||
msgid "View"
|
||||
msgstr "عرض"
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_equity
|
||||
msgid "Equity"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_cloture
|
||||
msgid "Cloture"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:account.account.type,name:l10n_syscohada.account_type_dettes
|
||||
msgid "Dettes long terme"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_syscohada
|
||||
#: model:ir.actions.todo,note:l10n_syscohada.config_call_account_template_syscohada
|
||||
msgid ""
|
||||
"Generate Chart of Accounts from a SYSCOHADA Chart Template. You will be "
|
||||
"asked to pass the name of the company, the chart template to follow, the no. "
|
||||
"of digits to generate the code for your accounts and Bank account, currency "
|
||||
"to create Journals. Thus,the pure copy of chart Template is generated.\n"
|
||||
"\tThis is the same wizard that runs from Financial "
|
||||
"Management/Configuration/Financial Accounting/Financial Accounts/Generate "
|
||||
"Chart of Accounts from a Chart Template."
|
||||
msgstr ""
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2011-09-05 06:39+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:39+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-02-09 07:07+0000\n"
|
||||
"X-Generator: Launchpad (build 14763)\n"
|
||||
"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: lunch
|
||||
|
@ -25,7 +25,7 @@ msgstr "Nulovat pokladnu"
|
|||
#. module: lunch
|
||||
#: view:report.lunch.amount:0
|
||||
msgid "Box amount in current year"
|
||||
msgstr ""
|
||||
msgstr "Částka pokladny v aktuálním roce"
|
||||
|
||||
#. module: lunch
|
||||
#: model:ir.actions.act_window,name:lunch.action_lunch_order_form
|
||||
|
@ -96,6 +96,8 @@ msgid ""
|
|||
"You can create on cashbox by employee if you want to keep track of the "
|
||||
"amount due by employee according to what have been ordered."
|
||||
msgstr ""
|
||||
"Můžete vytvořit pokladu podle zaměstnance, pokud chcete udržet přehled o "
|
||||
"dlužených částkách podle zaměstnance podle toho co si objednal."
|
||||
|
||||
#. module: lunch
|
||||
#: field:lunch.cashmove,amount:0 field:report.lunch.amount,amount:0
|
||||
|
@ -151,7 +153,7 @@ msgstr "Stav"
|
|||
#. module: lunch
|
||||
#: selection:lunch.order,state:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
msgstr "Nový"
|
||||
|
||||
#. module: lunch
|
||||
#: field:report.lunch.order,price_total:0
|
||||
|
@ -181,7 +183,7 @@ msgstr "Popis objednávky"
|
|||
#. module: lunch
|
||||
#: view:report.lunch.amount:0
|
||||
msgid "Box amount in last month"
|
||||
msgstr ""
|
||||
msgstr "Částka pokladny v minulém měsíci"
|
||||
|
||||
#. module: lunch
|
||||
#: model:ir.actions.act_window,name:lunch.action_lunch_order_confirm
|
||||
|
@ -233,7 +235,7 @@ msgstr "Pohyb hotovosti"
|
|||
#. module: lunch
|
||||
#: view:report.lunch.order:0
|
||||
msgid "Tasks performed in last 365 days"
|
||||
msgstr ""
|
||||
msgstr "Úkoly vykonané v posledních 365 dnech"
|
||||
|
||||
#. module: lunch
|
||||
#: selection:report.lunch.amount,month:0 selection:report.lunch.order,month:0
|
||||
|
@ -306,6 +308,10 @@ msgid ""
|
|||
"by supplier. It will be easier for the lunch manager to filter lunch orders "
|
||||
"by categories."
|
||||
msgstr ""
|
||||
"Určuje všechny výrobky, které zaměstnanci mohou objednat pro obědový čas. "
|
||||
"Pokud si objednáte oběd na více místech, můžete použít kategorie výrobků pro "
|
||||
"rozdělení dodavatelů. Bude pak jednodušší pro správce obědů filtrovat "
|
||||
"objednávky obědů podle kategorie."
|
||||
|
||||
#. module: lunch
|
||||
#: selection:report.lunch.amount,month:0 selection:report.lunch.order,month:0
|
||||
|
@ -398,7 +404,7 @@ msgstr "Nastavit pokladnu na nulu"
|
|||
#. module: lunch
|
||||
#: view:lunch.product:0
|
||||
msgid "General Information"
|
||||
msgstr ""
|
||||
msgstr "Obecné informace"
|
||||
|
||||
#. module: lunch
|
||||
#: view:lunch.order.confirm:0
|
||||
|
@ -480,7 +486,7 @@ msgstr "Celková částka"
|
|||
#. module: lunch
|
||||
#: view:report.lunch.order:0
|
||||
msgid "Tasks performed in last 30 days"
|
||||
msgstr ""
|
||||
msgstr "Úkoly vykonané v posledních 30 dnech"
|
||||
|
||||
#. module: lunch
|
||||
#: view:lunch.category:0
|
||||
|
@ -507,17 +513,17 @@ msgstr "Obědnávka obědu"
|
|||
#. module: lunch
|
||||
#: view:report.lunch.amount:0
|
||||
msgid "Box amount in current month"
|
||||
msgstr ""
|
||||
msgstr "Obsah pokladny v aktuálním měsíci"
|
||||
|
||||
#. module: lunch
|
||||
#: model:ir.actions.act_window,name:lunch.view_lunch_product_form_installer
|
||||
msgid "Define Your Lunch Products"
|
||||
msgstr ""
|
||||
msgstr "Určete vaše obědové výrobky"
|
||||
|
||||
#. module: lunch
|
||||
#: view:report.lunch.order:0
|
||||
msgid "Tasks during last 7 days"
|
||||
msgstr ""
|
||||
msgstr "Úkoly během posledních 7 dní"
|
||||
|
||||
#. module: lunch
|
||||
#: model:ir.actions.act_window,name:lunch.action_report_lunch_amount_tree
|
||||
|
@ -549,7 +555,7 @@ msgstr "Rok"
|
|||
#. module: lunch
|
||||
#: model:ir.actions.act_window,name:lunch.action_create_cashbox
|
||||
msgid "Create Lunch Cash Boxes"
|
||||
msgstr ""
|
||||
msgstr "Vytvořit obědové pokladny"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
|
||||
import mail_message
|
||||
import mail_thread
|
||||
import mail_group
|
||||
import mail_subscription
|
||||
import res_users
|
||||
import res_partner
|
||||
import report
|
||||
import wizard
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -56,16 +56,41 @@ The main features are:
|
|||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base', 'base_tools'],
|
||||
'data': [
|
||||
"wizard/mail_compose_message_view.xml",
|
||||
"mail_message_view.xml",
|
||||
"mail_thread_view.xml",
|
||||
"res_partner_view.xml",
|
||||
'wizard/mail_compose_message_view.xml',
|
||||
'mail_message_view.xml',
|
||||
'mail_subscription_view.xml',
|
||||
'mail_thread_view.xml',
|
||||
'mail_group_view.xml',
|
||||
'res_partner_view.xml',
|
||||
'report/mail_message_report_view.xml',
|
||||
'security/mail_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'mail_data.xml',
|
||||
'res_users_view.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '001056784984222247309',
|
||||
'images': ['images/customer_history.jpeg','images/messages_form.jpeg','images/messages_list.jpeg'],
|
||||
'images': [
|
||||
'images/customer_history.jpeg',
|
||||
'images/messages_form.jpeg',
|
||||
'images/messages_list.jpeg',
|
||||
'static/src/img/email_icong.png',
|
||||
'static/src/img/_al.png',
|
||||
'static/src/img/_pincky.png',
|
||||
'static/src/img/feeds.png',
|
||||
'static/src/img/feeds-hover.png',
|
||||
'static/src/img/groupdefault.png',
|
||||
],
|
||||
'css': [
|
||||
'static/src/css/mail.css',
|
||||
'static/src/css/mail_group.css',
|
||||
],
|
||||
'js': [
|
||||
'static/src/js/mail.js',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/mail.xml',
|
||||
],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
:orphan:
|
||||
|
||||
Mail module documentation
|
||||
=========================
|
||||
|
||||
.. include:: index.rst.inc
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
Mail Module
|
||||
'''''''''''
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
mail_thread
|
|
@ -0,0 +1,23 @@
|
|||
.. _mail_thread:
|
||||
|
||||
OpenChatter
|
||||
===========
|
||||
|
||||
TODO
|
||||
|
||||
mail.group
|
||||
++++++++++
|
||||
|
||||
A mail_group is a collection of users sharing messages in a discussion group. Group users are users that follow the mail group, using the subscription/follow mechanism of OpenSocial. A mail group has nothing in common wih res.users.group.
|
||||
Additional information on fields:
|
||||
- ``member_ids``: user member of the groups are calculated with ``message_get_subscribers`` method from mail.thread
|
||||
- ``member_count``: calculated with member_ids
|
||||
- ``is_subscriber``: calculated with member_ids
|
||||
|
||||
res.users
|
||||
+++++++++
|
||||
|
||||
OpenChatter updates the res.users class:
|
||||
- it adds a preference about sending emails when receiving a notification
|
||||
- make a new user follow itself automatically
|
||||
- create a welcome message when creating a new user, to make his arrival in OpenERP more friendly
|
|
@ -0,0 +1,138 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2010-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/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import datetime as DT
|
||||
import io
|
||||
import openerp
|
||||
import openerp.tools as tools
|
||||
from operator import itemgetter
|
||||
from osv import osv
|
||||
from osv import fields
|
||||
from PIL import Image
|
||||
import StringIO
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
class mail_group(osv.osv):
|
||||
"""
|
||||
A mail_group is a collection of users sharing messages in a discussion
|
||||
group. Group users are users that follow the mail group, using the
|
||||
subscription/follow mechanism of OpenSocial. A mail group has nothing
|
||||
in common wih res.users.group.
|
||||
Additional information on fields:
|
||||
- ``member_ids``: user member of the groups are calculated with
|
||||
``message_get_subscribers`` method from mail.thread
|
||||
- ``member_count``: calculated with member_ids
|
||||
- ``is_subscriber``: calculated with member_ids
|
||||
|
||||
"""
|
||||
|
||||
_description = 'Discussion group'
|
||||
_name = 'mail.group'
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
def action_group_join(self, cr, uid, ids, context={}):
|
||||
return self.message_subscribe(cr, uid, ids, context=context);
|
||||
|
||||
def action_group_leave(self, cr, uid, ids, context={}):
|
||||
return self.message_unsubscribe(cr, uid, ids, context=context);
|
||||
|
||||
def onchange_photo(self, cr, uid, ids, value, context=None):
|
||||
if not value:
|
||||
return {'value': {'avatar_big': value, 'avatar': value} }
|
||||
return {'value': {'photo_big': value, 'photo': self._photo_resize(cr, uid, value) } }
|
||||
|
||||
def _set_photo(self, cr, uid, id, name, value, args, context=None):
|
||||
if value:
|
||||
return self.write(cr, uid, [id], {'photo_big': value}, context=context)
|
||||
else:
|
||||
return self.write(cr, uid, [id], {'photo_big': value}, context=context)
|
||||
|
||||
def _photo_resize(self, cr, uid, photo, width=128, height=128, context=None):
|
||||
image_stream = io.BytesIO(photo.decode('base64'))
|
||||
img = Image.open(image_stream)
|
||||
img.thumbnail((width, height), Image.ANTIALIAS)
|
||||
img_stream = StringIO.StringIO()
|
||||
img.save(img_stream, "JPEG")
|
||||
return img_stream.getvalue().encode('base64')
|
||||
|
||||
def _get_photo(self, cr, uid, ids, name, args, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
for group in self.browse(cr, uid, ids, context=context):
|
||||
if group.photo_big:
|
||||
result[group.id] = self._photo_resize(cr, uid, group.photo_big, context=context)
|
||||
return result
|
||||
|
||||
def get_member_ids(self, cr, uid, ids, field_names, args, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = dict.fromkeys(ids)
|
||||
for id in ids:
|
||||
result[id] = {}
|
||||
result[id]['member_ids'] = self.message_get_subscribers_ids(cr, uid, [id], context=context)
|
||||
result[id]['member_count'] = len(result[id]['member_ids'])
|
||||
result[id]['is_subscriber'] = uid in result[id]['member_ids']
|
||||
return result
|
||||
|
||||
def search_member_ids(self, cr, uid, obj, name, args, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
sub_obj = self.pool.get('mail.subscription')
|
||||
sub_ids = sub_obj.search(cr, uid, ['&', ('res_model', '=', obj._name), ('user_id', '=', args[0][2])], context=context)
|
||||
subs = sub_obj.read(cr, uid, sub_ids, context=context)
|
||||
return [('id', 'in', map(itemgetter('res_id'), subs))]
|
||||
|
||||
def get_last_month_msg_nbr(self, cr, uid, ids, name, args, context=None):
|
||||
result = {}
|
||||
message_obj = self.pool.get('mail.message')
|
||||
for id in ids:
|
||||
lower_date = (DT.datetime.now() - DT.timedelta(days=30)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
result[id] = message_obj.search(cr, uid, ['&', '&', ('model', '=', self._name), ('res_id', 'in', ids), ('date', '>=', lower_date)], count=True, context=context)
|
||||
return result
|
||||
|
||||
def _get_default_photo(self, cr, uid, context=None):
|
||||
avatar_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
|
||||
return self._photo_resize(cr, uid, open(avatar_path, 'rb').read().encode('base64'), context=context)
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'description': fields.text('Description'),
|
||||
'responsible_id': fields.many2one('res.users', string='Responsible',
|
||||
ondelete='set null', required=True, select=1,
|
||||
help="Responsible of the group that has all rights on the record."),
|
||||
'public': fields.boolean('Public', help='This group is visible by non members. Invisible groups can add members through the invite button.'),
|
||||
'photo_big': fields.binary('Full-size photo', help='Field holding the full-sized PIL-supported and base64 encoded version of the group image. The photo field is used as an interface for this field.'),
|
||||
'photo': fields.function(_get_photo, fnct_inv=_set_photo, string='Photo', type="binary",
|
||||
store = {
|
||||
'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['photo_big'], 10),
|
||||
}, help='Field holding the automatically resized (128x128) PIL-supported and base64 encoded version of the group image.'),
|
||||
'member_ids': fields.function(get_member_ids, fnct_search=search_member_ids, type='many2many',
|
||||
relation='res.users', string='Group members', multi='get_member_ids'),
|
||||
'member_count': fields.function(get_member_ids, type='integer', string='Member count', multi='get_member_ids'),
|
||||
'is_subscriber': fields.function(get_member_ids, type='boolean', string='Joined', multi='get_member_ids'),
|
||||
'last_month_msg_nbr': fields.function(get_last_month_msg_nbr, type='integer', string='Messages count for last month'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'public': True,
|
||||
'responsible_id': (lambda s, cr, uid, ctx: uid),
|
||||
'photo': _get_default_photo,
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Group Kanban View !-->
|
||||
<record model="ir.ui.view" id="view_group_kanban">
|
||||
<field name="name">mail.group.kanban</field>
|
||||
<field name="model">mail.group</field>
|
||||
<field name="type">kanban</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-description">
|
||||
<div class="oe_group_description" t-if="record.description.raw_value">
|
||||
<field name="description"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="{record.is_subscriber.raw_value} oe_group_vignette">
|
||||
<div class="oe_group_image">
|
||||
<a type="edit"><img t-att-src="kanban_image('mail.group', 'photo', record.id.value)" class="oe_group_photo" tooltip="kanban-description"/></a>
|
||||
</div>
|
||||
<div class="oe_group_details">
|
||||
<h4><a type="edit"><field name="name"/></a></h4>
|
||||
<span style="display: none;"><field name="is_subscriber"/></span>
|
||||
<ul>
|
||||
<li><field name="member_count"/> members</li>
|
||||
<li t-if="! record.is_subscriber.raw_value"><a name="action_group_join" string="Join" type="object" class="oe_group_join">Not following</a></li>
|
||||
<li t-if="record.is_subscriber.raw_value"><a name="action_group_leave" string="Join" type="object" class="oe_group_leave">Following</a></li>
|
||||
<li><field name="last_month_msg_nbr"/> messages last month</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('.oe_group_photo').load(function() { if($(this).width() > $(this).height()) { $(this).addClass('oe_group_photo_wide') } });
|
||||
$('.oe_group_join').mouseover(function () { $(this).html('Follow'); }).mouseleave(function () { $(this).html('Not following'); });
|
||||
$('.oe_group_leave').mouseover(function () { $(this).html('Unfollow'); }).mouseleave(function () { $(this).html('Following'); });
|
||||
</script>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Group Form View !-->
|
||||
<record model="ir.ui.view" id="view_group_form">
|
||||
<field name="name">mail.group.form</field>
|
||||
<field name="model">mail.group</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Group">
|
||||
<group colspan="4" col="8">
|
||||
<group colspan="6" col="4">
|
||||
<separator string="General information" colspan="4"/>
|
||||
<field name="name" colspan="2"/>
|
||||
<field name="responsible_id" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="description" colspan="4"/>
|
||||
</group>
|
||||
<group colspan="1" col="2">
|
||||
<separator string="Group image" colspan="2"/>
|
||||
<field name="photo" widget='image' nolabel="1" on_change="onchange_photo(photo)"/>
|
||||
</group>
|
||||
<group colspan="1" col="2">
|
||||
<separator string="Privacy settings" colspan="2"/>
|
||||
<field name="public" nolabel="1"/>
|
||||
<label string="This group is visible by non members" colspan="2"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Group List View !-->
|
||||
<record model="ir.ui.view" id="view_group_tree">
|
||||
<field name="name">mail.group.tree</field>
|
||||
<field name="model">mail.group</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Groups">
|
||||
<field name="name"/>
|
||||
<field name="responsible_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Group Search View !-->
|
||||
<record model="ir.ui.view" id="view_group_search">
|
||||
<field name="name">mail.group.search</field>
|
||||
<field name="model">mail.group</field>
|
||||
<field name="type">search</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search groups">
|
||||
<field name="name"/>
|
||||
<field name="responsible_id"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- group record !-->
|
||||
<record id="action_view_groups" model="ir.actions.act_window">
|
||||
<field name="name">Groups</field>
|
||||
<field name="res_model">mail.group</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="search_view_id" ref="view_group_search"/>
|
||||
</record>
|
||||
|
||||
<!-- left-side menu: Groups !-->
|
||||
<menuitem id="mail_allgroups" name="All groups" parent="mail_feeds" sequence="12" action="action_view_groups"/>
|
||||
</data>
|
||||
</openerp>
|
|
@ -2,7 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2010-2011 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-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
|
||||
|
@ -26,6 +26,7 @@ import email
|
|||
import logging
|
||||
import re
|
||||
import time
|
||||
import datetime
|
||||
from email.header import decode_header
|
||||
from email.message import Message
|
||||
|
||||
|
@ -68,47 +69,82 @@ class mail_message_common(osv.osv_memory):
|
|||
database model or wizard screen that needs to hold a kind of
|
||||
message"""
|
||||
|
||||
def get_body(self, cr, uid, ids, name, arg, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = dict.fromkeys(ids, '')
|
||||
for message in self.browse(cr, uid, ids, context=context):
|
||||
if message.subtype == 'html':
|
||||
result[message.id] = message.body_html
|
||||
else:
|
||||
result[message.id] = message.body_text
|
||||
return result
|
||||
|
||||
def search_body(self, cr, uid, obj, name, args, context=None):
|
||||
"""will receive:
|
||||
- obj: mail.message object
|
||||
- name: 'body'
|
||||
- args: [('body', 'ilike', 'blah')]"""
|
||||
return ['|', '&', ('subtype', '=', 'html'), ('body_html', args[0][1], args[0][2]), ('body_text', args[0][1], args[0][2])]
|
||||
|
||||
def get_record_name(self, cr, uid, ids, name, arg, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = dict.fromkeys(ids, '')
|
||||
for message in self.browse(cr, uid, ids, context=context):
|
||||
if not message.model or not message.res_id:
|
||||
continue
|
||||
result[message.id] = self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1]
|
||||
return result
|
||||
|
||||
_name = 'mail.message.common'
|
||||
_rec_name = 'subject'
|
||||
_columns = {
|
||||
'subject': fields.char('Subject', size=512, required=True),
|
||||
'model': fields.char('Related Document model', size=128, select=1, readonly=1),
|
||||
'res_id': fields.integer('Related Document ID', select=1, readonly=1),
|
||||
'model': fields.char('Related Document model', size=128, select=1),
|
||||
'res_id': fields.integer('Related Document ID', select=1),
|
||||
'record_name': fields.function(get_record_name, type='string', string='Message record name',
|
||||
help="Name of the record, matching the result of the name_get."),
|
||||
'date': fields.datetime('Date'),
|
||||
'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences. If empty, this is not a mail but a message.'),
|
||||
'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences.'),
|
||||
'email_to': fields.char('To', size=256, help='Message recipients'),
|
||||
'email_cc': fields.char('Cc', size=256, help='Carbon copy message recipients'),
|
||||
'email_bcc': fields.char('Bcc', size=256, help='Blind carbon copy message recipients'),
|
||||
'reply_to':fields.char('Reply-To', size=256, help='Preferred response address for the message'),
|
||||
'headers': fields.text('Message headers', readonly=1,
|
||||
help="Full message headers, e.g. SMTP session headers "
|
||||
"(usually available on inbound messages only)"),
|
||||
help="Full message headers, e.g. SMTP session headers (usually available on inbound messages only)"),
|
||||
'message_id': fields.char('Message-Id', size=256, help='Message unique identifier', select=1, readonly=1),
|
||||
'references': fields.text('References', help='Message references, such as identifiers of previous messages', readonly=1),
|
||||
'subtype': fields.char('Message type', size=32, help="Type of message, usually 'html' or 'plain', used to "
|
||||
"select plaintext or rich text contents accordingly", readonly=1),
|
||||
'body_text': fields.text('Text contents', help="Plain-text version of the message"),
|
||||
'body_html': fields.text('Rich-text contents', help="Rich-text/HTML version of the message"),
|
||||
'body': fields.function(get_body, fnct_search = search_body, string='Message content', type='text',
|
||||
help="Content of the message. This content equals the body_text field for plain-test messages, and body_html for rich-text/HTML messages. This allows having one field if we want to access the content matching the message subtype."),
|
||||
'parent_id': fields.many2one('mail.message', 'Parent message', help="Parent message, used for displaying as threads with hierarchy",
|
||||
select=True, ondelete='set null',),
|
||||
'child_ids': fields.one2many('mail.message', 'parent_id', 'Child messages'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'subtype': 'plain'
|
||||
'subtype': 'plain',
|
||||
'date': (lambda *a: fields.datetime.now()),
|
||||
}
|
||||
|
||||
class mail_message(osv.osv):
|
||||
'''Model holding RFC2822 email messages, and providing facilities
|
||||
to parse, queue and send new messages
|
||||
|
||||
Messages that do not have a value for the email_from column
|
||||
are simple log messages (e.g. document state changes), while
|
||||
actual e-mails have the email_from value set.
|
||||
'''Model holding messages: system notification (replacing res.log
|
||||
notifications), comments (for OpenSocial feature) and
|
||||
RFC2822 email messages. This model also provides facilities to
|
||||
parse, queue and send new email messages. Type of messages
|
||||
are differentiated using the 'type' column.
|
||||
|
||||
The ``display_text`` field will have a slightly different
|
||||
presentation for real emails and for log messages.
|
||||
'''
|
||||
|
||||
_name = 'mail.message'
|
||||
_inherit = 'mail.message.common'
|
||||
_description = 'Email Message'
|
||||
_description = 'Mail Message (email, comment, notification)'
|
||||
_order = 'date desc'
|
||||
|
||||
# XXX to review - how to determine action to use?
|
||||
|
@ -163,8 +199,13 @@ class mail_message(osv.osv):
|
|||
msg_txt += (message.subject or '')
|
||||
result[message.id] = msg_txt
|
||||
return result
|
||||
|
||||
|
||||
_columns = {
|
||||
'type': fields.selection([
|
||||
('email', 'e-mail'),
|
||||
('comment', 'Comment'),
|
||||
('notification', 'System notification'),
|
||||
], 'Type', help="Message type: e-mail for e-mail message, notification for system message, comment for other messages such as user replies"),
|
||||
'partner_id': fields.many2one('res.partner', 'Related partner'),
|
||||
'user_id': fields.many2one('res.users', 'Related user', readonly=1),
|
||||
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', 'Attachments'),
|
||||
|
@ -180,11 +221,16 @@ class mail_message(osv.osv):
|
|||
'auto_delete': fields.boolean('Auto Delete', help="Permanently delete this email after sending it, to save space"),
|
||||
'original': fields.binary('Original', help="Original version of the message, as it was sent on the network", readonly=1),
|
||||
}
|
||||
|
||||
|
||||
_defaults = {
|
||||
'type': 'email',
|
||||
'state': 'received',
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------
|
||||
# E-Mail api
|
||||
#------------------------------------------------------
|
||||
|
||||
def init(self, cr):
|
||||
cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'mail_message_model_res_id_idx'""")
|
||||
if not cr.fetchone():
|
||||
|
@ -245,6 +291,7 @@ class mail_message(osv.osv):
|
|||
'user_id': uid,
|
||||
'model': model,
|
||||
'res_id': res_id,
|
||||
'type': 'email',
|
||||
'body_text': body if subtype != 'html' else False,
|
||||
'body_html': body if subtype == 'html' else False,
|
||||
'email_from': email_from,
|
||||
|
|
|
@ -1,6 +1,76 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- mail.message tree: short view !-->
|
||||
<record model="ir.ui.view" id="view_message_tree_short">
|
||||
<field name="name">mail.message.tree.short</field>
|
||||
<field name="model">mail.message</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Messages">
|
||||
<field name="date"/>
|
||||
<field name="subject"/>
|
||||
<field name="user_id"/>
|
||||
<field name="model"/>
|
||||
<field name="res_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- mail.message form: short view !-->
|
||||
<record model="ir.ui.view" id="view_message_form_short">
|
||||
<field name="name">mail.message.form.short</field>
|
||||
<field name="model">mail.message</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Message">
|
||||
<group colspan="2" col="2">
|
||||
<field name="subject"/>
|
||||
<field name="date"/>
|
||||
<field name="type"/>
|
||||
<field name="body_text"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<field name="user_id" string="User" readonly="0"/>
|
||||
<field name="model"/>
|
||||
<field name="res_id"/>
|
||||
<field name="parent_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- mail.message search: short view !-->
|
||||
<record model="ir.ui.view" id="view_message_search_short">
|
||||
<field name="name">mail.message.search.short</field>
|
||||
<field name="model">mail.message</field>
|
||||
<field name="type">search</field>
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Messages Search">
|
||||
<field name="user_id"/>
|
||||
<field name="model"/>
|
||||
<field name="date"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- mail.message search: wall view !-->
|
||||
<record model="ir.ui.view" id="view_message_search_wall">
|
||||
<field name="name">mail.message.search.wall</field>
|
||||
<field name="model">mail.message</field>
|
||||
<field name="type">search</field>
|
||||
<field name="priority">25</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Messages Search">
|
||||
<field name="user_id"/>
|
||||
<field name="body"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_email_message_form">
|
||||
<field name="name">mail.message.form</field>
|
||||
<field name="model">mail.message</field>
|
||||
|
@ -8,10 +78,11 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Email message">
|
||||
<group colspan="4" col="6">
|
||||
<field name="subject" colspan="4"/>
|
||||
<field name="date"/>
|
||||
<field name="user_id" string="User"/>
|
||||
<field name="partner_id" readonly="1" attrs="{'invisible':[('partner_id', '=', False)]}"/>
|
||||
<field name="subject" colspan="4"/>
|
||||
<field name="date"/>
|
||||
<field name="user_id" string="User"/>
|
||||
<field name="partner_id" readonly="1" attrs="{'invisible':[('partner_id', '=', False)]}"/>
|
||||
<field name="type"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
|
@ -31,7 +102,6 @@
|
|||
<field name="message_id" groups="base.group_extended" colspan="4" attrs="{'invisible':[('message_id', '=', False)]}"/>
|
||||
<field name="references" colspan="4" widget="char" size="512" groups="base.group_extended" attrs="{'invisible':[('references', '=', False)]}"/>
|
||||
</group>
|
||||
|
||||
<notebook colspan="4">
|
||||
<page string="Body (Rich)" attrs="{'invisible':[('subtype','=','plain')]}">
|
||||
<field name="body_html" widget="text_html" nolabel="1" colspan="4"/>
|
||||
|
@ -40,11 +110,11 @@
|
|||
<field name="body_text" colspan="4" widget="text" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
<separator string="" colspan="4"/>
|
||||
<group col="6" colspan="4">
|
||||
<group col="6" colspan="6">
|
||||
<field name="state" colspan="2"/>
|
||||
<group col="4" colspan="2">
|
||||
<field name="subtype" attrs="{'invisible':[('subtype', '=', False)]}"/>
|
||||
<group colspan="2">
|
||||
<button name="%(action_email_compose_message_wizard)d" string="Reply" type="action" icon="terp-mail-replied"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}" states='received,sent,exception,cancel'/>
|
||||
</group>
|
||||
|
@ -57,7 +127,6 @@
|
|||
<page string="Advanced" groups="base.group_extended">
|
||||
<group col="2" colspan="4">
|
||||
<field name="mail_server_id" attrs="{'invisible':[('mail_server_id', '=', False)]}"/>
|
||||
<field name="subtype" attrs="{'invisible':[('subtype', '=', False)]}"/>
|
||||
<field name="auto_delete"/>
|
||||
<field name="headers" colspan="4" attrs="{'invisible':[('headers', '=', False)]}"/>
|
||||
<field name="original" colspan="4" attrs="{'invisible':[('original', '=', False)]}"/>
|
||||
|
@ -80,6 +149,8 @@
|
|||
<field name="user_id" string="User"/>
|
||||
<field name="message_id" invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<field name="model" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
<button name="send" string="Send Now" type="object" icon="gtk-media-play" states='outgoing'/>
|
||||
<button name="mark_outgoing" string="Retry" type="object" icon="gtk-redo" states='exception,cancel'/>
|
||||
|
@ -100,7 +171,12 @@
|
|||
<filter icon="terp-call-start" name="outgoing" string="Outgoing" domain="[('state','=','outgoing')]"/>
|
||||
<filter icon="terp-check" name="sent" string="Sent" domain="[('state','=','sent')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-gtk-stop" string="Failed" domain="[('state','=','exception')]"/>
|
||||
<filter icon="terp-gtk-stop" name="exception" string="Failed" domain="[('state','=','exception')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-camera_test" name="type_email" string="Email" domain="[('type','=','email')]"/>
|
||||
<filter icon="terp-camera_test" name="type_comment" string="Comment" domain="[('type','=','comment')]"/>
|
||||
<filter icon="terp-camera_test" name="type_notification" string="Notification" domain="[('type','=','notification')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="email_from"/>
|
||||
<field name="email_to"/>
|
||||
<field name="subject"/>
|
||||
|
@ -109,6 +185,8 @@
|
|||
<group expand="0" string="Extended Filters..." groups="base.group_extended">
|
||||
<field name="user_id" string="User"/>
|
||||
<field name="partner_id" string="Partner Name"/>
|
||||
<field name="model"/>
|
||||
<field name="res_id"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By..." groups="base.group_extended">
|
||||
|
@ -124,12 +202,21 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_all_messages_short" model="ir.actions.act_window">
|
||||
<field name="name">Messages</field>
|
||||
<field name="res_model">mail.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'tree_view_ref': 'mail.view_message_tree_short', 'form_view_ref': 'mail.view_message_form_short'}</field>
|
||||
<field name="search_view_id" ref="view_message_search_short"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_mail_message" model="ir.actions.act_window">
|
||||
<field name="name">Messages</field>
|
||||
<field name="res_model">mail.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">['|',('state','in',['outgoing','exception']),('email_from', '!=', False)]</field>
|
||||
<field name="context">{'search_default_received': 1, 'search_default_type_email': 1}</field>
|
||||
<field name="search_view_id" ref="view_email_message_search"/>
|
||||
</record>
|
||||
|
||||
|
@ -140,10 +227,22 @@
|
|||
src_model="res.partner"
|
||||
view_id="view_email_message_tree"/>
|
||||
|
||||
<menuitem name="Messages"
|
||||
id="menu_email_message"
|
||||
parent="base.menu_email"
|
||||
action="action_view_mail_message" />
|
||||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Messages" id="menu_email_message" parent="base.menu_email" action="action_view_mail_message" />
|
||||
|
||||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Feeds" id="menu_email_message_all" parent="base.menu_email" action="action_view_all_messages_short" groups="base.group_no_one"/>
|
||||
|
||||
<record id="action_mail_all_feeds" model="ir.actions.client">
|
||||
<field name="name">All Feeds</field>
|
||||
<field name="tag">mail.all_feeds</field>
|
||||
<field name="params" eval="{'search_view_id': ref('view_message_search_wall')}"/>
|
||||
</record>
|
||||
|
||||
<record id="action_mail_my_feeds" model="ir.actions.client">
|
||||
<field name="name">My Feeds</field>
|
||||
<field name="tag">mail.all_feeds</field>
|
||||
<field name="params" eval="{'search_view_id': ref('view_message_search_wall'), 'my_feeds': True}"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009-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 osv import osv
|
||||
from osv import fields
|
||||
|
||||
class mail_subscription(osv.osv):
|
||||
"""
|
||||
mail_subscription holds the data related to the follow mechanism inside OpenERP.
|
||||
A subscription is characterized by:
|
||||
:param: res_model: model of the followed objects
|
||||
:param: res_id: ID of resource (may be 0 for every objects)
|
||||
:param: user_id: user_id of the follower
|
||||
"""
|
||||
_name = 'mail.subscription'
|
||||
_rec_name = 'id'
|
||||
_order = 'res_model asc'
|
||||
_description = 'Mail subscription'
|
||||
_columns = {
|
||||
'res_model': fields.char('Related Document Model', size=128,
|
||||
required=True, select=1,
|
||||
help='Model of the followed resource'),
|
||||
'res_id': fields.integer('Related Document ID', select=1,
|
||||
help='Id of the followed resource'),
|
||||
'user_id': fields.many2one('res.users', string='Related User',
|
||||
ondelete='cascade', required=True, select=1),
|
||||
}
|
||||
|
||||
class mail_notification(osv.osv):
|
||||
"""
|
||||
mail_notification is a relational table modeling messages pushed to users.
|
||||
:param: read: not used currently
|
||||
"""
|
||||
_name = 'mail.notification'
|
||||
_rec_name = 'id'
|
||||
_log_access = False
|
||||
_order = 'message_id desc'
|
||||
_description = 'Mail notification'
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', string='User',
|
||||
ondelete='cascade', required=True, select=1),
|
||||
'message_id': fields.many2one('mail.message', string='Message',
|
||||
ondelete='cascade', required=True, select=1),
|
||||
'read': fields.boolean('Read', help="Not used currently",),
|
||||
# TODO: add a timestamp ? or use message date ?
|
||||
}
|
||||
_defaults = {
|
||||
'read': False,
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!--
|
||||
SUBSCRIPTION
|
||||
!-->
|
||||
|
||||
<record model="ir.ui.view" id="view_subscription_tree">
|
||||
<field name="name">mail.subscription.tree</field>
|
||||
<field name="model">mail.subscription</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Subscription">
|
||||
<field name="res_model"/>
|
||||
<field name="res_id"/>
|
||||
<field name="user_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
NOTIFICATION
|
||||
!-->
|
||||
|
||||
<record model="ir.ui.view" id="view_notification_tree">
|
||||
<field name="name">mail.notification.tree</field>
|
||||
<field name="model">mail.notification</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Subscription">
|
||||
<field name="user_id"/>
|
||||
<field name="message_id"/>
|
||||
<field name="read"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_subscriptions" model="ir.actions.act_window">
|
||||
<field name="name">Subscriptions</field>
|
||||
<field name="res_model">mail.subscription</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_notifications" model="ir.actions.act_window">
|
||||
<field name="name">Pushed notif</field>
|
||||
<field name="res_model">mail.notification</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Subscriptions" id="menu_email_subscriptions" parent="base.menu_email" action="action_view_subscriptions" sequence="30" groups="base.group_no_one"/>
|
||||
|
||||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Notifications" id="menu_email_notifications" parent="base.menu_email" action="action_view_notifications" sequence="31" groups="base.group_no_one"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -2,7 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009-Today OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2009-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
|
||||
|
@ -19,19 +19,20 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import time
|
||||
import tools
|
||||
import base64
|
||||
import email
|
||||
from email.utils import parsedate
|
||||
|
||||
import logging
|
||||
import xmlrpclib
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
from mail_message import decode, to_email
|
||||
from operator import itemgetter
|
||||
from osv import osv, fields
|
||||
import re
|
||||
import time
|
||||
import tools
|
||||
from tools.translate import _
|
||||
import xmlrpclib
|
||||
|
||||
_logger = logging.getLogger('mail')
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class mail_thread(osv.osv):
|
||||
'''Mixin model, meant to be inherited by any model that needs to
|
||||
|
@ -40,24 +41,174 @@ class mail_thread(osv.osv):
|
|||
name collisions with methods of the models that will inherit
|
||||
from this mixin.
|
||||
|
||||
``mail.thread`` adds a one2many of mail.messages, acting as the
|
||||
thread's history, and a few methods that may be overridden to
|
||||
implement model-specific behavior upon arrival of new messages.
|
||||
``mail.thread`` is designed to work without adding any field
|
||||
to the extended models. All functionalities and expected behavior
|
||||
are managed by mail.thread, using model name and record ids.
|
||||
A widget has been designed for the 6.1 and following version of OpenERP
|
||||
web-client. However, due to technical limitations, ``mail.thread``
|
||||
adds a simulated one2many field, to display the web widget by
|
||||
overriding the default field displayed. Using this field
|
||||
is not recommanded has it will disappeear in future version
|
||||
of OpenERP, leading to a pure mixin class.
|
||||
|
||||
Inheriting classes are not required to implement any method, as the
|
||||
default implementation will work for any model. However it is common
|
||||
to override at least the ``message_new`` and ``message_update``
|
||||
methods (calling ``super``) to add model-specific behavior at
|
||||
creation and update of a thread.
|
||||
|
||||
creation and update of a thread; and ``message_get_subscribers``
|
||||
to manage more precisely the social aspect of the thread through
|
||||
the followers.
|
||||
'''
|
||||
_name = 'mail.thread'
|
||||
_description = 'Email Thread'
|
||||
|
||||
|
||||
def _get_message_ids(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
for id in ids:
|
||||
res[id] = self.message_load_ids(cr, uid, [id], context=context)
|
||||
return res
|
||||
|
||||
# OpenChatter: message_ids_social is a dummy field that should not be used
|
||||
_columns = {
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', readonly=True),
|
||||
'message_ids_social': fields.function(_get_message_ids, method=True,
|
||||
type='one2many', obj='mail.message', string='Temp messages', _fields_id = 'res_id'),
|
||||
}
|
||||
|
||||
#------------------------------------------------------
|
||||
# Automatic subscription when creating/reading
|
||||
#------------------------------------------------------
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Automatically subscribe the creator"""
|
||||
thread_id = super(mail_thread, self).create(cr, uid, vals, context=context);
|
||||
self.message_subscribe(cr, uid, [thread_id], [uid], context=context)
|
||||
return thread_id;
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""Automatically subscribe the writer"""
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
write_res = super(mail_thread, self).write(cr, uid, ids, vals, context=context);
|
||||
if write_res:
|
||||
self.message_subscribe(cr, uid, ids, [uid], context=context)
|
||||
return write_res;
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
"""Override unlink, to automatically delete
|
||||
- subscriptions
|
||||
- messages
|
||||
that are linked with res_model and res_id, not through
|
||||
a foreign key with a 'cascade' ondelete attribute.
|
||||
Notifications will be deleted with messages
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
subscr_obj = self.pool.get('mail.subscription')
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
# delete subscriptions
|
||||
subscr_to_del_ids = subscr_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
|
||||
subscr_obj.unlink(cr, uid, subscr_to_del_ids, context=context)
|
||||
# delete notifications
|
||||
msg_to_del_ids = msg_obj.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)], context=context)
|
||||
msg_obj.unlink(cr, uid, msg_to_del_ids, context=context)
|
||||
|
||||
return super(mail_thread, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Generic message api
|
||||
#------------------------------------------------------
|
||||
|
||||
def message_create(self, cr, uid, thread_id, vals, context=None):
|
||||
"""OpenSocial: wrapper of mail.message create method
|
||||
- creates the mail.message
|
||||
- automatically subscribe the message writer
|
||||
- push the message to subscribed users
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
message_obj = self.pool.get('mail.message')
|
||||
subscription_obj = self.pool.get('mail.subscription')
|
||||
notification_obj = self.pool.get('mail.notification')
|
||||
res_users_obj = self.pool.get('res.users')
|
||||
body = vals.get('body_html', '') if vals.get('subtype', 'plain') == 'html' else vals.get('body_text', '')
|
||||
|
||||
# automatically subscribe the writer of the message
|
||||
if vals['user_id']:
|
||||
self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context)
|
||||
|
||||
# get users that will get a notification pushed
|
||||
user_to_push_ids = self.message_create_get_notification_user_ids(cr, uid, [thread_id], vals, context=context)
|
||||
user_to_push_from_parse_ids = self.message_parse_users(cr, uid, [thread_id], body, context=context)
|
||||
|
||||
# set email_from and email_to for comments and notifications
|
||||
if vals.get('type', False) and vals['type'] == 'comment' or vals['type'] == 'notification':
|
||||
current_user = res_users_obj.browse(cr, uid, [uid], context=context)[0]
|
||||
if not vals.get('email_from', False):
|
||||
vals['email_from'] = current_user.user_email
|
||||
if not vals.get('email_to', False):
|
||||
email_to = ''
|
||||
for user in res_users_obj.browse(cr, uid, user_to_push_ids, context=context):
|
||||
if not user.notification_email_pref == 'all' and \
|
||||
not (user.notification_email_pref == 'comments' and vals['type'] == 'comment') and \
|
||||
not (user.notification_email_pref == 'to_me' and user.id in user_to_push_from_parse_ids):
|
||||
continue
|
||||
if not user.user_email:
|
||||
continue
|
||||
email_to = '%s, %s' % (email_to, user.user_email)
|
||||
email_to = email_to.lstrip(', ')
|
||||
if email_to:
|
||||
vals['email_to'] = email_to
|
||||
vals['state'] = 'outgoing'
|
||||
|
||||
# create message
|
||||
msg_id = message_obj.create(cr, uid, vals, context=context)
|
||||
|
||||
# special: if install mode, do not push demo data
|
||||
if context.get('install_mode', False):
|
||||
return True
|
||||
|
||||
# push to users
|
||||
for id in user_to_push_ids:
|
||||
notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context)
|
||||
|
||||
return msg_id
|
||||
|
||||
def message_create_get_notification_user_ids(self, cr, uid, thread_ids, new_msg_vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
notif_user_ids = []
|
||||
body = new_msg_vals.get('body_html', '') if new_msg_vals.get('subtype', 'plain') == 'html' else new_msg_vals.get('body_text', '')
|
||||
for thread_id in thread_ids:
|
||||
# add subscribers
|
||||
notif_user_ids += [user['id'] for user in self.message_get_subscribers(cr, uid, [thread_id], context=context)]
|
||||
# add users requested via parsing message (@login)
|
||||
notif_user_ids += self.message_parse_users(cr, uid, [thread_id], body, context=context)
|
||||
# add users requested to perform an action (need_action mechanism)
|
||||
if hasattr(self, 'get_needaction_user_ids'):
|
||||
notif_user_ids += self.get_needaction_user_ids(cr, uid, [thread_id], context=context)[thread_id]
|
||||
# add users notified of the parent messages (because: if parent message contains @login, login must receive the replies)
|
||||
if new_msg_vals.get('parent_id'):
|
||||
notif_obj = self.pool.get('mail.notification')
|
||||
parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', new_msg_vals.get('parent_id'))], context=context)
|
||||
parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, context=context)
|
||||
notif_user_ids += [parent_notif['user_id'][0] for parent_notif in parent_notifs]
|
||||
|
||||
# remove duplicate entries
|
||||
notif_user_ids = list(set(notif_user_ids))
|
||||
return notif_user_ids
|
||||
|
||||
def message_parse_users(self, cr, uid, ids, string, context=None):
|
||||
"""Parse message content
|
||||
- if find @login -(^|\s)@((\w|@|\.)*)-: returns the related ids
|
||||
this supports login that are emails (such as @admin@lapin.net)
|
||||
"""
|
||||
regex = re.compile('(^|\s)@((\w|@|\.)*)')
|
||||
login_lst = [item[1] for item in regex.findall(string)]
|
||||
if not login_lst: return []
|
||||
user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context=context)
|
||||
return user_ids
|
||||
|
||||
def message_capable_models(self, cr, uid, context=None):
|
||||
ret_dict = {}
|
||||
for model_name in self.pool.obj_list():
|
||||
|
@ -66,109 +217,32 @@ class mail_thread(osv.osv):
|
|||
ret_dict[model_name] = model._description
|
||||
return ret_dict
|
||||
|
||||
def message_thread_followers(self, cr, uid, ids, context=None):
|
||||
"""Returns a list of email addresses of the people following
|
||||
this thread, including the sender of each mail, and the
|
||||
people who were in CC of the messages, if any.
|
||||
"""
|
||||
res = {}
|
||||
if isinstance(ids, (str, int, long)):
|
||||
ids = [long(ids)]
|
||||
for thread in self.browse(cr, uid, ids, context=context):
|
||||
l = set()
|
||||
for message in thread.message_ids:
|
||||
l.add((message.user_id and message.user_id.user_email) or '')
|
||||
l.add(message.email_from or '')
|
||||
l.add(message.email_cc or '')
|
||||
res[thread.id] = filter(None, l)
|
||||
return res
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
"""Overrides default copy method to empty the thread of
|
||||
messages attached to this record, as the copied object
|
||||
will have its own thread and does not have to share it.
|
||||
"""
|
||||
if default is None:
|
||||
default = {}
|
||||
default.update({
|
||||
'message_ids': [],
|
||||
})
|
||||
return super(mail_thread, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def message_new(self, cr, uid, msg_dict, custom_values=None, context=None):
|
||||
"""Called by ``message_process`` when a new message is received
|
||||
for a given thread model, if the message did not belong to
|
||||
an existing thread.
|
||||
The default behavior is to create a new record of the corresponding
|
||||
model (based on some very basic info extracted from the message),
|
||||
then attach the message to the newly created record
|
||||
(by calling ``message_append_dict``).
|
||||
Additional behavior may be implemented by overriding this method.
|
||||
|
||||
:param dict msg_dict: a map containing the email details and
|
||||
attachments. See ``message_process`` and
|
||||
``mail.message.parse`` for details.
|
||||
:param dict custom_values: optional dictionary of additional
|
||||
field values to pass to create()
|
||||
when creating the new thread record.
|
||||
Be careful, these values may override
|
||||
any other values coming from the message.
|
||||
:param dict context: if a ``thread_model`` value is present
|
||||
in the context, its value will be used
|
||||
to determine the model of the record
|
||||
to create (instead of the current model).
|
||||
:rtype: int
|
||||
:return: the id of the newly created thread object
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
model = context.get('thread_model') or self._name
|
||||
model_pool = self.pool.get(model)
|
||||
fields = model_pool.fields_get(cr, uid, context=context)
|
||||
data = model_pool.default_get(cr, uid, fields, context=context)
|
||||
if 'name' in fields and not data.get('name'):
|
||||
data['name'] = msg_dict.get('from','')
|
||||
if custom_values and isinstance(custom_values, dict):
|
||||
data.update(custom_values)
|
||||
res_id = model_pool.create(cr, uid, data, context=context)
|
||||
self.message_append_dict(cr, uid, [res_id], msg_dict, context=context)
|
||||
return res_id
|
||||
|
||||
def message_update(self, cr, uid, ids, msg_dict, vals={}, default_act=None, context=None):
|
||||
"""Called by ``message_process`` when a new message is received
|
||||
for an existing thread. The default behavior is to create a
|
||||
new mail.message in the given thread (by calling
|
||||
``message_append_dict``)
|
||||
Additional behavior may be implemented by overriding this
|
||||
method.
|
||||
|
||||
:param dict msg_dict: a map containing the email details and
|
||||
attachments. See ``message_process`` and
|
||||
``mail.message.parse()`` for details.
|
||||
:param dict context: if a ``thread_model`` value is present
|
||||
in the context, its value will be used
|
||||
to determine the model of the thread to
|
||||
update (instead of the current model).
|
||||
"""
|
||||
return self.message_append_dict(cr, uid, ids, msg_dict, context=context)
|
||||
|
||||
def message_append(self, cr, uid, threads, subject, body_text=None, email_to=False,
|
||||
email_from=False, email_cc=None, email_bcc=None, reply_to=None,
|
||||
email_date=None, message_id=False, references=None,
|
||||
attachments=None, body_html=None, subtype=None, headers=None,
|
||||
original=None, context=None):
|
||||
def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None,
|
||||
parent_id=False, type='email', subtype='plain', state='received',
|
||||
email_to=False, email_from=False, email_cc=None, email_bcc=None,
|
||||
reply_to=None, email_date=None, message_id=False, references=None,
|
||||
attachments=None, headers=None, original=None, context=None):
|
||||
"""Creates a new mail.message attached to the current mail.thread,
|
||||
containing all the details passed as parameters. All attachments
|
||||
will be attached to the thread record as well as to the actual
|
||||
message.
|
||||
If only the ``threads`` and ``subject`` parameters are provided,
|
||||
a *event log* message is created, without the usual envelope
|
||||
attributes (sender, recipients, etc.).
|
||||
If ``email_from`` is not set or ``type`` not set as 'email',
|
||||
a note message is created, without the usual envelope
|
||||
attributes (sender, recipients, etc.).
|
||||
The creation of the message is done by calling ``message_create``
|
||||
method, that will manage automatic pushing of notifications.
|
||||
|
||||
:param threads: list of thread ids, or list of browse_records representing
|
||||
threads to which a new message should be attached
|
||||
:param subject: subject of the message, or description of the event if this
|
||||
is an *event log* entry.
|
||||
:param body_text: plaintext contents of the mail or log message
|
||||
:param body_html: html contents of the mail or log message
|
||||
:param parent_id: id of the parent message (threaded messaging model)
|
||||
:param type: optional type of message: 'email', 'comment', 'notification'
|
||||
:param subtype: optional subtype of message: 'plain' or 'html', corresponding to the main
|
||||
body contents (body_text or body_html).
|
||||
:param state: optional state of message; 'received' by default
|
||||
:param email_to: Email-To / Recipient address
|
||||
:param email_from: Email From / Sender address if any
|
||||
:param email_cc: Comma-Separated list of Carbon Copy Emails To addresse if any
|
||||
|
@ -177,10 +251,6 @@ class mail_thread(osv.osv):
|
|||
:param email_date: email date string if different from now, in server timezone
|
||||
:param message_id: optional email identifier
|
||||
:param references: optional email references
|
||||
:param body_text: plaintext contents of the mail or log message
|
||||
:param body_html: html contents of the mail or log message
|
||||
:param subtype: optional type of message: 'plain' or 'html', corresponding to the main
|
||||
body contents (body_text or body_html).
|
||||
:param headers: mail headers to store
|
||||
:param dict attachments: map of attachment filenames to binary contents, if any.
|
||||
:param str original: optional full source of the RFC2822 email, for reference
|
||||
|
@ -189,7 +259,7 @@ class mail_thread(osv.osv):
|
|||
to determine the model of the thread to
|
||||
update (instead of the current model).
|
||||
"""
|
||||
if context is None:
|
||||
if context is None:
|
||||
context = {}
|
||||
if attachments is None:
|
||||
attachments = {}
|
||||
|
@ -207,6 +277,7 @@ class mail_thread(osv.osv):
|
|||
ir_attachment = self.pool.get('ir.attachment')
|
||||
mail_message = self.pool.get('mail.message')
|
||||
|
||||
new_msg_ids = []
|
||||
for thread in threads:
|
||||
to_attach = []
|
||||
for attachment in attachments:
|
||||
|
@ -228,46 +299,39 @@ class mail_thread(osv.osv):
|
|||
partner_id = thread.id
|
||||
data = {
|
||||
'subject': subject,
|
||||
'body_text': body_text or (hasattr(thread, 'description') and thread.description or ''),
|
||||
'body_html': body_html or '',
|
||||
'parent_id': parent_id,
|
||||
'date': email_date or fields.datetime.now(),
|
||||
'type': type,
|
||||
'subtype': subtype,
|
||||
'state': state,
|
||||
'message_id': message_id,
|
||||
'attachment_ids': [(6, 0, to_attach)],
|
||||
'user_id': uid,
|
||||
'model' : thread._name,
|
||||
'partner_id': partner_id,
|
||||
'res_id': thread.id,
|
||||
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'message_id': message_id,
|
||||
'body_text': body_text or (hasattr(thread, 'description') and thread.description or False),
|
||||
'attachment_ids': [(6, 0, to_attach)],
|
||||
'state' : 'received',
|
||||
'partner_id': partner_id,
|
||||
}
|
||||
|
||||
if email_from:
|
||||
if email_from or type == 'email':
|
||||
for param in (email_to, email_cc, email_bcc):
|
||||
if isinstance(param, list):
|
||||
param = ", ".join(param)
|
||||
data = {
|
||||
data.update({
|
||||
'subject': subject or _('History'),
|
||||
'user_id': uid,
|
||||
'model' : thread._name,
|
||||
'res_id': thread.id,
|
||||
'date': email_date or time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'body_text': body_text,
|
||||
'email_to': email_to,
|
||||
'email_from': email_from or \
|
||||
(hasattr(thread, 'user_id') and thread.user_id and thread.user_id.user_email),
|
||||
'email_cc': email_cc,
|
||||
'email_bcc': email_bcc,
|
||||
'partner_id': partner_id,
|
||||
'references': references,
|
||||
'message_id': message_id,
|
||||
'attachment_ids': [(6, 0, to_attach)],
|
||||
'state' : 'received',
|
||||
'body_html': body_html,
|
||||
'subtype': subtype,
|
||||
'headers': headers,
|
||||
'reply_to': reply_to,
|
||||
'original': original,
|
||||
}
|
||||
mail_message.create(cr, uid, data, context=context)
|
||||
return True
|
||||
'original': original, })
|
||||
|
||||
new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context=context))
|
||||
return new_msg_ids
|
||||
|
||||
def message_append_dict(self, cr, uid, ids, msg_dict, context=None):
|
||||
"""Creates a new mail.message attached to the given threads (``ids``),
|
||||
|
@ -288,22 +352,101 @@ class mail_thread(osv.osv):
|
|||
return self.message_append(cr, uid, ids,
|
||||
subject = msg_dict.get('subject'),
|
||||
body_text = msg_dict.get('body_text'),
|
||||
email_to = msg_dict.get('to'),
|
||||
email_from = msg_dict.get('from'),
|
||||
email_cc = msg_dict.get('cc'),
|
||||
email_bcc = msg_dict.get('bcc'),
|
||||
reply_to = msg_dict.get('reply'),
|
||||
body_html= msg_dict.get('body_html'),
|
||||
parent_id = msg_dict.get('parent_id', False),
|
||||
type = msg_dict.get('type', 'email'),
|
||||
subtype = msg_dict.get('subtype', 'plain'),
|
||||
state = msg_dict.get('state', 'received'),
|
||||
email_from = msg_dict.get('from', msg_dict.get('email_from')),
|
||||
email_to = msg_dict.get('to', msg_dict.get('email_to')),
|
||||
email_cc = msg_dict.get('cc', msg_dict.get('email_cc')),
|
||||
email_bcc = msg_dict.get('bcc', msg_dict.get('email_bcc')),
|
||||
reply_to = msg_dict.get('reply', msg_dict.get('reply_to')),
|
||||
email_date = msg_dict.get('date'),
|
||||
message_id = msg_dict.get('message-id'),
|
||||
message_id = msg_dict.get('message-id', msg_dict.get('message_id')),
|
||||
references = msg_dict.get('references')\
|
||||
or msg_dict.get('in-reply-to'),
|
||||
attachments = msg_dict.get('attachments'),
|
||||
body_html= msg_dict.get('body_html'),
|
||||
subtype = msg_dict.get('subtype'),
|
||||
headers = msg_dict.get('headers'),
|
||||
original = msg_dict.get('original'),
|
||||
context = context)
|
||||
|
||||
# Message loading
|
||||
def _message_add_ancestor_ids(self, cr, uid, ids, child_ids, root_ids, context=None):
|
||||
""" Given message child_ids
|
||||
Find their ancestors until root ids"""
|
||||
if context is None:
|
||||
context = {}
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
tmp_msgs = msg_obj.read(cr, uid, child_ids, ['id', 'parent_id'], context=context)
|
||||
parent_ids = [msg['parent_id'][0] for msg in tmp_msgs if msg['parent_id'] and msg['parent_id'][0] not in root_ids and msg['parent_id'][0] not in child_ids]
|
||||
child_ids += parent_ids
|
||||
cur_iter = 0; max_iter = 100; # avoid infinite loop
|
||||
while (parent_ids and (cur_iter < max_iter)):
|
||||
cur_iter += 1
|
||||
tmp_msgs = msg_obj.read(cr, uid, parent_ids, ['id', 'parent_id'], context=context)
|
||||
parent_ids = [msg['parent_id'][0] for msg in tmp_msgs if msg['parent_id'] and msg['parent_id'][0] not in root_ids and msg['parent_id'][0] not in child_ids]
|
||||
child_ids += parent_ids
|
||||
if (cur_iter > max_iter):
|
||||
_logger.warning("Possible infinite loop in _message_add_ancestor_ids. Note that this algorithm is intended to check for cycle in message graph.")
|
||||
return child_ids
|
||||
|
||||
def message_load_ids(self, cr, uid, ids, limit=100, offset=0, domain=[], ascent=False, root_ids=[], context=None):
|
||||
""" OpenChatter feature: return thread messages ids. It searches in
|
||||
mail.messages where res_id = ids, (res_)model = current model.
|
||||
:param domain: domain to add to the search; especially child_of
|
||||
is interesting when dealing with threaded display
|
||||
:param ascent: performs an ascended search; will add to fetched msgs
|
||||
all their parents until root_ids
|
||||
:param root_ids: for ascent search
|
||||
:param root_ids: root_ids when performing an ascended search
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', ids), ('model', '=', self._name)] + domain,
|
||||
limit=limit, offset=offset, context=context)
|
||||
if (ascent): msg_ids = self._message_add_ancestor_ids(cr, uid, ids, msg_ids, root_ids, context=context)
|
||||
return msg_ids
|
||||
|
||||
def message_load(self, cr, uid, ids, limit=100, offset=0, domain=[], ascent=False, root_ids=[], context=None):
|
||||
""" OpenChatter feature: return thread messages
|
||||
"""
|
||||
msg_ids = self.message_load_ids(cr, uid, ids, limit, offset, domain, ascent, root_ids, context=context)
|
||||
return self.pool.get('mail.message').read(cr, uid, msg_ids, context=context)
|
||||
|
||||
def get_pushed_messages(self, cr, uid, ids, limit=100, offset=0, msg_search_domain=[], ascent=False, root_ids=[], context=None):
|
||||
""" OpenChatter: wall: get messages to display (=pushed notifications)
|
||||
:param domain: domain to add to the search; especially child_of
|
||||
is interesting when dealing with threaded display
|
||||
:param ascent: performs an ascended search; will add to fetched msgs
|
||||
all their parents until root_ids
|
||||
:param root_ids: for ascent search
|
||||
:return list of mail.messages sorted by date
|
||||
"""
|
||||
if context is None: context = {}
|
||||
notification_obj = self.pool.get('mail.notification')
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
# update message search
|
||||
for arg in msg_search_domain:
|
||||
if isinstance(arg, (tuple, list)):
|
||||
arg[0] = 'message_id.' + arg[0]
|
||||
# compose final domain
|
||||
domain = [('user_id', '=', uid)] + msg_search_domain
|
||||
# get notifications
|
||||
notification_ids = notification_obj.search(cr, uid, domain, limit=limit, offset=offset, context=context)
|
||||
notifications = notification_obj.browse(cr, uid, notification_ids, context=context)
|
||||
msg_ids = [notification.message_id.id for notification in notifications]
|
||||
# get messages
|
||||
msg_ids = msg_obj.search(cr, uid, [('id', 'in', msg_ids)], context=context)
|
||||
if (ascent): msg_ids = self._message_add_ancestor_ids(cr, uid, ids, msg_ids, root_ids, context=context)
|
||||
msgs = msg_obj.read(cr, uid, msg_ids, context=context)
|
||||
return msgs
|
||||
|
||||
#------------------------------------------------------
|
||||
# Email specific
|
||||
#------------------------------------------------------
|
||||
# message_process will call either message_new or message_update.
|
||||
|
||||
def message_process(self, cr, uid, model, message, custom_values=None,
|
||||
save_original=False, strip_attachments=False,
|
||||
|
@ -389,8 +532,79 @@ class mail_thread(osv.osv):
|
|||
self.message_forward(cr, uid, model, [res_id], msg_txt, context=context)
|
||||
return res_id
|
||||
|
||||
# for backwards-compatibility with old scripts
|
||||
process_email = message_process
|
||||
def message_new(self, cr, uid, msg_dict, custom_values=None, context=None):
|
||||
"""Called by ``message_process`` when a new message is received
|
||||
for a given thread model, if the message did not belong to
|
||||
an existing thread.
|
||||
The default behavior is to create a new record of the corresponding
|
||||
model (based on some very basic info extracted from the message),
|
||||
then attach the message to the newly created record
|
||||
(by calling ``message_append_dict``).
|
||||
Additional behavior may be implemented by overriding this method.
|
||||
|
||||
:param dict msg_dict: a map containing the email details and
|
||||
attachments. See ``message_process`` and
|
||||
``mail.message.parse`` for details.
|
||||
:param dict custom_values: optional dictionary of additional
|
||||
field values to pass to create()
|
||||
when creating the new thread record.
|
||||
Be careful, these values may override
|
||||
any other values coming from the message.
|
||||
:param dict context: if a ``thread_model`` value is present
|
||||
in the context, its value will be used
|
||||
to determine the model of the record
|
||||
to create (instead of the current model).
|
||||
:rtype: int
|
||||
:return: the id of the newly created thread object
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
model = context.get('thread_model') or self._name
|
||||
model_pool = self.pool.get(model)
|
||||
fields = model_pool.fields_get(cr, uid, context=context)
|
||||
data = model_pool.default_get(cr, uid, fields, context=context)
|
||||
if 'name' in fields and not data.get('name'):
|
||||
data['name'] = msg_dict.get('from','')
|
||||
if custom_values and isinstance(custom_values, dict):
|
||||
data.update(custom_values)
|
||||
res_id = model_pool.create(cr, uid, data, context=context)
|
||||
self.message_append_dict(cr, uid, [res_id], msg_dict, context=context)
|
||||
return res_id
|
||||
|
||||
def message_update(self, cr, uid, ids, msg_dict, vals={}, default_act=None, context=None):
|
||||
"""Called by ``message_process`` when a new message is received
|
||||
for an existing thread. The default behavior is to create a
|
||||
new mail.message in the given thread (by calling
|
||||
``message_append_dict``)
|
||||
Additional behavior may be implemented by overriding this
|
||||
method.
|
||||
|
||||
:param dict msg_dict: a map containing the email details and
|
||||
attachments. See ``message_process`` and
|
||||
``mail.message.parse()`` for details.
|
||||
:param dict context: if a ``thread_model`` value is present
|
||||
in the context, its value will be used
|
||||
to determine the model of the thread to
|
||||
update (instead of the current model).
|
||||
"""
|
||||
return self.message_append_dict(cr, uid, ids, msg_dict, context=context)
|
||||
|
||||
def message_thread_followers(self, cr, uid, ids, context=None):
|
||||
"""Returns a list of email addresses of the people following
|
||||
this thread, including the sender of each mail, and the
|
||||
people who were in CC of the messages, if any.
|
||||
"""
|
||||
res = {}
|
||||
if isinstance(ids, (str, int, long)):
|
||||
ids = [long(ids)]
|
||||
for thread in self.browse(cr, uid, ids, context=context):
|
||||
l = set()
|
||||
for message in thread.message_ids:
|
||||
l.add((message.user_id and message.user_id.user_email) or '')
|
||||
l.add(message.email_from or '')
|
||||
l.add(message.email_cc or '')
|
||||
res[thread.id] = filter(None, l)
|
||||
return res
|
||||
|
||||
def message_forward(self, cr, uid, model, thread_ids, msg, email_error=False, context=None):
|
||||
"""Sends an email to all people following the given threads.
|
||||
|
@ -465,4 +679,114 @@ class mail_thread(osv.osv):
|
|||
res['partner_id'] = contact.id
|
||||
return res
|
||||
|
||||
# for backwards-compatibility with old scripts
|
||||
process_email = message_process
|
||||
|
||||
#------------------------------------------------------
|
||||
# Note specific
|
||||
#------------------------------------------------------
|
||||
|
||||
def message_broadcast(self, cr, uid, ids, subject=None, body=None, parent_id=False, type='notification', subtype='html', context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
notification_obj = self.pool.get('mail.notification')
|
||||
# write message
|
||||
msg_ids = self.message_append_note(cr, uid, ids, subject=subject, body=body, parent_id=parent_id, type=type, subtype=subtype, context=context)
|
||||
# escape if in install mode or note writing was not successfull
|
||||
if 'install_mode' in context:
|
||||
return True
|
||||
if not isinstance(msg_ids, (list)):
|
||||
return True
|
||||
# get already existing notigications
|
||||
notification_ids = notification_obj.search(cr, uid, [('message_id', 'in', msg_ids)], context=context)
|
||||
already_pushed_user_ids = map(itemgetter('user_id'), notification_obj.read(cr, uid, notification_ids, context=context))
|
||||
# get base.group_user group
|
||||
res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user') or False
|
||||
group_id = res and res[1] or False
|
||||
if not group_id: return True
|
||||
group = self.pool.get('res.groups').browse(cr, uid, [group_id], context=context)[0]
|
||||
for user in group.users:
|
||||
if user.id in already_pushed_user_ids: continue
|
||||
for msg_id in msg_ids:
|
||||
notification_obj.create(cr, uid, {'user_id': user.id, 'message_id': msg_id}, context=context)
|
||||
return True
|
||||
|
||||
def log(self, cr, uid, id, message, secondary=False, context=None):
|
||||
_logger.warning("log() is deprecated. Please use OpenChatter notification system instead of the res.log mechanism.")
|
||||
self.message_append_note(cr, uid, [id], 'res.log', message, context=context)
|
||||
|
||||
def message_append_note(self, cr, uid, ids, subject=None, body=None, parent_id=False, type='notification', subtype='html', context=None):
|
||||
if subject is None:
|
||||
if type == 'notification':
|
||||
subject = _('System notification')
|
||||
elif type == 'comment' and not parent_id:
|
||||
subject = _('Comment')
|
||||
elif type == 'comment' and parent_id:
|
||||
subject = _('Reply')
|
||||
if subtype == 'html':
|
||||
body_html = body
|
||||
body_text = body
|
||||
else:
|
||||
body_html = body
|
||||
body_text = body
|
||||
return self.message_append(cr, uid, ids, subject, body_html=body_html, body_text=body_text, parent_id=parent_id, type=type, subtype=subtype, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Subscription mechanism
|
||||
#------------------------------------------------------
|
||||
|
||||
def message_get_subscribers_ids(self, cr, uid, ids, context=None):
|
||||
subscr_obj = self.pool.get('mail.subscription')
|
||||
subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
|
||||
subs = subscr_obj.read(cr, uid, subscr_ids, context=context)
|
||||
return [sub['user_id'][0] for sub in subs]
|
||||
|
||||
def message_get_subscribers(self, cr, uid, ids, context=None):
|
||||
user_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context)
|
||||
users = self.pool.get('res.users').read(cr, uid, user_ids, fields=['id', 'name', 'avatar'], context=context)
|
||||
return users
|
||||
|
||||
def message_is_subscriber(self, cr, uid, ids, user_id = None, context=None):
|
||||
users = self.message_get_subscribers(cr, uid, ids, context=context)
|
||||
sub_user_id = uid if user_id is None else user_id
|
||||
if sub_user_id in [user['id'] for user in users]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def message_subscribe(self, cr, uid, ids, user_ids = None, context=None):
|
||||
subscription_obj = self.pool.get('mail.subscription')
|
||||
to_subscribe_uids = [uid] if user_ids is None else user_ids
|
||||
create_ids = []
|
||||
for id in ids:
|
||||
for user_id in to_subscribe_uids:
|
||||
if self.message_is_subscriber(cr, uid, [id], user_id=user_id, context=context): continue
|
||||
create_ids.append(subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context))
|
||||
return create_ids
|
||||
|
||||
def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None):
|
||||
if not user_ids and not uid in self.message_get_subscribers_ids(cr, uid, ids, context=context):
|
||||
return False
|
||||
subscription_obj = self.pool.get('mail.subscription')
|
||||
to_unsubscribe_uids = [uid] if user_ids is None else user_ids
|
||||
to_delete_sub_ids = subscription_obj.search(cr, uid,
|
||||
['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', 'in', to_unsubscribe_uids)], context=context)
|
||||
subscription_obj.unlink(cr, uid, to_delete_sub_ids, context=context)
|
||||
return True
|
||||
|
||||
#------------------------------------------------------
|
||||
# Notification API
|
||||
#------------------------------------------------------
|
||||
|
||||
def message_remove_pushed_notifications(self, cr, uid, ids, msg_ids, remove_childs=True, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
notif_obj = self.pool.get('mail.notification')
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
if remove_childs:
|
||||
notif_msg_ids = msg_obj.search(cr, uid, [('id', 'child_of', msg_ids)], context=context)
|
||||
else:
|
||||
notif_msg_ids = msg_ids
|
||||
to_del_notif_ids = notif_obj.search(cr, uid, ['&', ('user_id', '=', uid), ('message_id', 'in', notif_msg_ids)], context=context)
|
||||
return notif_obj.unlink(cr, uid, to_del_notif_ids, context=context)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,53 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="view_mailgate_thread_form">
|
||||
<field name="name">mail.thread.form</field>
|
||||
<field name="model">mail.thread</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Thread">
|
||||
<separator string="Communication History" colspan="4"/>
|
||||
<field name="message_ids" nolabel="1" colspan="4" mode="tree">
|
||||
<tree string="Communication History">
|
||||
<field name="display_text"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
<!-- toplevel menu -->
|
||||
<record id="mail_feeds_main" model="ir.ui.menu">
|
||||
<field name="name">Feeds</field>
|
||||
<field name="sequence">0</field>
|
||||
<field name="web_icon" eval="static/src/img/feeds.png"/>
|
||||
<field name="web_icon_hover" eval="static/src/img/feeds-hover.png"/>
|
||||
<field name="action" ref="action_mail_all_feeds"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_mailgate_thread_tree">
|
||||
<field name="name">mail.thread.tree</field>
|
||||
<field name="model">mail.thread</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Email Threads">
|
||||
<field name="message_ids" />
|
||||
</tree>
|
||||
</field>
|
||||
<!-- left-side menu: Feeds !-->
|
||||
<menuitem id="mail_feeds" name="Feeds" parent="mail_feeds_main"/>
|
||||
<record id="mail_wallfeeds" model="ir.ui.menu">
|
||||
<field name="name">All Feeds</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="action" ref="action_mail_all_feeds"/>
|
||||
<field name="parent_id" ref="mail_feeds"/>
|
||||
</record>
|
||||
|
||||
<!-- Emails thread action -->
|
||||
<record model="ir.actions.act_window" id="action_view_mailgate_thread">
|
||||
<field name="name">Email Threads</field>
|
||||
<field name="res_model">mail.thread</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_tree"/>
|
||||
<record id="mail_myfeeds" model="ir.ui.menu">
|
||||
<field name="name">My Feeds</field>
|
||||
<field name="sequence" eval="11"/>
|
||||
<field name="action" ref="action_mail_my_feeds"/>
|
||||
<field name="parent_id" ref="mail_feeds"/>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_tree"/>
|
||||
<field name="act_window_id" ref="action_view_mailgate_thread"/>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_form"/>
|
||||
<field name="act_window_id" ref="action_view_mailgate_thread"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009-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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import mail_message_report
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009-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 osv import fields, osv
|
||||
import time
|
||||
import tools
|
||||
|
||||
class mail_message_report(osv.osv):
|
||||
#CSV:: access_res_log_report all,res.log.report,model_res_log_report,,1,0,0,0
|
||||
""" Log Report """
|
||||
_name = "mail.message.report"
|
||||
_auto = False
|
||||
_description = "Mail Message Report"
|
||||
_columns = {
|
||||
'name': fields.char('Year', size=64, required=False, readonly=True),
|
||||
'month':fields.selection([('01', 'January'), ('02', 'February'), \
|
||||
('03', 'March'), ('04', 'April'),\
|
||||
('05', 'May'), ('06', 'June'), \
|
||||
('07', 'July'), ('08', 'August'),\
|
||||
('09', 'September'), ('10', 'October'),\
|
||||
('11', 'November'), ('12', 'December')], 'Month', readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'creation_date': fields.date('Creation Date', readonly=True),
|
||||
'res_model': fields.char('Object', size=128),
|
||||
'nbr': fields.integer('# of Entries', readonly=True)
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
"""
|
||||
Log Report
|
||||
@param cr: the current row, from the database cursor
|
||||
"""
|
||||
tools.drop_view_if_exists(cr,'mail_message_report')
|
||||
cr.execute("""
|
||||
CREATE OR REPLACE VIEW mail_message_report AS (
|
||||
SELECT
|
||||
l.id as id,
|
||||
1 as nbr,
|
||||
to_char(l.create_date, 'YYYY') as name,
|
||||
to_char(l.create_date, 'MM') as month,
|
||||
to_char(l.create_date, 'YYYY-MM-DD') as day,
|
||||
to_char(l.create_date, 'YYYY-MM-DD') as creation_date,
|
||||
l.model as res_model,
|
||||
date_trunc('day',l.create_date) as create_date
|
||||
FROM
|
||||
mail_message l
|
||||
)""")
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Latest Activities -->
|
||||
<record model="ir.actions.act_window" id="action_latest_activities_tree">
|
||||
<field name="name">Latest Activities</field>
|
||||
<field name="res_model">mail.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<!-- Mail message report search view -->
|
||||
<record id="view_mail_message_report_filter" model="ir.ui.view">
|
||||
<field name="name">mail.message.report.select</field>
|
||||
<field name="model">mail.message.report</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Mail message Analysis">
|
||||
<group>
|
||||
<filter icon="terp-go-year" string=" Year "
|
||||
domain="[('create_date','<=', time.strftime('%%Y-%%m-%%d')),('create_date','>=',time.strftime('%%Y-01-01'))]"
|
||||
help="Messages created in current year"/>
|
||||
<filter icon="terp-go-month" string=" Month "
|
||||
name="month"
|
||||
domain="[('create_date','<=',(datetime.date.today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('create_date','>=',(datetime.date.today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Messages created in current month"/>
|
||||
<filter icon="terp-go-month"
|
||||
string=" Month-1 "
|
||||
domain="[('create_date','<=', (datetime.date.today() - relativedelta(day=31, months=1)).strftime('%%Y-%%m-%%d')),('create_date','>=',(datetime.date.today() - relativedelta(day=1,months=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Messages created in last month"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="1" string="Group By...">
|
||||
<filter string="Model" icon="terp-go-home" context="{'group_by':'res_model'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Day" icon="terp-go-today"
|
||||
domain="[]" context="{'group_by':'day'}"/>
|
||||
<filter string="Month" icon="terp-go-month"
|
||||
domain="[]" context="{'group_by':'month'}" />
|
||||
<filter string="Year" icon="terp-go-year"
|
||||
domain="[]" context="{'group_by':'name'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Mail message report Tree view -->
|
||||
<record id="view_mail_message_report_tree" model="ir.ui.view">
|
||||
<field name="name">mail.message.report.tree</field>
|
||||
<field name="model">mail.message.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Mail message Analysis">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="day" invisible="1"/>
|
||||
<field name="res_model" invisible="1"/>
|
||||
<field name="nbr" />
|
||||
<field name="creation_date" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Monthly Activity per Document -->
|
||||
<record id="board_mail_message_report_graph" model="ir.ui.view">
|
||||
<field name="name">board.mail.message.report.graph</field>
|
||||
<field name="model">mail.message.report</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Monthly Activity per Document" type="bar">
|
||||
<field name="res_model"/>
|
||||
<field name="nbr" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record id="board_monthly_mail_message_report_action" model="ir.actions.act_window">
|
||||
<field name="name">Monthly Activity per Document</field>
|
||||
<field name="res_model">mail.message.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,tree</field>
|
||||
<field name="domain">[('create_date','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="context">{'group_by':['res_model'],'group_by_no_leaf':1}</field>
|
||||
<field name="view_id" ref="board_mail_message_report_graph"></field>
|
||||
</record>
|
||||
|
||||
<!-- Weekly Global Activity -->
|
||||
<record id="board_weekly_mail_message_report_graph" model="ir.ui.view">
|
||||
<field name="name">board.weekly.mail.message.report.graph</field>
|
||||
<field name="model">mail.message.report</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Weekly Global Activity" type="bar">
|
||||
<field name="day"/>
|
||||
<field name="nbr" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record id="board_weekly_mail_message_report_action" model="ir.actions.act_window">
|
||||
<field name="name">Weekly Global Activity</field>
|
||||
<field name="res_model">mail.message.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,tree</field>
|
||||
<field name="domain">[('create_date','>',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="context">{'group_by':['day'],'group_by_no_leaf':1}</field>
|
||||
<field name="view_id" ref="board_weekly_mail_message_report_graph"></field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,83 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009-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 osv import osv, fields
|
||||
from tools.translate import _
|
||||
|
||||
class res_users(osv.osv):
|
||||
""" Update of res.users class
|
||||
- add a preference about sending emails about notificatoins
|
||||
- make a new user follow itself
|
||||
"""
|
||||
_name = 'res.users'
|
||||
_inherit = ['res.users', 'mail.thread']
|
||||
|
||||
_columns = {
|
||||
'notification_email_pref': fields.selection([
|
||||
('all', 'All feeds'),
|
||||
('comments', 'Only comments'),
|
||||
('to_me', 'Only when sent directly to me'),
|
||||
('none', 'Never')
|
||||
], 'Receive feeds by email', required=True,
|
||||
help="Choose in which case you want to receive an email when you receive new feeds."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'notification_email_pref': 'all',
|
||||
}
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
""" Override of __init__ to add access rights on notification_email_pref
|
||||
field. Access rights are disabled by default, but allowed on
|
||||
fields defined in self.SELF_WRITEABLE_FIELDS.
|
||||
"""
|
||||
init_res = super(res_users, self).__init__(pool, cr)
|
||||
# duplicate list to avoid modifying the original reference
|
||||
self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
|
||||
self.SELF_WRITEABLE_FIELDS.append('notification_email_pref')
|
||||
return init_res
|
||||
|
||||
def create(self, cr, uid, data, context=None):
|
||||
user_id = super(res_users, self).create(cr, uid, data, context=context)
|
||||
user = self.browse(cr, uid, [user_id], context=context)[0]
|
||||
# make user follow itself
|
||||
self.message_subscribe(cr, uid, [user_id], [user_id], context=context)
|
||||
# create a welcome message to broadcast
|
||||
company_name = user.company_id.name if user.company_id else 'the company'
|
||||
message = _('%s has joined %s! You may leave him/her a message to celebrate a new arrival in the company ! You can help him/her doing its first steps on OpenERP.') % (user.name, company_name)
|
||||
self.message_broadcast(cr, uid, [user.id], 'Welcome notification', message, context=context)
|
||||
return user_id
|
||||
|
||||
def message_load_ids(self, cr, uid, ids, limit=100, offset=0, domain=[], ascent=False, root_ids=[False], context=None):
|
||||
""" Override of message_load_ids
|
||||
User discussion page :
|
||||
- messages posted on res.users, res_id = user.id
|
||||
- messages directly sent to user with @user_login
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
msg_ids = []
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
msg_ids += msg_obj.search(cr, uid, ['|', '|', ('body_text', 'like', '@%s' % (user.login)), ('body_html', 'like', '@%s' % (user.login)), '&', ('res_id', '=', user.id), ('model', '=', self._name)] + domain,
|
||||
limit=limit, offset=offset, context=context)
|
||||
if (ascent): msg_ids = self._message_add_ancestor_ids(cr, uid, ids, msg_ids, root_ids, context=context)
|
||||
return msg_ids
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Update Preferences form !-->
|
||||
<record id="view_users_form_simple_modif_mail" model="ir.ui.view">
|
||||
<field name="name">res.users.preferences.form.mail</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form_simple_modif"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="/form/group/group[@name='preferences']/field[@name='menu_tips']" position="after">
|
||||
<field name="notification_email_pref" readonly="0"/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Update user form !-->
|
||||
<record id="view_users_form_mail" model="ir.ui.view">
|
||||
<field name="name">res.users.form.mail</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="/form/notebook/page[@string='User']/group/group/group[@name='preferences']/field[@name='menu_tips']" position="after">
|
||||
<field name="notification_email_pref"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/notebook" position="after">
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,3 +1,7 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_mail_message,mail.message,model_mail_message,,1,1,1,0
|
||||
access_mail_thread,mail.thread,model_mail_thread,,1,1,1,0
|
||||
access_mail_message,mail.message,model_mail_message,base.group_user,1,1,1,1
|
||||
access_mail_thread,mail.thread,model_mail_thread,base.group_user,1,1,1,0
|
||||
access_mail_subscription,mail.subscription,model_mail_subscription,base.group_user,1,1,1,1
|
||||
access_mail_notification,mail.notification,model_mail_notification,base.group_user,1,1,1,1
|
||||
access_mail_group,mail.group,model_mail_group,base.group_user,1,1,1,1
|
||||
access_mail_message_report,mail.message.report,model_mail_message_report,base.group_user,1,0,0,0
|
||||
|
|
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- CATEGORY -->
|
||||
<record model="ir.module.category" id="module_category_social">
|
||||
<field name="name">Social and Sharing Tools</field>
|
||||
<field name="parent_id" ref="base.module_category_tools"/>
|
||||
<field name="sequence">26</field>
|
||||
</record>
|
||||
|
||||
<!-- GROUPS -->
|
||||
<record id="group_mail_manager" model="res.groups">
|
||||
<field name="name">Mail manager</field>
|
||||
<field name="comment"></field>
|
||||
<field name="category_id" ref="module_category_social"/>
|
||||
</record>
|
||||
|
||||
<!-- RULES -->
|
||||
<record id="group_rule_public_and_joined" model="ir.rule">
|
||||
<field name="name">Mail.group: access only public and joined groups</field>
|
||||
<field name="model_id" ref="model_mail_group"/>
|
||||
<field name="domain_force">['|', ('public', '=', True), ('member_ids', 'in', user.id)]</field>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record id="group_rule_delete_mygroup" model="ir.rule">
|
||||
<field name="name">Mail.group: delete my groups only</field>
|
||||
<field name="model_id" ref="model_mail_group"/>
|
||||
<field name="domain_force">[('responsible_id', '=', user.id)]</field>
|
||||
<field name="perm_read" eval="False"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
</record>
|
||||
<record id="group_rule_all" model="ir.rule">
|
||||
<field name="name">Mail.group: all groups</field>
|
||||
<field name="model_id" ref="model_mail_group"/>
|
||||
<field name="domain_force">[(1,'=',1)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_mail_manager'))]"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,259 @@
|
|||
/* ------------------------------ */
|
||||
/* Wall */
|
||||
/* ------------------------------ */
|
||||
|
||||
div.oe_mail_wall {
|
||||
overflow: auto;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.oe_mail_wall_search {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
/* 2 columns view */
|
||||
div.oe_mail_wall_left {
|
||||
float: left;
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
div.oe_mail_wall_right {
|
||||
float: right;
|
||||
width: 34%;
|
||||
}
|
||||
|
||||
.oe_mail_wall_thread div.oe_mail_thread_act .oe_mail_action_textarea, div.oe_mail_thread_subthread .oe_mail_action_textarea {
|
||||
height: 20px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.oe_mail_thread_subthread div.oe_mail_thread_act .oe_mail_msg_image, .oe_mail_thread_subthread div.oe_mail_thread_display .oe_mail_msg_image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.oe_mail_thread_subthread .oe_mail_msg_content, .oe_mail_thread_subthread .oe_mail_msg_content {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
div.oe_mail_wall_more {
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* RecordThread */
|
||||
/* ------------------------------ */
|
||||
|
||||
.oe_mail_recthread {
|
||||
overflow: auto;
|
||||
padding: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
/* Left-side CSS */
|
||||
.oe_mail_recthread_actions {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.oe_mail_recthread_followers {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.oe_mail_followers_action, .oe_mail_followers_display {
|
||||
}
|
||||
|
||||
/* RecordThread: 2 columns view */
|
||||
.oe_mail_recthread_left {
|
||||
float: left;
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
.oe_mail_recthread_right {
|
||||
float: right;
|
||||
width: 25%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.oe_mail_button_follow, .oe_mail_button_unfollow {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.oe_mail_button_followers {
|
||||
display: inline;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.oe_mail_followers h4 {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* ThreadDisplay */
|
||||
/* ------------------------------ */
|
||||
|
||||
div.oe_mail_thread_act {
|
||||
white-space: normal;
|
||||
margin-bottom: 5px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
div.oe_mail_thread_display {
|
||||
white-space: normal;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
div.oe_mail_thread_subthread {
|
||||
margin-top: 8px;
|
||||
padding-left: 5%;
|
||||
}
|
||||
|
||||
div.oe_mail_thread_more {
|
||||
display: none;
|
||||
border-bottom: 1px solid #D2D9E7;
|
||||
}
|
||||
|
||||
li.oe_mail_thread_msg {
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.notification, .email {
|
||||
background: #E0E0E0;
|
||||
padding: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-ms-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.comment {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.notification:after, .email:after, .comment:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
li.oe_mail_thread_msg:after, div.oe_mail_thread_act:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.oe_mail_msg_content {
|
||||
margin-left: 60px;
|
||||
}
|
||||
|
||||
.oe_mail_msg_content:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.oe_mail_action_textarea {
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.oe_mail_msg_image {
|
||||
margin-right: 8px;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-ms-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
-o-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
clip: rect(5px, 40px, 45px, 0px);
|
||||
}
|
||||
|
||||
p.oe_mail_msg_p_email_header {
|
||||
border-bottom: 1px solid #D2D9E7;
|
||||
}
|
||||
|
||||
.oe_mail_msg_body a.reduce, .oe_mail_msg_body_short a.expand {
|
||||
color: #4E43E7;
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* Styling (should be openerp) */
|
||||
/* ------------------------------ */
|
||||
|
||||
ul.oe_mail {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li.oe_mail {
|
||||
list-style-type: none;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
input.oe_mail, textarea.oe_mail {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #cccccc;
|
||||
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-ms-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
input.oe_mail:focus, textarea.oe_mail:focus {
|
||||
outline: 0;
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
}
|
||||
|
||||
p.oe_mail_msg {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.oe_mail_oe_right {
|
||||
float: right;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.oe_mail_oe_left {
|
||||
float: left;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.oe_mail_oe_fade {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.oe_mail_oe_bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.oe_mail_oe_intlink {
|
||||
color: #8786b7;
|
||||
}
|
||||
|
||||
.oe_mail_oe_warning, .oe_mail_oe_warning a {
|
||||
color: #C03000;
|
||||
}
|
||||
|
||||
.oe_mail_oe_space {
|
||||
margin-left: 15px;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
.oe_group_vignette {
|
||||
padding: 8px 0;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.oe_group_image, .oe_group_details {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.oe_group_image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
-o-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.oe_group_photo {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
clip: rect(0px, 100px, 100px, 0px);
|
||||
}
|
||||
|
||||
.oe_group_photo_wide {
|
||||
height: 100px;
|
||||
width: auto;
|
||||
clip: rect(0px, 115px, 100px, 15px);
|
||||
}
|
||||
|
||||
.oe_group_details {
|
||||
width: 220px;
|
||||
font-size: 13px;
|
||||
padding: 2px 5px;
|
||||
color: #4c4c4c;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.oe_group_details a, .oe_group_details a:hover {
|
||||
font-weight: bold;
|
||||
color: #4c4c4c;
|
||||
}
|
||||
|
||||
.oe_group_details h4 {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.oe_group_details h4 a {
|
||||
color: #4c4c4c;
|
||||
}
|
||||
|
||||
.oe_group_details h4 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.oe_group_details ul {
|
||||
margin: 3px 0 5px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.oe_group_details li {
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.oe_group_description {
|
||||
}
|
||||
|
||||
.oe_kanban_record div.true {
|
||||
}
|
After Width: | Height: | Size: 1017 B |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,779 @@
|
|||
openerp.mail = function(session) {
|
||||
var _t = session.web._t,
|
||||
_lt = session.web._lt;
|
||||
|
||||
var mail = session.mail = {};
|
||||
|
||||
/**
|
||||
* Add records to sorted_comments array
|
||||
* @param {Array} records records from mail.message sorted by date desc
|
||||
* @returns {Object} cs comments_structure: dict
|
||||
* cs.model_to_root_ids = {model: [root_ids], }
|
||||
* cs.new_root_ids = [new_root_ids]
|
||||
* cs.root_ids = [root_ids]
|
||||
* cs.msgs = {record.id: record,}
|
||||
* cs.tree_struct = {record.id: {
|
||||
* 'level': record_level in hierarchy, 0 is root,
|
||||
* 'msg_nbr': number of childs,
|
||||
* 'direct_childs': [msg_ids],
|
||||
* 'all_childs': [msg_ids],
|
||||
* 'for_thread_msgs': [records],
|
||||
* 'ancestors': [msg_ids], } }
|
||||
*/
|
||||
function tools_sort_comments(cs, records, parent_id) {
|
||||
var cur_iter = 0; var max_iter = 10; var modif = true;
|
||||
while ( modif && (cur_iter++) < max_iter) {
|
||||
modif = false;
|
||||
_(records).each(function (record) {
|
||||
// root and not yet recorded
|
||||
if ( (record.parent_id == false || record.parent_id[0] == parent_id) && ! cs['msgs'][record.id]) {
|
||||
// add to model -> root_list ids
|
||||
if (! cs['model_to_root_ids'][record.model]) cs['model_to_root_ids'][record.model] = [record.id];
|
||||
else cs['model_to_root_ids'][record.model].push(record.id);
|
||||
// add root data
|
||||
cs['new_root_ids'].push(record.id);
|
||||
// add record
|
||||
cs['tree_struct'][record.id] = {'level': 0, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [record], 'msg_nbr': -1, 'ancestors': []};
|
||||
cs['msgs'][record.id] = record;
|
||||
modif = true;
|
||||
}
|
||||
// not yet recorded, but parent is recorded
|
||||
else if (! cs['msgs'][record.id] && cs['msgs'][record.parent_id[0]]) {
|
||||
var parent_level = cs['tree_struct'][record.parent_id[0]]['level'];
|
||||
// update parent structure
|
||||
cs['tree_struct'][record.parent_id[0]]['direct_childs'].push(record.id);
|
||||
cs['tree_struct'][record.parent_id[0]]['for_thread_msgs'].push(record);
|
||||
// update ancestors structure
|
||||
for (ancestor_id in cs['tree_struct'][record.parent_id[0]]['ancestors']) {
|
||||
cs['tree_struct'][ancestor_id]['all_childs'].push(record.id);
|
||||
}
|
||||
// add record
|
||||
cs['tree_struct'][record.id] = {'level': parent_level+1, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [], 'msg_nbr': -1, 'ancestors': []};
|
||||
cs['msgs'][record.id] = record;
|
||||
modif = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
/* Add ThreadDisplay widget to registry */
|
||||
session.web.form.widgets.add(
|
||||
'Thread', 'openerp.mail.Thread');
|
||||
session.web.page.readonly.add(
|
||||
'Thread', 'openerp.mail.Thread');
|
||||
|
||||
/**
|
||||
* ThreadDisplay widget: this widget handles the display of a thread of
|
||||
* messages. The [thread_level] parameter sets the thread level number:
|
||||
* - root message
|
||||
* - - sub message (parent_id = root message)
|
||||
* - - - sub sub message (parent id = sub message)
|
||||
* - - sub message (parent_id = root message)
|
||||
* This widget has 2 ways of initialization, either you give records to be rendered,
|
||||
* either it will fetch [limit] messages related to [res_model]:[res_id].
|
||||
*/
|
||||
mail.Thread = session.web.Widget.extend({
|
||||
template: 'Thread',
|
||||
|
||||
/**
|
||||
* @param {Object} parent parent
|
||||
* @param {Object} [params]
|
||||
* @param {String} [params.res_model] res_model of mail.thread object
|
||||
* @param {Number} [params.res_id] res_id of record
|
||||
* @param {Number} [params.parent_id=false] parent_id of message
|
||||
* @param {Number} [params.uid] user id
|
||||
* @param {Number} [params.thread_level=0] number of levels in the thread (only 0 or 1 currently)
|
||||
* @param {Number} [params.msg_more_limit=100] number of character to display before having a "show more" link;
|
||||
* note that the text will not be truncated if it does not have 110% of
|
||||
* the parameter (ex: 110 characters needed to be truncated and be displayed
|
||||
* as a 100-characters message)
|
||||
* @param {Number} [params.limit=10] maximum number of messages to fetch
|
||||
* @param {Number} [params.offset=0] offset for fetching messages
|
||||
* @param {Number} [params.records=null] records to show instead of fetching messages
|
||||
*/
|
||||
init: function(parent, params) {
|
||||
this._super(parent);
|
||||
this.params = params;
|
||||
this.params.parent_id = this.params.parent_id || false;
|
||||
this.params.thread_level = this.params.thread_level || 0;
|
||||
this.params.msg_more_limit = this.params.msg_more_limit || 100;
|
||||
this.params.limit = this.params.limit || 100;
|
||||
this.params.offset = this.params.offset || 0;
|
||||
this.params.records = this.params.records || null;
|
||||
// datasets and internal vars
|
||||
this.ds = new session.web.DataSet(this, this.params.res_model);
|
||||
this.ds_users = new session.web.DataSet(this, 'res.users');
|
||||
this.ds_msg = new session.web.DataSet(this, 'mail.message');
|
||||
this.sorted_comments = {'root_ids': [], 'root_id_msg_list': {}};
|
||||
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
|
||||
// display customization vars
|
||||
this.display = {};
|
||||
this.display.show_post_comment = this.params.show_post_comment || false;
|
||||
this.display.show_reply = (this.params.thread_level > 0);
|
||||
this.display.show_delete = true;
|
||||
this.display.show_hide = this.params.show_hide || false;
|
||||
this.display.show_more = (this.params.thread_level == 0);
|
||||
// not used currently
|
||||
this.intlinks_mapping = {};
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
// customize display
|
||||
if (! this.display.show_post_comment) this.$element.find('div.oe_mail_thread_act').hide();
|
||||
// add events
|
||||
this.add_events();
|
||||
/* display user, fetch comments */
|
||||
this.display_current_user();
|
||||
if (this.params.records) var display_done = this.display_comments_from_parameters(this.params.records);
|
||||
else var display_done = this.init_comments();
|
||||
return display_done
|
||||
},
|
||||
|
||||
add_events: function() {
|
||||
var self = this;
|
||||
// event: click on 'more' at bottom of thread
|
||||
this.$element.find('button.oe_mail_button_more').click(function () {
|
||||
self.do_more();
|
||||
});
|
||||
// event: writing in textarea
|
||||
this.$element.find('textarea.oe_mail_action_textarea').keyup(function (event) {
|
||||
var charCode = (event.which) ? event.which : window.event.keyCode;
|
||||
if (event.shiftKey && charCode == 13) { this.value = this.value+"\n"; }
|
||||
else if (charCode == 13) { return self.do_comment(); }
|
||||
});
|
||||
// event: click on 'reply' in msg
|
||||
this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_reply', 'click', function (event) {
|
||||
var act_dom = $(this).parents('div.oe_mail_thread_display').find('div.oe_mail_thread_act:first');
|
||||
act_dom.toggle();
|
||||
event.preventDefault();
|
||||
});
|
||||
// event: click on 'delete' in msg
|
||||
this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_delete', 'click', function (event) {
|
||||
//console.log('deleting');
|
||||
if (! confirm(_t("Do you really want to delete this message?"))) { return false; }
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
var call_defer = self.ds_msg.unlink([parseInt(msg_id)]);
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).hide();
|
||||
if (self.params.thread_level > 0) {
|
||||
$(event.srcElement).parents('ul.oe_mail_thread').eq(0).hide();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// event: click on 'hide' in msg
|
||||
this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_hide', 'click', function (event) {
|
||||
//console.log('hiding');
|
||||
if (! confirm(_t("Do you really want to hide this thread ?"))) { return false; }
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
//console.log(msg_id);
|
||||
var call_defer = self.ds.call('message_remove_pushed_notifications', [[self.params.res_id], [parseInt(msg_id)], true]);
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).hide();
|
||||
if (self.params.thread_level > 0) {
|
||||
$(event.srcElement).parents('ul.oe_mail_thread').eq(0).hide();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// event: click on an internal link
|
||||
this.$element.find('div.oe_mail_thread_display').delegate('a.intlink', 'click', function (event) {
|
||||
// lazy implementation: fetch data and try to redirect
|
||||
if (! event.srcElement.dataset.resModel) return false;
|
||||
else var res_model = event.srcElement.dataset.resModel;
|
||||
var res_login = event.srcElement.dataset.resLogin;
|
||||
var res_id = event.srcElement.dataset.resId;
|
||||
if ((! res_login) && (! res_id)) return false;
|
||||
if (! res_id) {
|
||||
var ds = new session.web.DataSet(self, res_model);
|
||||
var defer = ds.call('search', [[['login', '=', res_login]]]).then(function (records) {
|
||||
if (records[0]) {
|
||||
self.do_action({ type: 'ir.actions.act_window', res_model: res_model, res_id: parseInt(records[0]), views: [[false, 'form']]});
|
||||
}
|
||||
else return false;
|
||||
});
|
||||
}
|
||||
else self.do_action({ type: 'ir.actions.act_window', res_model: res_model, res_id: parseInt(res_id), views: [[false, 'form']]});
|
||||
});
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
init_comments: function() {
|
||||
var self = this;
|
||||
this.params.offset = 0;
|
||||
this.sorted_comments = {'root_ids': [], 'root_id_msg_list': {}};
|
||||
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
|
||||
this.$element.find('div.oe_mail_thread_display').empty();
|
||||
domain = this.get_fetch_domain(this.sorted_comments);
|
||||
return this.fetch_comments(this.params.limit, this.params.offset, domain).then();
|
||||
},
|
||||
|
||||
fetch_comments: function (limit, offset, domain) {
|
||||
var self = this;
|
||||
var defer = this.ds.call('message_load', [[this.params.res_id], ( (limit+1)||(this.params.limit+1) ), (offset||this.params.offset), (domain||[]), (this.params.thread_level > 0), (this.sorted_comments['root_ids'])]);
|
||||
$.when(defer).then(function (records) {
|
||||
if (records.length <= self.params.limit) self.display.show_more = false;
|
||||
else { self.display.show_more = true; records.pop(); }
|
||||
self.display_comments(records);
|
||||
if (self.display.show_more == true) self.$element.find('div.oe_mail_thread_more:last').show();
|
||||
else self.$element.find('div.oe_mail_thread_more:last').hide();
|
||||
});
|
||||
return defer;
|
||||
},
|
||||
|
||||
display_comments_from_parameters: function (records) {
|
||||
if (records.length > 0 && records.length < (records[0].child_ids.length+1) ) this.display.show_more = true;
|
||||
else this.display.show_more = false;
|
||||
var defer = this.display_comments(records);
|
||||
if (this.display.show_more == true) $('div.oe_mail_thread_more').eq(-2).show();
|
||||
else $('div.oe_mail_thread_more').eq(-2).hide();
|
||||
return defer;
|
||||
},
|
||||
|
||||
display_comments: function (records) {
|
||||
var self = this;
|
||||
this.cs = this.sort_comments_tmp(records);
|
||||
|
||||
/* WIP: map matched regexp -> records to browse with name */
|
||||
//_(records).each(function (record) {
|
||||
//self.do_check_internal_links(record.body_text);
|
||||
//});
|
||||
|
||||
_(records).each(function (record) {
|
||||
var sub_msgs = [];
|
||||
if ((record.parent_id == false || record.parent_id[0] == self.params.parent_id) && self.params.thread_level > 0 ) {
|
||||
var sub_list = self.cs['tree_struct'][record.id]['direct_childs'];
|
||||
_(records).each(function (record) {
|
||||
//if (record.parent_id == false || record.parent_id[0] == self.params.parent_id) return;
|
||||
if (_.indexOf(sub_list, record.id) != -1) {
|
||||
sub_msgs.push(record);
|
||||
}
|
||||
});
|
||||
self.display_comment(record);
|
||||
self.thread = new mail.Thread(self, {'res_model': self.params.res_model, 'res_id': self.params.res_id, 'uid': self.params.uid,
|
||||
'records': sub_msgs, 'thread_level': (self.params.thread_level-1), 'parent_id': record.id});
|
||||
self.$element.find('li.oe_mail_thread_msg:last').append('<div class="oe_mail_thread_subthread"/>');
|
||||
self.thread.appendTo(self.$element.find('div.oe_mail_thread_subthread:last'));
|
||||
}
|
||||
else if (self.params.thread_level == 0) {
|
||||
self.display_comment(record);
|
||||
}
|
||||
});
|
||||
// update offset for "More" buttons
|
||||
if (this.params.thread_level == 0) this.params.offset += records.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display a record
|
||||
*/
|
||||
display_comment: function (record) {
|
||||
if (record.type == 'email') { record.mini_url = ('/mail/static/src/img/email_icon.png'); }
|
||||
else { record.mini_url = this.thread_get_avatar('res.users', 'avatar', record.user_id[0]); }
|
||||
// body text manipulation
|
||||
record.body = this.do_clean_text(record.body);
|
||||
record.tr_body = this.do_truncate_string(record.body, this.params.msg_more_limit);
|
||||
record.body = this.do_replace_internal_links(record.body);
|
||||
if (record.tr_body) record.tr_body = this.do_replace_internal_links(record.tr_body);
|
||||
// render
|
||||
$(session.web.qweb.render('ThreadMsg', {'record': record, 'thread': this, 'params': this.params, 'display': this.display})
|
||||
).appendTo(this.$element.children('div.oe_mail_thread_display:first'));
|
||||
// truncated: hide full-text, show summary, add buttons
|
||||
if (record.tr_body) {
|
||||
var node_body = this.$element.find('span.oe_mail_msg_body:last').append(' <a href="#" class="reduce">[ ... Show less]</a>');
|
||||
var node_body_short = this.$element.find('span.oe_mail_msg_body_short:last').append(' <a href="#" class="expand">[ ... Show more]</a>');
|
||||
node_body.hide();
|
||||
node_body.find('a:last').click(function() { node_body.hide(); node_body_short.show(); return false; });
|
||||
node_body_short.find('a:last').click(function() { node_body_short.hide(); node_body.show(); return false; });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add records to sorted_comments array
|
||||
* @param {Array} records records from mail.message sorted by date desc
|
||||
* @returns {Object} sc sorted_comments: dict {
|
||||
* 'root_id_list': list or root_ids
|
||||
* 'root_id_msg_list': {'record_id': [ancestor_ids]}, still sorted by date desc
|
||||
* 'id_to_root': {'root_id': [records]}, still sorted by date desc
|
||||
* }
|
||||
*/
|
||||
sort_comments: function (records) {
|
||||
var self = this;
|
||||
sc = {'root_id_list': [], 'root_id_msg_list': {}, 'id_to_root': {}}
|
||||
var cur_iter = 0; var max_iter = 10; var modif = true;
|
||||
/* step1: get roots */
|
||||
while ( modif && (cur_iter++) < max_iter) {
|
||||
modif = false;
|
||||
_(records).each(function (record) {
|
||||
if ( (record.parent_id == false || record.parent_id[0] == self.params.parent_id) && (_.indexOf(sc['root_id_list'], record.id) == -1)) {
|
||||
sc['root_id_list'].push(record.id);
|
||||
sc['root_id_msg_list'][record.id] = [];
|
||||
self.sorted_comments['root_ids'].push(record.id);
|
||||
modif = true;
|
||||
}
|
||||
else {
|
||||
if (_.indexOf(sc['root_id_list'], record.parent_id[0]) != -1) {
|
||||
sc['id_to_root'][record.id] = record.parent_id[0];
|
||||
modif = true;
|
||||
}
|
||||
else if ( sc['id_to_root'][record.parent_id[0]] ) {
|
||||
sc['id_to_root'][record.id] = sc['id_to_root'][record.parent_id[0]];
|
||||
modif = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/* step2: add records */
|
||||
_(records).each(function (record) {
|
||||
var root_id = sc['id_to_root'][record.id];
|
||||
if (! root_id) return;
|
||||
sc['root_id_msg_list'][root_id].push(record);
|
||||
//self.sorted_comments['root_id_msg_list'][root_id].push(record.id);
|
||||
});
|
||||
return sc;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add records to comments_structure object: see function for details
|
||||
*/
|
||||
sort_comments_tmp: function(records) {
|
||||
return tools_sort_comments(this.comments_structure, records, this.params.parent_id);
|
||||
},
|
||||
|
||||
display_current_user: function () {
|
||||
return this.$element.find('img.oe_mail_msg_image').attr('src', this.thread_get_avatar('res.users', 'avatar', this.params.uid));
|
||||
},
|
||||
|
||||
do_comment: function () {
|
||||
var comment_node = this.$element.find('textarea');
|
||||
var body_text = comment_node.val();
|
||||
comment_node.val('');
|
||||
return this.ds.call('message_append_note', [[this.params.res_id], 'Reply', body_text, this.params.parent_id, 'comment', 'html']).then(
|
||||
this.proxy('init_comments'));
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a domain to fetch new comments according to
|
||||
* comment already present in sorted_comments
|
||||
* @param {Object} sorted_comments (see sort_comments)
|
||||
* @returns {Array} fetch_domain (OpenERP domain style)
|
||||
*/
|
||||
get_fetch_domain: function (sorted_comments) {
|
||||
var domain = [];
|
||||
var ids = sorted_comments.root_ids.slice();
|
||||
var ids2 = [];
|
||||
// must be child of current parent
|
||||
if (this.params.parent_id) { domain.push(['id', 'child_of', this.params.parent_id]); }
|
||||
_(sorted_comments.root_ids).each(function (id) { // each record
|
||||
ids.push(id);
|
||||
ids2.push(id);
|
||||
});
|
||||
if (this.params.parent_id != false) {
|
||||
ids2.push(this.params.parent_id);
|
||||
}
|
||||
// must not be children of already fetched messages
|
||||
if (ids.length > 0) {
|
||||
domain.push('&');
|
||||
domain.push('!');
|
||||
domain.push(['id', 'child_of', ids]);
|
||||
}
|
||||
if (ids2.length > 0) {
|
||||
domain.push(['id', 'not in', ids2]);
|
||||
}
|
||||
return domain;
|
||||
},
|
||||
|
||||
do_more: function () {
|
||||
domain = this.get_fetch_domain(this.sorted_comments);
|
||||
return this.fetch_comments(this.params.limit, this.params.offset, domain);
|
||||
},
|
||||
|
||||
do_replace_internal_links: function (string) {
|
||||
var self = this;
|
||||
var icon_list = ['al', 'pinky']
|
||||
/* shortcut to user: @login */
|
||||
var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
|
||||
var regex_res = regex_login.exec(string);
|
||||
while (regex_res != null) {
|
||||
var login = regex_res[2];
|
||||
string = string.replace(regex_res[0], regex_res[1] + '<a href="#" class="intlink oe_mail_oe_intlink" data-res-model="res.users" data-res-login = ' + login + '>@' + login + '</a>');
|
||||
regex_res = regex_login.exec(string);
|
||||
}
|
||||
/* special shortcut: :name, try to find an icon if in list */
|
||||
var regex_login = new RegExp(/(^|\s):((\w)*)/g);
|
||||
var regex_res = regex_login.exec(string);
|
||||
while (regex_res != null) {
|
||||
var icon_name = regex_res[2];
|
||||
if (_.include(icon_list, icon_name))
|
||||
string = string.replace(regex_res[0], regex_res[1] + '<img src="/mail/static/src/img/_' + icon_name + '.png" width="22px" height="22px" alt="' + icon_name + '"/>');
|
||||
regex_res = regex_login.exec(string);
|
||||
}
|
||||
return string;
|
||||
},
|
||||
|
||||
thread_get_avatar: function(model, field, id) {
|
||||
return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
|
||||
},
|
||||
|
||||
do_truncate_string: function(string, max_length) {
|
||||
if (string.length <= (max_length * 1.2)) return false;
|
||||
else return string.slice(0, max_length);
|
||||
},
|
||||
|
||||
do_clean_text: function (string) {
|
||||
var html = $('<div/>').text(string.replace(/\s+/g, ' ')).html().replace(new RegExp('<(/)?(b|em)\\s*>', 'gi'), '<$1$2>');
|
||||
return html;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* var regex_login = new RegExp(/(^|\s)@(\w*[a-zA-Z_.]+\w*\s)/g);
|
||||
* var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
|
||||
* var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g);
|
||||
*/
|
||||
do_check_internal_links: function(string) {
|
||||
/* shortcut to user: @login */
|
||||
var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
|
||||
var regex_res = regex_login.exec(string);
|
||||
while (regex_res != null) {
|
||||
var login = regex_res[2];
|
||||
if (! ('res.users' in this.map_hash)) { this.map_hash['res.users']['name'] = []; }
|
||||
this.map_hash['res.users']['login'].push(login);
|
||||
regex_res = regex_login.exec(string);
|
||||
}
|
||||
/* internal links: #res.model,name */
|
||||
var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g);
|
||||
regex_res = regex_intlink.exec(string);
|
||||
while (regex_res != null) {
|
||||
var res_model = regex_res[2] + '.' + regex_res[3];
|
||||
var res_name = regex_res[4];
|
||||
if (! (res_model in this.map_hash)) { this.map_hash[res_model]['name'] = []; }
|
||||
this.map_hash[res_model]['name'].push(res_name);
|
||||
regex_res = regex_intlink.exec(string);
|
||||
}
|
||||
},
|
||||
|
||||
/** checks if tue current user is the message author */
|
||||
_is_author: function (id) {
|
||||
return (this.session.uid == id);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* Add ThreadView widget to registry */
|
||||
session.web.form.widgets.add(
|
||||
'ThreadView', 'openerp.mail.RecordThread');
|
||||
session.web.page.readonly.add(
|
||||
'ThreadView', 'openerp.mail.RecordThread');
|
||||
|
||||
/* ThreadView widget: thread of comments */
|
||||
mail.RecordThread = session.web.form.Field.extend({
|
||||
// QWeb template to use when rendering the object
|
||||
form_template: 'RecordThread',
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.see_subscribers = true;
|
||||
this.thread = null;
|
||||
// datasets
|
||||
this.ds = new session.web.DataSet(this, this.view.model);
|
||||
this.ds_users = new session.web.DataSet(this, 'res.users');
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
// bind buttons
|
||||
this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); }).hide();
|
||||
this.$element.find('button.oe_mail_button_follow').click(function () { self.do_follow(); })
|
||||
.mouseover(function () { $(this).html('Follow'); }).mouseleave(function () { $(this).html('Not following'); });
|
||||
this.$element.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); })
|
||||
.mouseover(function () { $(this).html('Unfollow'); }).mouseleave(function () { $(this).html('Following'); });
|
||||
this.reinit();
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
reinit: function() {
|
||||
this.see_subscribers = true;
|
||||
this.$element.find('button.oe_mail_button_followers').html('Hide followers')
|
||||
this.$element.find('button.oe_mail_button_follow').hide();
|
||||
this.$element.find('button.oe_mail_button_unfollow').hide();
|
||||
},
|
||||
|
||||
set_value: function() {
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
this.reinit();
|
||||
if (! this.view.datarecord.id) { this.$element.find('ul.oe_mail_thread').hide(); return; }
|
||||
// fetch followers
|
||||
var fetch_sub_done = this.fetch_subscribers();
|
||||
// create and render Thread widget
|
||||
this.$element.find('div.oe_mail_recthread_left').empty();
|
||||
if (this.thread) this.thread.destroy();
|
||||
// hack: for groups and users
|
||||
if (this.view.model == 'mail.group') thread_level = 1;
|
||||
if (this.view.model == 'res.users') thread_level = 1;
|
||||
else thread_level = 0;
|
||||
this.thread = new mail.Thread(this, {'res_model': this.view.model, 'res_id': this.view.datarecord.id, 'uid': this.session.uid,
|
||||
'thread_level': thread_level, 'show_post_comment': true, 'limit': 15});
|
||||
var thread_done = this.thread.appendTo(this.$element.find('div.oe_mail_recthread_left'));
|
||||
return fetch_sub_done && thread_done;
|
||||
},
|
||||
|
||||
fetch_subscribers: function () {
|
||||
return this.ds.call('message_get_subscribers', [[this.view.datarecord.id]]).then(this.proxy('display_subscribers'));
|
||||
},
|
||||
|
||||
display_subscribers: function (records) {
|
||||
var self = this;
|
||||
this.is_subscriber = false;
|
||||
var sub_node = this.$element.find('div.oe_mail_recthread_followers')
|
||||
sub_node.empty();
|
||||
$('<h4/>').html('Followers (' + records.length + ')').appendTo(sub_node);
|
||||
_(records).each(function (record) {
|
||||
if (record.id == self.session.uid) { self.is_subscriber = true; }
|
||||
var mini_url = self.thread_get_avatar('res.users', 'avatar', record.id);
|
||||
$('<img class="oe_mail_oe_left oe_mail_msg_image" src="' + mini_url + '" title="' + record.name + '" alt="' + record.name + '"/>').appendTo(sub_node);
|
||||
});
|
||||
if (self.is_subscriber) {
|
||||
self.$element.find('button.oe_mail_button_follow').hide();
|
||||
self.$element.find('button.oe_mail_button_unfollow').show(); }
|
||||
else {
|
||||
self.$element.find('button.oe_mail_button_follow').show();
|
||||
self.$element.find('button.oe_mail_button_unfollow').hide(); }
|
||||
},
|
||||
|
||||
do_follow: function () {
|
||||
return this.ds.call('message_subscribe', [[this.view.datarecord.id]]).pipe(this.proxy('fetch_subscribers'));
|
||||
},
|
||||
|
||||
do_unfollow: function () {
|
||||
var self = this;
|
||||
return this.ds.call('message_unsubscribe', [[this.view.datarecord.id]]).then(function (record) {
|
||||
if (record == false) self.do_notify("Impossible to unsubscribe", "You are automatically subscribed to this record. You cannot unsubscribe.");
|
||||
}).pipe(this.proxy('fetch_subscribers'));
|
||||
},
|
||||
|
||||
do_toggle_followers: function () {
|
||||
this.see_subscribers = ! this.see_subscribers;
|
||||
if (this.see_subscribers) { this.$element.find('button.oe_mail_button_followers').html('Hide followers'); }
|
||||
else { this.$element.find('button.oe_mail_button_followers').html('Display followers'); }
|
||||
this.$element.find('div.oe_mail_recthread_followers').toggle();
|
||||
},
|
||||
|
||||
thread_get_avatar: function(model, field, id) {
|
||||
return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
/* Add WallView widget to registry */
|
||||
session.web.client_actions.add('mail.all_feeds', 'session.mail.WallView');
|
||||
|
||||
/* WallView widget: a wall of messages */
|
||||
mail.WallView = session.web.Widget.extend({
|
||||
template: 'Wall',
|
||||
|
||||
/**
|
||||
* @param {Object} parent parent
|
||||
* @param {Object} [params]
|
||||
* @param {Number} [params.limit=20] number of messages to show and fetch
|
||||
* @param {Number} [params.search_view_id=false] search view id for messages
|
||||
* @var {Array} sorted_comments records sorted by res_model and res_id
|
||||
* records.res_model = {res_ids}
|
||||
* records.res_model.res_id = [records]
|
||||
*/
|
||||
init: function (parent, params) {
|
||||
this._super(parent);
|
||||
this.params = {};
|
||||
this.params.limit = params.limit || 25;
|
||||
this.params.domain = params.domain || [];
|
||||
this.params.context = params.context || {};
|
||||
this.params.search_view_id = params.search_view_id || false;
|
||||
this.params.thread_level = params.thread_level || 1;
|
||||
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
|
||||
this.display_show_more = true;
|
||||
this.thread_list = [];
|
||||
this.search = {'domain': [], 'context': {}, 'groupby': {}}
|
||||
this.search_results = {'domain': [], 'context': {}, 'groupby': {}}
|
||||
// datasets
|
||||
this.ds_msg = new session.web.DataSet(this, 'mail.message');
|
||||
this.ds_thread = new session.web.DataSet(this, 'mail.thread');
|
||||
this.ds_users = new session.web.DataSet(this, 'res.users');
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
// add events
|
||||
this.add_event_handlers();
|
||||
// load mail.message search view
|
||||
var search_view_ready = this.load_search_view(this.params.search_view_id, {}, false);
|
||||
// fetch first threads
|
||||
var comments_ready = this.init_and_fetch_comments(this.params.limit, 0);
|
||||
return (search_view_ready && comments_ready);
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
/** Add events */
|
||||
add_event_handlers: function () {
|
||||
var self = this;
|
||||
// post a comment
|
||||
this.$element.find('button.oe_mail_wall_button_comment').click(function () { return self.do_comment(); });
|
||||
// display more threads
|
||||
this.$element.find('button.oe_mail_wall_button_more').click(function () { return self.do_more(); });
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the mail.message search view
|
||||
* @param {Number} view_id id of the search view to load
|
||||
* @param {Object} defaults ??
|
||||
* @param {Boolean} hidden some kind of trick we do not care here
|
||||
*/
|
||||
load_search_view: function (view_id, defaults, hidden) {
|
||||
var self = this;
|
||||
this.searchview = new session.web.SearchView(this, this.ds_msg, view_id || false, defaults || {}, hidden || false);
|
||||
var search_view_loaded = this.searchview.appendTo(this.$element.find('div.oe_mail_wall_search'));
|
||||
return $.when(search_view_loaded).then(function () {
|
||||
self.searchview.on_search.add(self.do_searchview_search);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Aggregate the domains, contexts and groupbys in parameter
|
||||
* with those from search form, and then calls fetch_comments
|
||||
* to actually fetch comments
|
||||
* @param {Array} domains
|
||||
* @param {Array} contexts
|
||||
* @param {Array} groupbys
|
||||
*/
|
||||
do_searchview_search: function(domains, contexts, groupbys) {
|
||||
var self = this;
|
||||
this.rpc('/web/session/eval_domain_and_context', {
|
||||
domains: domains || [],
|
||||
contexts: contexts || [],
|
||||
group_by_seq: groupbys || []
|
||||
}, function (results) {
|
||||
self.search_results['context'] = results.context;
|
||||
self.search_results['domain'] = results.domain;
|
||||
self.search_results['groupby'] = results.group_by;
|
||||
return self.init_and_fetch_comments();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the wall and calls fetch_comments
|
||||
* @param {Number} limit: number of notifications to fetch
|
||||
* @param {Number} offset: offset in notifications search
|
||||
* @param {Array} domain
|
||||
* @param {Array} context
|
||||
*/
|
||||
init_and_fetch_comments: function() {
|
||||
this.search['domain'] = _.union(this.params.domain, this.search_results.domain);
|
||||
this.search['context'] = _.extend(this.params.context, this.search_results.context);
|
||||
this.display_show_more = true;
|
||||
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
|
||||
this.$element.find('div.oe_mail_wall_threads').empty();
|
||||
return this.fetch_comments(this.params.limit, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches wall messages
|
||||
* @param {Number} limit: number of notifications to fetch
|
||||
* @param {Number} offset: offset in notifications search
|
||||
* @param {Array} domain
|
||||
* @param {Array} context
|
||||
*/
|
||||
fetch_comments: function (limit, offset, additional_domain, additional_context) {
|
||||
var self = this;
|
||||
if (additional_domain) var fetch_domain = this.search['domain'].concat(additional_domain);
|
||||
else var fetch_domain = this.search['domain'];
|
||||
if (additional_context) var fetch_context = _.extend(this.search['context'], additional_context);
|
||||
else var fetch_context = this.search['context'];
|
||||
return this.ds_thread.call('get_pushed_messages',
|
||||
[[this.session.uid], (limit || 0), (offset || 0), fetch_domain, true, [], fetch_context]).then(this.proxy('display_comments'));
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Array} records records to show in threads
|
||||
*/
|
||||
display_comments: function (records) {
|
||||
var self = this;
|
||||
this.do_update_show_more(records.length >= self.params.limit);
|
||||
this.sort_comments(records);
|
||||
_(this.comments_structure['new_root_ids']).each(function (root_id) {
|
||||
var records = self.comments_structure.tree_struct[root_id]['for_thread_msgs'];
|
||||
var model_name = self.comments_structure.msgs[root_id]['model'];
|
||||
var res_id = self.comments_structure.msgs[root_id]['res_id'];
|
||||
var render_res = session.web.qweb.render('WallThreadContainer', {});
|
||||
$('<div class="oe_mail_wall_thread">').html(render_res).appendTo(self.$element.find('div.oe_mail_wall_threads'));
|
||||
var thread = new mail.Thread(self, {
|
||||
'res_model': model_name, 'res_id': res_id, 'uid': self.session.uid, 'records': records,
|
||||
'parent_id': false, 'thread_level': self.params.thread_level, 'show_hide': true}
|
||||
);
|
||||
self.thread_list.push(thread);
|
||||
return thread.appendTo(self.$element.find('div.oe_mail_wall_thread:last'));
|
||||
});
|
||||
// update TODO
|
||||
this.comments_structure['root_ids'] = _.union(this.comments_structure['root_ids'], this.comments_structure['new_root_ids']);
|
||||
this.comments_structure['new_root_ids'] = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Add records to comments_structure object: see function for details
|
||||
*/
|
||||
sort_comments: function(records) {
|
||||
tools_sort_comments(this.comments_structure, records, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a domain to fetch new comments according to
|
||||
* comments already present in sorted_comments
|
||||
* - for each model:
|
||||
* -- should not be child of already displayed ids
|
||||
* @param {Object} sorted_comments (see sort_comments)
|
||||
* @returns {Array} fetch_domain (OpenERP domain style)
|
||||
*/
|
||||
get_fetch_domain: function () {
|
||||
var self = this;
|
||||
var model_to_root = {};
|
||||
var fetch_domain = [];
|
||||
_(this.comments_structure['model_to_root_ids']).each(function (sc_model, model_name) {
|
||||
fetch_domain.push('|', ['model', '!=', model_name], '!', ['id', 'child_of', sc_model]);
|
||||
});
|
||||
return fetch_domain;
|
||||
},
|
||||
|
||||
/** Display update: show more button */
|
||||
do_update_show_more: function (new_value) {
|
||||
if (new_value != undefined) this.display_show_more = new_value;
|
||||
if (this.display_show_more) this.$element.find('div.oe_mail_wall_more:last').show();
|
||||
else this.$element.find('div.oe_mail_wall_more:last').hide();
|
||||
},
|
||||
|
||||
/** Action: Shows more discussions */
|
||||
do_more: function () {
|
||||
var domain = this.get_fetch_domain();
|
||||
return this.fetch_comments(this.params.limit, 0, domain);
|
||||
},
|
||||
|
||||
/** Action: Posts a comment */
|
||||
do_comment: function () {
|
||||
var comment_node = this.$element.find('textarea.oe_mail_wall_action_textarea');
|
||||
var body_text = comment_node.val();
|
||||
comment_node.val('');
|
||||
var call_done = this.ds_users.call('message_append_note', [[this.session.uid], 'Tweet', body_text, false, 'comment', 'html']).then(this.proxy('init_and_fetch_comments'));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<template>
|
||||
|
||||
<div t-name="Wall" class="oe_mail_wall">
|
||||
<div class="oe_mail_wall_search">
|
||||
</div>
|
||||
<div class="oe_mail_wall_left">
|
||||
<div class="oe_mail_wall_act">
|
||||
<textarea class="oe_mail oe_mail_wall_action_textarea" placeholder="Add a personnal message here..."/><br />
|
||||
<button class="oe_mail_wall_button_comment" type="button">Post comment</button>
|
||||
</div>
|
||||
<div class="oe_mail_wall_threads">
|
||||
</div>
|
||||
<div class="oe_mail_wall_more">
|
||||
<button class="oe_mail_wall_button_more" type="button">See more discussions</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_mail_wall_right"></div>
|
||||
</div>
|
||||
|
||||
<t t-name="WallThreadContainer">
|
||||
</t>
|
||||
|
||||
<div t-name="RecordThread" class="oe_mail_recthread">
|
||||
<h4>History and Comments</h4>
|
||||
<div class="oe_mail_recthread_left">
|
||||
</div>
|
||||
<div class="oe_mail_recthread_right">
|
||||
<div class="oe_mail_recthread_actions">
|
||||
<button type="button" class="oe_mail_button_follow">Not following</button>
|
||||
<button type="button" class="oe_mail_button_unfollow">Following</button>
|
||||
<button type="button" class="oe_mail_button_followers">Display followers</button>
|
||||
</div>
|
||||
<div class="oe_mail_recthread_followers">
|
||||
<h4>Followers</h4>
|
||||
<div class="oe_mail_followers_display">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul t-name="Thread" class="oe_mail_thread oe_mail">
|
||||
<div class="oe_mail_thread_act">
|
||||
<img class="oe_mail_msg_image oe_mail_oe_left" alt="User img"/>
|
||||
<div class="oe_mail_msg_content">
|
||||
<textarea class="oe_mail_action_textarea oe_mail" placeholder="Add your comment here..." onfocus="this.value = '';"/><br />
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_mail_thread_display"></div>
|
||||
<div class="oe_mail_thread_more">
|
||||
<button class="oe_mail_button_more" type="button">Load more messages</button>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<li t-name="ThreadMsg" t-attf-class="oe_mail_thread_msg oe_mail">
|
||||
<div t-attf-class="{record.type}">
|
||||
<img class="oe_mail_msg_image oe_mail_oe_left" t-att-src="record.mini_url"/>
|
||||
<div class="oe_mail_msg_content">
|
||||
<t t-if="record.type == 'email'"><t t-call="EmailDisplay" /></t>
|
||||
<t t-if="record.type == 'notification' || record.type == 'comment'"><t t-call="NoteDisplay" /></t>
|
||||
</div>
|
||||
<t t-if="record.type == 'tmp'"><t t-call="ThreadDisplay" /></t>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<t t-name="NoteDisplay">
|
||||
<p class="oe_mail_msg">
|
||||
<a href="#" class="intlink oe_mail_oe_intlink" t-attf-data-res-model='{params.res_model}' t-attf-data-res-id='{params.res_id}'><t t-raw="record.record_name"/></a>
|
||||
<span class="oe_mail_msg_body"><t t-raw="record.body"/></span>
|
||||
<t t-if="record.tr_body"><span class="oe_mail_msg_body_short"><t t-raw="record.tr_body"/></span></t>
|
||||
<br />
|
||||
<span class="oe_mail_oe_fade">
|
||||
<a href="#" class="intlink oe_mail_oe_intlink" data-res-model='res.users' t-attf-data-res-id='{record.user_id[0]}'><t t-raw="record.user_id[1]"/></a>
|
||||
on <t t-raw="record.date"/>
|
||||
</span>
|
||||
<t t-if="display['show_reply']"><span class="oe_mail_oe_space"><a href="#" class="oe_mail_msg_reply oe_mail_oe_intlink">Reply</a></span></t>
|
||||
<t t-if="display['show_delete']">
|
||||
<t t-if="thread._is_author(record.user_id[0])"><span class="oe_mail_oe_space"><a href="#" t-attf-data-id='{record.id}' class="oe_mail_msg_delete oe_mail_oe_intlink">Delete</a></span></t>
|
||||
</t>
|
||||
<t t-if="display['show_hide']">
|
||||
<t t-if="!(thread._is_author(record.user_id[0]))"><span class="oe_mail_oe_space"><a href="#" t-attf-data-id='{record.id}' class="oe_mail_msg_hide oe_mail_oe_intlink">Hide</a></span></t>
|
||||
</t>
|
||||
</p>
|
||||
</t>
|
||||
|
||||
<t t-name="EmailDisplay">
|
||||
<p class="oe_mail_msg oe_mail_msg_p_email_header">
|
||||
<span class="oe_mail_oe_bold">From:</span> <t t-esc="record.email_from"/> on <span class="oe_mail_oe_fade"><t t-raw="record.date"/></span><br />
|
||||
<span class="oe_mail_oe_bold">To:</span> <t t-esc="record.email_to"/><br />
|
||||
<span class="oe_mail_oe_bold">Subject:</span> <t t-esc="record.subject"/><br />
|
||||
</p>
|
||||
<p class="oe_mail_msg">
|
||||
<span class="oe_mail_msg_body"><t t-raw="record.body"/></span>
|
||||
<t t-if="record.tr_body"><span class="oe_mail_msg_body_short"><t t-raw="record.tr_body"/></span></t>
|
||||
</p>
|
||||
</t>
|
||||
|
||||
</template>
|
|
@ -200,13 +200,8 @@ class mail_compose_message(osv.osv_memory):
|
|||
|
||||
body = mail.body_html if mail.subtype == 'html' else mail.body_text
|
||||
|
||||
# Reply Email
|
||||
if context.get('mail.compose.message.mode') == 'reply' and mail.message_id:
|
||||
references = (mail.references or '') + " " + mail.message_id
|
||||
headers['In-Reply-To'] = mail.message_id
|
||||
|
||||
# Get model, and check whether it is OpenChatter enabled, aka inherit from mail.thread
|
||||
if context.get('mail.compose.message.mode') == 'mass_mail':
|
||||
# Mass mailing: must render the template patterns
|
||||
if context.get('active_ids') and context.get('active_model'):
|
||||
active_ids = context['active_ids']
|
||||
active_model = context['active_model']
|
||||
|
@ -214,7 +209,22 @@ class mail_compose_message(osv.osv_memory):
|
|||
active_model = mail.model
|
||||
active_model_pool = self.pool.get(active_model)
|
||||
active_ids = active_model_pool.search(cr, uid, ast.literal_eval(mail.filter_id.domain), context=ast.literal_eval(mail.filter_id.context))
|
||||
else:
|
||||
active_model = mail.model
|
||||
active_ids = [int(mail.res_id)]
|
||||
active_model_pool = self.pool.get(active_model)
|
||||
if hasattr(active_model_pool, '_inherit') and 'mail.thread' in active_model_pool._inherit:
|
||||
mail_thread_enabled = True
|
||||
else:
|
||||
mail_thread_enabled = False
|
||||
|
||||
# Reply Email
|
||||
if context.get('mail.compose.message.mode') == 'reply' and mail.message_id:
|
||||
references = (mail.references or '') + " " + mail.message_id
|
||||
headers['In-Reply-To'] = mail.message_id
|
||||
|
||||
if context.get('mail.compose.message.mode') == 'mass_mail':
|
||||
# Mass mailing: must render the template patterns
|
||||
for active_id in active_ids:
|
||||
subject = self.render_template(cr, uid, mail.subject, active_model, active_id)
|
||||
rendered_body = self.render_template(cr, uid, body, active_model, active_id)
|
||||
|
@ -223,21 +233,33 @@ class mail_compose_message(osv.osv_memory):
|
|||
email_cc = self.render_template(cr, uid, mail.email_cc, active_model, active_id)
|
||||
email_bcc = self.render_template(cr, uid, mail.email_bcc, active_model, active_id)
|
||||
reply_to = self.render_template(cr, uid, mail.reply_to, active_model, active_id)
|
||||
|
||||
|
||||
# in mass-mailing mode we only schedule the mail for sending, it will be
|
||||
# processed as soon as the mail scheduler runs.
|
||||
mail_message.schedule_with_attach(cr, uid, email_from, to_email(email_to), subject, rendered_body,
|
||||
model=mail.model, email_cc=to_email(email_cc), email_bcc=to_email(email_bcc), reply_to=reply_to,
|
||||
attachments=attachment, references=references, res_id=active_id,
|
||||
subtype=mail.subtype, headers=headers, context=context)
|
||||
if mail_thread_enabled:
|
||||
active_model_pool.message_append(cr, uid, [active_id],
|
||||
subject, body_text=mail.body_text, body_html=mail.body_html, subtype=mail.subtype, state='outgoing',
|
||||
email_to=email_to, email_from=email_from, email_cc=email_cc, email_bcc=email_bcc,
|
||||
reply_to=reply_to, references=references, attachments=attachment, headers=headers, context=context)
|
||||
else:
|
||||
mail_message.schedule_with_attach(cr, uid, email_from, to_email(email_to), subject, rendered_body,
|
||||
model=mail.model, email_cc=to_email(email_cc), email_bcc=to_email(email_bcc), reply_to=reply_to,
|
||||
attachments=attachment, references=references, res_id=active_id,
|
||||
subtype=mail.subtype, headers=headers, context=context)
|
||||
else:
|
||||
# normal mode - no mass-mailing
|
||||
msg_id = mail_message.schedule_with_attach(cr, uid, mail.email_from, to_email(mail.email_to), mail.subject, body,
|
||||
model=mail.model, email_cc=to_email(mail.email_cc), email_bcc=to_email(mail.email_bcc), reply_to=mail.reply_to,
|
||||
attachments=attachment, references=references, res_id=int(mail.res_id),
|
||||
subtype=mail.subtype, headers=headers, context=context)
|
||||
if mail_thread_enabled:
|
||||
msg_ids = active_model_pool.message_append(cr, uid, active_ids,
|
||||
mail.subject, body_text=mail.body_text, body_html=mail.body_html, subtype=mail.subtype, state='outgoing',
|
||||
email_to=mail.email_to, email_from=mail.email_from, email_cc=mail.email_cc, email_bcc=mail.email_bcc,
|
||||
reply_to=mail.reply_to, references=references, attachments=attachment, headers=headers, context=context)
|
||||
else:
|
||||
msg_ids = [mail_message.schedule_with_attach(cr, uid, mail.email_from, to_email(mail.email_to), mail.subject, body,
|
||||
model=mail.model, email_cc=to_email(mail.email_cc), email_bcc=to_email(mail.email_bcc), reply_to=mail.reply_to,
|
||||
attachments=attachment, references=references, res_id=int(mail.res_id),
|
||||
subtype=mail.subtype, headers=headers, context=context)]
|
||||
# in normal mode, we send the email immediately, as the user expects us to (delay should be sufficiently small)
|
||||
mail_message.send(cr, uid, [msg_id], context=context)
|
||||
mail_message.send(cr, uid, msg_ids, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-04-06 05:18+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: marketing
|
||||
#: model:res.groups,name:marketing.group_marketing_manager
|
||||
msgid "Manager"
|
||||
msgstr "Vedoucí"
|
||||
|
||||
#. module: marketing
|
||||
#: model:res.groups,name:marketing.group_marketing_user
|
||||
msgid "User"
|
||||
msgstr "Uživatel"
|
|
@ -130,6 +130,7 @@ class mrp_bom(osv.osv):
|
|||
"""
|
||||
_name = 'mrp.bom'
|
||||
_description = 'Bill of Material'
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
def _child_compute(self, cr, uid, ids, name, arg, context=None):
|
||||
""" Gets child bom.
|
||||
|
@ -358,6 +359,18 @@ class mrp_bom(osv.osv):
|
|||
default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False})
|
||||
return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(mrp_bom, self).create(cr, uid, vals, context=context)
|
||||
self.create_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
prod_obj = self.pool.get('product.product')
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
for prod in prod_obj.browse(cr, uid, [obj.product_id], context=context):
|
||||
self.message_append_note(cr, uid, [obj.id], body=_("Bill of Material has been <b>created</b> for <em>%s</em> product.") % (prod.id.name_template), context=context)
|
||||
return True
|
||||
|
||||
mrp_bom()
|
||||
|
||||
class mrp_bom_revision(osv.osv):
|
||||
|
@ -393,6 +406,7 @@ class mrp_production(osv.osv):
|
|||
_name = 'mrp.production'
|
||||
_description = 'Manufacturing Order'
|
||||
_date_name = 'date_planned'
|
||||
_inherit = ['ir.needaction_mixin', 'mail.thread']
|
||||
|
||||
def _production_calc(self, cr, uid, ids, prop, unknow_none, context=None):
|
||||
""" Calculates total hours and total no. of cycles for a production order.
|
||||
|
@ -497,6 +511,11 @@ class mrp_production(osv.osv):
|
|||
(_check_qty, 'Order quantity cannot be negative or zero!', ['product_qty']),
|
||||
]
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(mrp_production, self).create(cr, uid, vals, context=context)
|
||||
self.create_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for production in self.browse(cr, uid, ids, context=context):
|
||||
if production.state not in ('draft', 'cancel'):
|
||||
|
@ -629,9 +648,10 @@ class mrp_production(osv.osv):
|
|||
move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids])
|
||||
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
|
||||
self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
self.action_cancel_send_note(cr, uid, ids, context)
|
||||
return True
|
||||
|
||||
def action_ready(self, cr, uid, ids):
|
||||
def action_ready(self, cr, uid, ids, context=None):
|
||||
""" Changes the production state to Ready and location id of stock move.
|
||||
@return: True
|
||||
"""
|
||||
|
@ -643,18 +663,18 @@ class mrp_production(osv.osv):
|
|||
if production.move_prod_id:
|
||||
move_obj.write(cr, uid, [production.move_prod_id.id],
|
||||
{'location_id': production.location_dest_id.id})
|
||||
|
||||
message = _("Manufacturing order '%s' is ready to produce.") % ( name,)
|
||||
self.log(cr, uid, production_id, message)
|
||||
self.action_ready_send_note(cr, uid, [production_id], context)
|
||||
return True
|
||||
|
||||
def action_production_end(self, cr, uid, ids):
|
||||
def action_production_end(self, cr, uid, ids, context=None):
|
||||
""" Changes production state to Finish and writes finished date.
|
||||
@return: True
|
||||
"""
|
||||
for production in self.browse(cr, uid, ids):
|
||||
self._costs_generate(cr, uid, production)
|
||||
return self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
write_res = self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
self.action_done_send_note(cr, uid, ids, context)
|
||||
return write_res
|
||||
|
||||
def test_production_done(self, cr, uid, ids):
|
||||
""" Tests whether production is done or not.
|
||||
|
@ -698,7 +718,6 @@ class mrp_production(osv.osv):
|
|||
if (produced_product.scrapped) or (produced_product.product_id.id <> production.product_id.id):
|
||||
continue
|
||||
produced_qty += produced_product.product_qty
|
||||
|
||||
if production_mode in ['consume','consume_produce']:
|
||||
consumed_data = {}
|
||||
|
||||
|
@ -819,11 +838,12 @@ class mrp_production(osv.osv):
|
|||
} )
|
||||
return amount
|
||||
|
||||
def action_in_production(self, cr, uid, ids):
|
||||
def action_in_production(self, cr, uid, ids, context=None):
|
||||
""" Changes state to In Production and writes starting date.
|
||||
@return: True
|
||||
"""
|
||||
self.write(cr, uid, ids, {'state': 'in_production', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
self.action_in_production_send_note(cr, uid, ids, context)
|
||||
return True
|
||||
|
||||
def test_if_product(self, cr, uid, ids):
|
||||
|
@ -997,11 +1017,7 @@ class mrp_production(osv.osv):
|
|||
|
||||
wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
|
||||
production.write({'state':'confirmed'}, context=context)
|
||||
message = _("Manufacturing order '%s' is scheduled for the %s.") % (
|
||||
production.name,
|
||||
datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y'),
|
||||
)
|
||||
self.log(cr, uid, production.id, message)
|
||||
self.action_confirm_send_note(cr, uid, [production.id], context);
|
||||
return shipment_id
|
||||
|
||||
def force_production(self, cr, uid, ids, *args):
|
||||
|
@ -1012,6 +1028,55 @@ class mrp_production(osv.osv):
|
|||
pick_obj = self.pool.get('stock.picking')
|
||||
pick_obj.force_assign(cr, uid, [prod.picking_id.id for prod in self.browse(cr, uid, ids)])
|
||||
return True
|
||||
|
||||
# ---------------------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
# ---------------------------------------------------
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids, [])
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.state == 'draft' and obj.user_id:
|
||||
result[obj.id] = [obj.user_id.id]
|
||||
return result
|
||||
|
||||
def message_get_subscribers(self, cr, uid, ids, context=None):
|
||||
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.user_id:
|
||||
sub_ids.append(obj.user_id.id)
|
||||
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
self.message_append_note(cr, uid, ids, body=_("Manufacturing order has been <b>created</b>."), context=context)
|
||||
return True
|
||||
|
||||
def action_cancel_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Manufacturing order has been <b>canceled</b>.")
|
||||
self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_ready_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Manufacturing order is <b>ready to produce</b>.")
|
||||
self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_in_production_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Manufacturing order is <b>in production</b>.")
|
||||
self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_done_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Manufacturing order has been <b>done</b>.")
|
||||
self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_confirm_send_note(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
message = _("Manufacturing order has been <b>confirmed</b> and is <b>scheduled</b> for the <em>%s</em>.") % (obj.date_planned)
|
||||
self.message_append_note(cr, uid, [obj.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
|
||||
mrp_production()
|
||||
|
||||
|
@ -1019,6 +1084,7 @@ class mrp_production_workcenter_line(osv.osv):
|
|||
_name = 'mrp.production.workcenter.line'
|
||||
_description = 'Work Order'
|
||||
_order = 'sequence'
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Work Order', size=64, required=True),
|
||||
|
|
|
@ -412,6 +412,8 @@
|
|||
<field colspan="4" name="property_ids" nolabel="1" groups="base.group_extended"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -646,6 +648,7 @@
|
|||
<label string="" colspan="2"/>
|
||||
<field name="product_uos_qty" groups="product.group_uos"/>
|
||||
<field name="product_uos" groups="product.group_uos"/>
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
|
||||
<notebook colspan="4">
|
||||
|
@ -775,7 +778,6 @@
|
|||
<field colspan="4" name="product_lines" nolabel="1" widget="one2many_list"/>
|
||||
</page>
|
||||
<page string="Extra Information">
|
||||
<field name="user_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="priority" groups="base.group_extended"/>
|
||||
<newline/>
|
||||
|
@ -785,6 +787,7 @@
|
|||
<field name="move_prod_id" groups="base.group_extended"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -70,7 +70,7 @@ class change_production_qty(osv.osv_memory):
|
|||
bom_obj = self.pool.get('mrp.bom')
|
||||
for wiz_qty in self.browse(cr, uid, ids, context=context):
|
||||
prod = prod_obj.browse(cr, uid, record_id, context=context)
|
||||
prod_obj.write(cr, uid,prod.id, {'product_qty': wiz_qty.product_qty})
|
||||
prod_obj.write(cr, uid, [prod.id], {'product_qty': wiz_qty.product_qty})
|
||||
prod_obj.action_compute(cr, uid, [prod.id])
|
||||
|
||||
move_lines_obj = self.pool.get('stock.move')
|
||||
|
|
|
@ -156,22 +156,24 @@ class mrp_production_workcenter_line(osv.osv):
|
|||
prod_obj.write(cr, uid, [prod.production_id.id], {'date_start':dstart}, context=context, mini=False)
|
||||
return result
|
||||
|
||||
def action_draft(self, cr, uid, ids):
|
||||
def action_draft(self, cr, uid, ids, context=None):
|
||||
""" Sets state to draft.
|
||||
@return: True
|
||||
"""
|
||||
self.write(cr, uid, ids, {'state':'draft'})
|
||||
self.action_draft_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def action_start_working(self, cr, uid, ids):
|
||||
def action_start_working(self, cr, uid, ids, context=None):
|
||||
""" Sets state to start working and writes starting date.
|
||||
@return: True
|
||||
"""
|
||||
self.modify_production_order_state(cr, uid, ids, 'start')
|
||||
self.write(cr, uid, ids, {'state':'startworking', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
self.action_start_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def action_done(self, cr, uid, ids):
|
||||
def action_done(self, cr, uid, ids, context=None):
|
||||
""" Sets state to done, writes finish date and calculates delay.
|
||||
@return: True
|
||||
"""
|
||||
|
@ -185,28 +187,76 @@ class mrp_production_workcenter_line(osv.osv):
|
|||
delay += (date_finished-date_start).seconds / float(60*60)
|
||||
|
||||
self.write(cr, uid, ids, {'state':'done', 'date_finished': date_now,'delay':delay})
|
||||
self.action_done_send_note(cr, uid, ids, context=context)
|
||||
self.modify_production_order_state(cr,uid,ids,'done')
|
||||
return True
|
||||
|
||||
def action_cancel(self, cr, uid, ids):
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
""" Sets state to cancel.
|
||||
@return: True
|
||||
"""
|
||||
self.write(cr, uid, ids, {'state':'cancel'})
|
||||
self.action_cancel_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def action_pause(self, cr, uid, ids):
|
||||
def action_pause(self, cr, uid, ids, context=None):
|
||||
""" Sets state to pause.
|
||||
@return: True
|
||||
"""
|
||||
self.write(cr, uid, ids, {'state':'pause'})
|
||||
self.action_pending_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def action_resume(self, cr, uid, ids):
|
||||
def action_resume(self, cr, uid, ids, context=None):
|
||||
""" Sets state to startworking.
|
||||
@return: True
|
||||
"""
|
||||
self.write(cr, uid, ids, {'state':'startworking'})
|
||||
self.action_start_send_note(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
# -------------------------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
# -------------------------------------------------------
|
||||
|
||||
def action_draft_send_note(self, cr, uid, ids, context=None):
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
for workorder in self.browse(cr, uid, ids):
|
||||
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
|
||||
message = _("Work order has been <b>created</b> for production order <em>%s</em>.") % (prod.id.name)
|
||||
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_start_send_note(self, cr, uid, ids, context=None):
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
for workorder in self.browse(cr, uid, ids):
|
||||
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
|
||||
message = _("Work order has been <b>started</b> for production order <em>%s</em>.") % (prod.id.name)
|
||||
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_done_send_note(self, cr, uid, ids, context=None):
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
for workorder in self.browse(cr, uid, ids):
|
||||
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
|
||||
message = _("Work order has been <b>done</b> for production order <em>%s</em>.") % (prod.id.name)
|
||||
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_pending_send_note(self, cr, uid, ids, context=None):
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
for workorder in self.browse(cr, uid, ids):
|
||||
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
|
||||
message = _("Work order is <b>pending</b> for production order <em>%s</em>.") % (prod.id.name)
|
||||
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
def action_cancel_send_note(self, cr, uid, ids, context=None):
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
for workorder in self.browse(cr, uid, ids):
|
||||
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
|
||||
message = _("Work order has been <b>cancelled</b> for production order <em>%s</em>.") % (prod.id.name)
|
||||
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
|
||||
return True
|
||||
|
||||
mrp_production_workcenter_line()
|
||||
|
|
|
@ -118,6 +118,7 @@
|
|||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# Czech 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: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2012-04-06 06:59+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2012-04-07 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 15060)\n"
|
||||
|
||||
#. module: pad
|
||||
#: sql_constraint:res.company:0
|
||||
msgid "The company name must be unique !"
|
||||
msgstr "Jméno společnosti musí být jedinečné !"
|
||||
|
||||
#. module: pad
|
||||
#: help:res.company,pad_url_template:0
|
||||
msgid "Template used to generate pad URL."
|
||||
msgstr "Šablona použitá pro generování URL bloku"
|
||||
|
||||
#. module: pad
|
||||
#: model:ir.model,name:pad.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr "Společnosti"
|
||||
|
||||
#. module: pad
|
||||
#: constraint:res.company:0
|
||||
msgid "Error! You can not create recursive companies."
|
||||
msgstr "Chyba! Nemůžete vytvořit rekurzivní společnosti."
|
||||
|
||||
#. module: pad
|
||||
#: model:ir.model,name:pad.model_ir_attachment
|
||||
msgid "ir.attachment"
|
||||
msgstr "ir.attachment"
|
||||
|
||||
#. module: pad
|
||||
#: view:res.company:0
|
||||
msgid "Pad"
|
||||
msgstr "Blok"
|
||||
|
||||
#. module: pad
|
||||
#: field:res.company,pad_url_template:0
|
||||
msgid "Pad URL Template"
|
||||
msgstr "Šablona URL bloku"
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/pad/static/src/xml/pad.xml:9
|
||||
msgid "Add Pad"
|
||||
msgstr "Přidat blok"
|