[MERGE]: Merge with lp:openobject-addons

bzr revid: mma@tinyerp.com-20121018052756-65fv51x0qrmz7zj6
bzr revid: mma@tinyerp.com-20121019050930-mcht3lslqjk38q22
This commit is contained in:
Mayur Maheshwari (OpenERP) 2012-10-19 10:39:30 +05:30
commit d1131c4a8d
65 changed files with 10517 additions and 2484 deletions

View File

@ -514,8 +514,7 @@ class account_move_line(osv.osv):
'analytic_lines': fields.one2many('account.analytic.line', 'move_id', 'Analytic lines'),
'centralisation': fields.selection([('normal','Normal'),('credit','Credit Centralisation'),('debit','Debit Centralisation'),('currency','Currency Adjustment')], 'Centralisation', size=8),
'balance': fields.function(_balance, fnct_search=_balance_search, string='Balance'),
'state': fields.selection([('draft','Unbalanced'), ('valid','Valid')], 'Status', readonly=True,
help='When new move line is created the status will be \'Draft\'.\n* When all the payments are done it will be in \'Valid\' status.'),
'state': fields.selection([('draft','Unbalanced'), ('valid','Balanced')], 'Status', readonly=True),
'tax_code_id': fields.many2one('account.tax.code', 'Tax Account', help="The Account can either be a base tax code or a tax code account."),
'tax_amount': fields.float('Tax/Base Amount', digits_compute=dp.get_precision('Account'), select=True, help="If the Tax account is a tax code account, this field will contain the taxed amount.If the tax account is base tax code, "\
"this field will contain the basic amount(without tax)."),

View File

@ -1078,7 +1078,7 @@
<field name="currency_id" attrs="{'readonly':[('state','=','valid')]}" groups="base.group_multi_currency"/>
<field name="reconcile_partial_id"/>
<field name="reconcile_id"/>
<field name="state"/>
<field name="state" invisible="1"/>
</tree>
</field>
</record>
@ -1980,7 +1980,7 @@
<field name="credit" sum="Total credit"/>
<field name="account_tax_id"/>
<field name="analytic_account_id" domain="[('parent_id','!=',False)]" groups="analytic.group_analytic_accounting"/>
<field name="state"/>
<field name="state" invisible="1"/>
</tree>
</field>
</record>

View File

@ -127,6 +127,7 @@
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Status</field>
<field name="field">state</field>
<field eval="True" name="invisible"/>
<field eval="19" name="sequence"/>
</record>
<record id="bank_col20" model="account.journal.column">
@ -214,6 +215,7 @@
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Status</field>
<field name="field">state</field>
<field eval="True" name="invisible"/>
<field eval="19" name="sequence"/>
</record>
<record id="bank_col20_multi" model="account.journal.column">
@ -289,6 +291,7 @@
<field name="view_id" ref="account_journal_view"/>
<field name="name">Status</field>
<field name="field">state</field>
<field eval="True" name="invisible"/>
<field eval="19" name="sequence"/>
</record>
@ -370,6 +373,7 @@
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Status</field>
<field name="field">state</field>
<field eval="True" name="invisible"/>
<field eval="19" name="sequence"/>
</record>
<record id="sp_journal_col20" model="account.journal.column">
@ -456,6 +460,7 @@
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Status</field>
<field name="field">state</field>
<field eval="True" name="invisible"/>
<field eval="19" name="sequence"/>
</record>
<record id="sp_refund_journal_col20" model="account.journal.column">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -106,8 +106,10 @@ openerp.account = function (instance) {
result.context = _.extend(result.context || {}, additional_context);
result.flags = result.flags || {};
result.flags.new_window = true;
return self.do_action(result, function () {
self.do_search(self.last_domain, self.last_context, self.last_group_by);
return self.do_action(result, {
on_close: function () {
self.do_search(self.last_domain, self.last_context, self.last_group_by);
}
});
});
});

View File

@ -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 01:37+0100\n"
"PO-Revision-Date: 2012-04-18 07:47+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"PO-Revision-Date: 2012-10-17 08:25+0000\n"
"Last-Translator: filsys <office@filsystem.ro>\n"
"Language-Team: Romanian <ro@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-08-28 06:42+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: account_asset
#: view:account.asset.asset:0
@ -440,12 +440,12 @@ msgstr "Metoda Timp"
#. module: account_asset
#: view:account.asset.category:0
msgid "Analytic Information"
msgstr ""
msgstr "Informatii analitice"
#. module: account_asset
#: view:asset.modify:0
msgid "Asset Durations to Modify"
msgstr ""
msgstr "Durata de modificat"
#. module: account_asset
#: constraint:account.move.line:0
@ -622,7 +622,7 @@ msgstr "Prorata Temporis"
#. module: account_asset
#: view:account.asset.category:0
msgid "Accounting Information"
msgstr ""
msgstr "Informații contabile"
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_invoice

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,213 @@
# Latvian 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-10-16 20:21+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Latvian <lv@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-10-17 04:36+0000\n"
"X-Generator: Launchpad (build 16152)\n"
#. module: anonymization
#: model:ir.model,name:anonymization.model_ir_model_fields_anonymize_wizard
msgid "ir.model.fields.anonymize.wizard"
msgstr "ir.model.fields.anonymize.wizard"
#. module: anonymization
#: field:ir.model.fields.anonymization,field_name:0
msgid "Field Name"
msgstr "Lauka Nosaukums"
#. module: anonymization
#: field:ir.model.fields.anonymization,field_id:0
msgid "Field"
msgstr "Lauks"
#. module: anonymization
#: field:ir.model.fields.anonymization.history,state:0
#: field:ir.model.fields.anonymize.wizard,state:0
msgid "State"
msgstr "Stāvoklis"
#. module: anonymization
#: field:ir.model.fields.anonymize.wizard,file_import:0
msgid "Import"
msgstr "Importēt"
#. module: anonymization
#: model:ir.model,name:anonymization.model_ir_model_fields_anonymization
msgid "ir.model.fields.anonymization"
msgstr "ir.model.fields.anonymization"
#. module: anonymization
#: field:ir.model.fields.anonymization.history,direction:0
msgid "Direction"
msgstr "Virziens"
#. module: anonymization
#: model:ir.actions.act_window,name:anonymization.action_ir_model_fields_anonymization_tree
#: view:ir.model.fields.anonymization:0
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization_fields
msgid "Anonymized Fields"
msgstr "Anonimizēti Lauki"
#. module: anonymization
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization
msgid "Database anonymization"
msgstr "Datubāzes anonimizācija"
#. module: anonymization
#: selection:ir.model.fields.anonymization.history,direction:0
msgid "clear -> anonymized"
msgstr "tīrs -> anonimizēts"
#. module: anonymization
#: selection:ir.model.fields.anonymization,state:0
#: selection:ir.model.fields.anonymize.wizard,state:0
msgid "Anonymized"
msgstr "Anonimizēta"
#. module: anonymization
#: field:ir.model.fields.anonymization,state:0
msgid "unknown"
msgstr "nezināms"
#. module: anonymization
#: field:ir.model.fields.anonymization,model_id:0
msgid "Object"
msgstr "Objekts"
#. module: anonymization
#: field:ir.model.fields.anonymization.history,filepath:0
msgid "File path"
msgstr "Ceļš uz failu"
#. module: anonymization
#: field:ir.model.fields.anonymization.history,date:0
msgid "Date"
msgstr "Datums"
#. module: anonymization
#: field:ir.model.fields.anonymize.wizard,file_export:0
msgid "Export"
msgstr "Eksportēt"
#. module: anonymization
#: view:ir.model.fields.anonymize.wizard:0
msgid "Reverse the Database Anonymization"
msgstr "Atgriezt Datubāzes Anonimizāciju"
#. module: anonymization
#: view:ir.model.fields.anonymize.wizard:0
msgid "Database Anonymization"
msgstr "Datubāzes Anonimizācija"
#. module: anonymization
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization_wizard
msgid "Anonymize database"
msgstr "Anonimizēt datubāzi"
#. module: anonymization
#: view:ir.model.fields.anonymization.history:0
#: field:ir.model.fields.anonymization.history,field_ids:0
msgid "Fields"
msgstr "Lauki"
#. module: anonymization
#: selection:ir.model.fields.anonymization,state:0
#: selection:ir.model.fields.anonymize.wizard,state:0
msgid "Clear"
msgstr "Notīrīt"
#. module: anonymization
#: view:ir.model.fields.anonymize.wizard:0
#: field:ir.model.fields.anonymize.wizard,summary:0
msgid "Summary"
msgstr "Kopsavilkums"
#. module: anonymization
#: view:ir.model.fields.anonymization:0
msgid "Anonymized Field"
msgstr "Anonimizēts lauks"
#. module: anonymization
#: selection:ir.model.fields.anonymize.wizard,state:0
msgid "Unstable"
msgstr "Nestabīls"
#. module: anonymization
#: selection:ir.model.fields.anonymization.history,state:0
msgid "Exception occured"
msgstr "Notikusī kļūda"
#. module: anonymization
#: selection:ir.model.fields.anonymization,state:0
#: selection:ir.model.fields.anonymize.wizard,state:0
msgid "Not Existing"
msgstr "Neeksistē"
#. module: anonymization
#: field:ir.model.fields.anonymization,model_name:0
msgid "Object Name"
msgstr "Objekta nosaukums"
#. module: anonymization
#: model:ir.actions.act_window,name:anonymization.action_ir_model_fields_anonymization_history_tree
#: view:ir.model.fields.anonymization.history:0
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization_history
msgid "Anonymization History"
msgstr "Anonimizācijas Vēsture"
#. module: anonymization
#: model:ir.model,name:anonymization.model_ir_model_fields_anonymization_history
msgid "ir.model.fields.anonymization.history"
msgstr "ir.model.fields.anonymization.history"
#. module: anonymization
#: model:ir.actions.act_window,name:anonymization.action_ir_model_fields_anonymize_wizard
#: view:ir.model.fields.anonymize.wizard:0
msgid "Anonymize Database"
msgstr "Anonimizēt Datubāzi"
#. module: anonymization
#: field:ir.model.fields.anonymize.wizard,name:0
msgid "File Name"
msgstr "Faila nosaukums"
#. module: anonymization
#: selection:ir.model.fields.anonymization.history,direction:0
msgid "anonymized -> clear"
msgstr "anonimizēts -> tīrs"
#. module: anonymization
#: selection:ir.model.fields.anonymization.history,state:0
msgid "Started"
msgstr "Iesākta"
#. module: anonymization
#: selection:ir.model.fields.anonymization.history,state:0
msgid "Done"
msgstr "Izdarīts"
#. module: anonymization
#: view:ir.model.fields.anonymization.history:0
#: field:ir.model.fields.anonymization.history,msg:0
#: field:ir.model.fields.anonymize.wizard,msg:0
msgid "Message"
msgstr "Ziņojums"
#. module: anonymization
#: code:addons/anonymization/anonymization.py:55
#: sql_constraint:ir.model.fields.anonymization:0
#, python-format
msgid "You cannot have two fields with the same name on the same object!"
msgstr "Nevar būt divi lauki ar vienādiem nosaukumiem vienam objektam!"

View File

@ -0,0 +1,45 @@
# Latvian 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-10-16 16:11+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Latvian <lv@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-10-17 04:36+0000\n"
"X-Generator: Launchpad (build 16152)\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 "Nevar būt divi lietotāji ar vienādu pieteikuma vārdu!"
#. module: base_crypt
#: constraint:res.users:0
msgid "The chosen company is not in the allowed companies for this user"
msgstr "Izvēlētais uzņēmums nav šim lietotājam atļauto uzņēmumu sarakstā"
#. module: base_crypt
#: code:addons/base_crypt/crypt.py:140
#, python-format
msgid "Please specify the password !"
msgstr "Lūdzu norādiet paroli!"
#. module: base_crypt
#: code:addons/base_crypt/crypt.py:140
#, python-format
msgid "Error"
msgstr "Kļūda"

View File

@ -1,3 +1,54 @@
.oe_import{
display: inline-block;
width: 600px;
padding: 16px;
}
.oe_import > p {
margin-left: 8px;
margin-right: 8px;
text-align: justify
}
/* ----------- IMPORT BOX ----------- */
.oe_import .oe_import_box{
margin: 16px;
padding: 16px;
background: #F0EEEE;
border-radius: 3px;
border: solid 1px #dddddd;
}
.oe_import .oe_import_toggle{
margin-top: 8px;
}
.oe_import .oe_import_options{
margin-top: 8px;
}
.oe_import .oe_import_options input{
width: 150px;
}
.oe_import a.oe_import_toggle {
display: block;
}
.oe_import a.oe_import_toggle:before {
content: '+'
}
.oe_import .oe_import_options p {
margin: 0;
padding: 0;
}
.oe_import .oe_import_options label {
display: inline-block;
width: 100px;
height:32px;
line-height:32px;
text-align: right;
}
/* ----------- INITIAL SETUP ------------ */
.openerp .oe_list_buttons .oe_alternative {
visibility: visible;
}
@ -25,38 +76,85 @@
display: block;
}
.oe_import .oe_import_error_report ul .oe_import_report_error {
background-color: #FFD9DB;
}
.oe_import .oe_import_error_report ul .oe_import_report_warning {
background-color: #FEFFD9;
}
.oe_import .oe_import_error_report ul .oe_import_report_info {
background-color: #d3ffd3;
}
.oe_import .oe_import_noheaders {
color: #888;
}
.oe_import a.oe_import_toggle {
display: block;
}
.oe_import a.oe_import_toggle:before {
content: '> '
}
.oe_import .oe_import_options p {
margin: 0;
padding: 0;
}
.oe_import .oe_import_options label {
display: inline-block;
width: 8em;
text-align: right;
}
.oe_import_selector ul,
.oe_import_selector li {
margin: 0; padding: 0;
}
/* ------------- ERRORS AND WARNINGS REPORT ------------ */
.oe_import .oe_import_error_report ul{
padding-left: 16px;
}
.oe_import .oe_import_report {
margin-right: 16px;
padding: 4px;
list-style: none;
border-bottom: solid 1px rgba(0,0,0,0.05);
}
.oe_import .oe_import_report:first-child{
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.oe_import .oe_import_report:last-child{
border-bottom-left-radius:3px;
border-bottom-right-radius:3px;
border-bottom: none;
}
.oe_import .oe_import_report_error {
background-color: #FFD9DB;
color: #AF5F5E;
}
.oe_import .oe_import_report_error:last-of-type{
border-bottom:none;
}
.oe_import .oe_import_report_warning {
background-color: #FEFFD9;
color: #918743;
}
.oe_import .oe_import_report_warning:last-of-type{
border-bottom:none;
}
.oe_import .oe_import_report_info {
background-color: #d3ffd3;
}
.oe_import .oe_import_report_info:last-of-type{
border-bottom:none;
}
/* ------------- THE CSV TABLE ------------ */
.oe_import .oe_import_grid{
margin: 16px;
border-radius:3px;
border: solid 1px #909090;
}
.oe_import .oe_import_grid tr{
height:16px;
}
.oe_import .oe_import_grid tr.oe_import_grid-header:first-child{
height: 24px;
background: #909090;
color: white;
}
.oe_import .oe_import_grid tr:nth-child(odd){
background: rgba(0,0,0,0.05);
}
.oe_import .oe_import_grid td{
padding: 2px;
padding-left: 4px;
}
.oe_import .oe_import_grid tr.oe_import_grid-header td:not(:last-child){
border-right: 1px solid #707070;
}
.oe_import .oe_import_grid td:not(:last-child){
border-right: 1px solid #D0D0D0;
}

View File

@ -53,8 +53,10 @@ openerp.base_import = function (instance) {
params: {
model: self.dataset.model
}
}, void 0, void 0, function () {
self.reload();
}, {
on_reverse_breadcrumb: function () {
self.reload();
},
});
return false;
});

View File

@ -21,24 +21,26 @@
class="oe_import_csv" target="_blank">.CSV</a>
file to import. If you need a sample importable file, you
can use the export tool to generate one.</p>
<label t-attf-for="file_#{_id}" autofocus="autofocus">CSV File:</label>
<input type="file" id-attf-id="file_#{_id}"
name="file" class="oe_import_file"/>
<button type="button" class="oe_import_file_reload">
<img src="/web/static/src/img/icons/gtk-refresh.png"/>
</button>
<div class="oe_import_with_file">
<a href="#" class="oe_import_toggle">
File Format Options…</a>
<div class="oe_import_toggled oe_import_options">
<p t-foreach="widget.opts" t-as="option">
<!-- no @name, avoid submission when file_update called -->
<label t-attf-for="#{option.name}_#{_id}">
<t t-esc="option.label"/></label>
<input t-attf-id="#{option.name}_#{_id}"
t-attf-class="oe_import_#{option.name}"
t-att-value="option.value"/>
</p>
<div class="oe_import_box">
<label t-attf-for="file_#{_id}" autofocus="autofocus">CSV File:</label>
<input type="file" id-attf-id="file_#{_id}"
name="file" class="oe_import_file"/>
<button type="button" class="oe_import_file_reload">
<img src="/web/static/src/img/icons/gtk-refresh.png"/>
</button>
<div class="oe_import_with_file">
<a href="#" class="oe_import_toggle">
File Format Options…</a>
<div class="oe_import_toggled oe_import_options">
<p t-foreach="widget.opts" t-as="option">
<!-- no @name, avoid submission when file_update called -->
<label t-attf-for="#{option.name}_#{_id}">
<t t-esc="option.label"/></label>
<input t-attf-id="#{option.name}_#{_id}"
t-attf-class="oe_import_#{option.name}"
t-att-value="option.value"/>
</p>
</div>
</div>
</div>
@ -54,7 +56,7 @@
simpler especially when the file has many columns.</p>
<div class="oe_import_error_report"></div>
<table class="oe_import_grid" width="100%"/>
<table class="oe_import_grid" />
<h2>Frequently Asked Questions</h2>
<dl>

View File

@ -7,25 +7,25 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-08-13 12:14+0000\n"
"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n"
"PO-Revision-Date: 2012-10-17 00:06+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 06:43+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: document_page
#: field:document.page.type,template:0
msgid "Document page Template"
msgstr ""
msgstr "Modelo de página de Documento"
#. module: document_page
#: model:ir.actions.act_window,name:document_page.action_wiki
#: model:ir.ui.menu,name:document_page.menu_action_wiki_wiki
msgid "Document Pages"
msgstr ""
msgstr "Páginas do Documento"
#. module: document_page
#: field:document.page.type,method:0
@ -56,7 +56,7 @@ msgstr "Indica se estas páginas têm uma tabela de conteúdo ou não"
#. module: document_page
#: model:ir.model,name:document_page.model_wiki_wiki_history view:document.page.history:0
msgid "Document page History"
msgstr ""
msgstr "Histórico de páginas do Documento"
#. module: document_page
#: field:document.page,minor_edit:0
@ -269,7 +269,7 @@ msgstr "Todas as Páginas de Históricos"
#. module: document_page
#: model:ir.model,name:document_page.model_wiki_wiki
msgid "document.page"
msgstr ""
msgstr "document.page"
#. module: document_page
#: help:document.page.type,method:0
@ -284,7 +284,7 @@ msgstr "Fechar"
#. module: document_page
#: model:ir.model,name:document_page.model_wizard_wiki_history_show_diff
msgid "wizard.document.page.history.show_diff"
msgstr ""
msgstr "wizard.document.page.history.show_diff"
#. module: document_page
#: field:document.page.history,wiki_id:0
@ -357,7 +357,7 @@ msgstr "Esta é uma edição Avançada ?"
#: model:ir.model,name:document_page.model_wiki_groups
#: model:ir.ui.menu,name:document_page.menu_action_wiki_groups view:document.page.type:0
msgid "Document Types"
msgstr ""
msgstr "Tipos de Documento"
#. module: document_page
#: view:document.page:0
@ -374,12 +374,12 @@ msgstr "Modificado por"
#: field:document.page,type:0
#, python-format
msgid "Type"
msgstr ""
msgstr "Tipo"
#. module: document_page
#: view:document.page.type:0 view:document.page.page.open:0
msgid "Open Document Page"
msgstr ""
msgstr "Página do documento aberto"
#. module: document_page
#: model:ir.model,name:document_page.model_wiki_wiki_page_open

View File

@ -175,7 +175,7 @@ class email_template(osv.osv):
'res_model': 'mail.compose.message',
'src_model': src_obj,
'view_type': 'form',
'context': "{'default_composition_mode': 'mass_mail', 'default_template_id' : %d}" % (template.id),
'context': "{'default_composition_mode': 'mass_mail', 'default_template_id' : %d, 'default_use_template': True}" % (template.id),
'view_mode':'form,tree',
'view_id': res_id,
'target': 'new',

View File

@ -24,7 +24,8 @@ import tools
from osv import osv
from osv import fields
class mail_compose_message(osv.osv_memory):
class mail_compose_message(osv.TransientModel):
_inherit = 'mail.compose.message'
def _get_templates(self, cr, uid, context=None):

View File

@ -8,38 +8,15 @@
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//form/footer/button" position="before">
<field name="use_template" invisible="1"/>
<button icon="gtk-paste" type="object" name="toggle_template"
string="" help="Use a message template" invisible="1"/>
<button icon="gtk-save" type="object" name="save_as_template"
string="" help="Save as a new template" invisible="1"/>
</xpath>
<xpath expr="//form/notebook" position="after">
<group attrs="{'invisible':[('use_template','=',False)]}" colspan="4" col="4">
<field name="use_template" invisible="1"/>
<field name="template_id" colspan="3" invisible="1"
<group attrs="{'invisible':[('use_template','=',False)]}">
<field name="use_template" invisible="1"
on_change="onchange_use_template(use_template, template_id, composition_mode, model, res_id, context)"/>
<field name="template_id"
on_change="onchange_template_id(use_template, template_id, composition_mode, model, res_id, context)"/>
</group>
</xpath>
</data>
</field>
</record>
<record model="ir.ui.view" id="email_compose_message_wizard_inherit_form_chatter">
<field name="name">mail.compose.message.form</field>
<field name="model">mail.compose.message</field>
<field name="inherit_id" ref="mail.email_compose_message_wizard_form_chatter"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='partner_ids']" position="after">
<field name="use_template" colspan="2" nolabel="1" invisible="1"
on_change="onchange_use_template(use_template, template_id, composition_mode, model, res_id, context)"/>
<field name="template_id" colspan="2" nolabel="1"
attrs="{'invisible':[('use_template','=',False)]}"
on_change="onchange_template_id(use_template, template_id, composition_mode, model, res_id, context)"/>
</xpath>
<xpath expr="//button[@name='dummy']" position="before">
<xpath expr="//form/footer/button" position="after">
<button icon="/email_template/static/src/img/email_template.png"
type="object" name="toggle_template" string=""
help="Use a message template"

View File

@ -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 01:37+0100\n"
"PO-Revision-Date: 2012-05-10 17:47+0000\n"
"Last-Translator: Raphael Collet (OpenERP) <Unknown>\n"
"PO-Revision-Date: 2012-10-16 23:42+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 06:24+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:40+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: hr
#: model:process.node,name:hr.process_node_openerpuser0
@ -24,7 +24,7 @@ msgstr "Usuário Openerp"
#. module: hr
#: view:hr.job:0 field:hr.job,requirements:0
msgid "Requirements"
msgstr "Requisitos"
msgstr "Pré-requisitos"
#. module: hr
#: constraint:hr.department:0
@ -197,6 +197,7 @@ msgstr "Feminino"
msgid ""
"Expected number of employees for this job position after new recruitment."
msgstr ""
"Número de empregados para esta posição após o novo processo de contratação."
#. module: hr
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
@ -289,7 +290,7 @@ msgstr "Categorias"
#. module: hr
#: field:hr.job,expected_employees:0
msgid "Total Employees"
msgstr ""
msgstr "Total de Empregados"
#. module: hr
#: selection:hr.employee,marital:0
@ -462,7 +463,7 @@ msgstr "Erro! Você não pode criar hierarquia recursiva de funcionários."
#. module: hr
#: model:ir.actions.act_window,name:hr.action2
msgid "Subordinate Hierarchy"
msgstr ""
msgstr "Subordinação hierárquica"
#. module: hr
#: model:ir.actions.act_window,help:hr.view_department_form_installer
@ -712,12 +713,12 @@ msgstr "Subordinados"
#. module: hr
#: field:hr.job,no_of_employee:0
msgid "Number of employees currently occupying this job position."
msgstr ""
msgstr "Número de empregados atualmente ocupando esta posição"
#. module: hr
#: field:hr.job,no_of_recruitment:0
msgid "Number of new employees you expect to recruit."
msgstr ""
msgstr "Número de novos empregados a serem contratados."
#~ msgid "Sunday"
#~ msgstr "Domingo"

View File

@ -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 01:37+0100\n"
"PO-Revision-Date: 2012-02-13 11:31+0000\n"
"Last-Translator: Mauricio Pacheco de Andrade <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:10+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:30+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:40+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: hr_evaluation
#: help:hr_evaluation.plan.phase,send_anonymous_manager:0
@ -317,7 +317,7 @@ msgstr "Avaliações feitas no mês passado"
#. module: hr_evaluation
#: model:ir.model,name:hr_evaluation.model_mail_compose_message
msgid "Email composition wizard"
msgstr ""
msgstr "Assistente para compor Email"
#. module: hr_evaluation
#: view:hr.evaluation.report:0

View File

@ -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 01:37+0100\n"
"PO-Revision-Date: 2012-02-19 15:06+0000\n"
"Last-Translator: Gustavo T <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:16+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:23+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:40+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
@ -28,7 +28,8 @@ msgid "Allocation Type"
msgstr "Tipo de Alocação"
#. module: hr_holidays
#: selection:hr.employee,current_leave_state:0 selection:hr.holidays,state:0
#: selection:hr.employee,current_leave_state:0
#: selection:hr.holidays,state:0
msgid "Waiting Second Approval"
msgstr "Aguardando Segunda Aprovação"
@ -53,7 +54,8 @@ msgid "Allocation Mode"
msgstr "Modo de Alocação"
#. module: hr_holidays
#: view:hr.holidays:0 field:hr.holidays,department_id:0
#: view:hr.holidays:0
#: field:hr.holidays,department_id:0
msgid "Department"
msgstr "Departamento"
@ -63,7 +65,8 @@ msgid "Requests Approve"
msgstr "Aprovar Solicitações"
#. module: hr_holidays
#: selection:hr.employee,current_leave_state:0 selection:hr.holidays,state:0
#: selection:hr.employee,current_leave_state:0
#: selection:hr.holidays,state:0
msgid "Refused"
msgstr "Recusado"
@ -140,7 +143,8 @@ msgid "Summary Of Leaves"
msgstr "Resumo das Folgas"
#. module: hr_holidays
#: selection:hr.employee,current_leave_state:0 view:hr.holidays:0
#: selection:hr.employee,current_leave_state:0
#: view:hr.holidays:0
#: selection:hr.holidays,state:0
msgid "Approved"
msgstr "Aprovado"
@ -204,7 +208,8 @@ msgid "Leaves by Department"
msgstr "Folgas por Departamento"
#. module: hr_holidays
#: selection:hr.employee,current_leave_state:0 selection:hr.holidays,state:0
#: selection:hr.employee,current_leave_state:0
#: selection:hr.holidays,state:0
msgid "Cancelled"
msgstr "Cancelado"
@ -258,7 +263,8 @@ msgstr ""
#. module: hr_holidays
#: field:hr.holidays,holiday_status_id:0
#: field:hr.holidays.remaining.leaves.user,leave_type:0
#: view:hr.holidays.status:0 field:hr.holidays.status,name:0
#: view:hr.holidays.status:0
#: field:hr.holidays.status,name:0
#: field:hr.holidays.summary.dept,holiday_type:0
#: model:ir.actions.act_window,name:hr_holidays.open_view_holiday_status
#: model:ir.model,name:hr_holidays.model_hr_holidays_status
@ -313,7 +319,8 @@ msgid "Remaining Leaves"
msgstr "Folhas Restantes"
#. module: hr_holidays
#: view:hr.holidays:0 field:hr.holidays,state:0
#: view:hr.holidays:0
#: field:hr.holidays,state:0
msgid "State"
msgstr "Status"
@ -323,14 +330,17 @@ msgid "Total holidays by type"
msgstr "Total de Folgas por tipo"
#. module: hr_holidays
#: view:hr.employee:0 view:hr.holidays:0 field:hr.holidays,employee_id:0
#: view:hr.employee:0
#: view:hr.holidays:0
#: field:hr.holidays,employee_id:0
#: field:hr.holidays.remaining.leaves.user,name:0
#: model:ir.model,name:hr_holidays.model_hr_employee
msgid "Employee"
msgstr "Funcionário"
#. module: hr_holidays
#: selection:hr.employee,current_leave_state:0 selection:hr.holidays,state:0
#: selection:hr.employee,current_leave_state:0
#: selection:hr.holidays,state:0
msgid "New"
msgstr "Novo"
@ -371,7 +381,8 @@ msgid "Allocation for %s"
msgstr "Alocação para %s"
#. module: hr_holidays
#: view:hr.holidays:0 field:hr.holidays,number_of_days:0
#: view:hr.holidays:0
#: field:hr.holidays,number_of_days:0
#: field:hr.holidays,number_of_days_temp:0
msgid "Number of Days"
msgstr "Número de Dias"
@ -413,9 +424,12 @@ msgid ""
"When selected, the Allocation/Leave Requests for this type require a second "
"validation to be approved."
msgstr ""
"Quando selecionado, a Locação/Requerimento de Saída deste tipo necessita de "
"uma segunda aprovação."
#. module: hr_holidays
#: selection:hr.employee,current_leave_state:0 selection:hr.holidays,state:0
#: selection:hr.employee,current_leave_state:0
#: selection:hr.holidays,state:0
msgid "Waiting Approval"
msgstr "Aguardando Aprovação"
@ -449,6 +463,7 @@ msgid "Lavender"
msgstr "Lavanda"
#. module: hr_holidays
#: xsl:holidays.summary:0
#: view:hr.holidays:0
msgid "Month"
msgstr "Mês"
@ -472,7 +487,8 @@ msgid "Employee's Holidays"
msgstr "Férias de Funcionários"
#. module: hr_holidays
#: view:hr.holidays:0 field:hr.holidays,category_id:0
#: view:hr.holidays:0
#: field:hr.holidays,category_id:0
msgid "Category"
msgstr "Categoria"
@ -517,7 +533,8 @@ msgid "Holiday"
msgstr "Feriado"
#. module: hr_holidays
#: field:hr.holidays,case_id:0 field:hr.holidays.status,categ_id:0
#: field:hr.holidays,case_id:0
#: field:hr.holidays.status,categ_id:0
msgid "Meeting"
msgstr "Reunião"
@ -559,7 +576,8 @@ msgid "Error ! You cannot create recursive Hierarchy of Employees."
msgstr "Erro! Você não pode criar uma Hierarquia de Funcionários recursiva."
#. module: hr_holidays
#: view:hr.employee:0 field:hr.employee,remaining_leaves:0
#: view:hr.employee:0
#: field:hr.employee,remaining_leaves:0
msgid "Remaining Legal Leaves"
msgstr "Folgas Restantes"
@ -641,7 +659,8 @@ msgid "Compensatory Days"
msgstr "Dias Compensatórios"
#. module: hr_holidays
#: view:hr.holidays:0 field:hr.holidays,notes:0
#: view:hr.holidays:0
#: field:hr.holidays,notes:0
msgid "Reasons"
msgstr "Motivos"
@ -652,7 +671,8 @@ msgid "Leaves Analysis"
msgstr "Análise de Folgas"
#. module: hr_holidays
#: view:hr.holidays.summary.dept:0 view:hr.holidays.summary.employee:0
#: view:hr.holidays.summary.dept:0
#: view:hr.holidays.summary.employee:0
msgid "Cancel"
msgstr "Cancelar"
@ -666,13 +686,15 @@ msgstr ""
"departamento"
#. module: hr_holidays
#: view:hr.holidays:0 selection:hr.holidays.summary.dept,holiday_type:0
#: view:hr.holidays:0
#: selection:hr.holidays.summary.dept,holiday_type:0
#: selection:hr.holidays.summary.employee,holiday_type:0
msgid "Validated"
msgstr "Validado"
#. module: hr_holidays
#: view:hr.holidays:0 selection:hr.holidays,type:0
#: view:hr.holidays:0
#: selection:hr.holidays,type:0
msgid "Allocation Request"
msgstr "Solicitação de Alocação"
@ -688,7 +710,8 @@ msgid "Apply Double Validation"
msgstr "Aplicar Validação Dupla"
#. module: hr_holidays
#: view:hr.holidays.summary.dept:0 view:hr.holidays.summary.employee:0
#: view:hr.holidays.summary.dept:0
#: view:hr.holidays.summary.employee:0
msgid "Print"
msgstr "Imprimir"
@ -709,7 +732,8 @@ msgid "By Employee Category"
msgstr "Por Categoria de Funcionário"
#. module: hr_holidays
#: view:hr.holidays:0 selection:hr.holidays,type:0
#: view:hr.holidays:0
#: selection:hr.holidays,type:0
msgid "Leave Request"
msgstr "Pedido de Folga"
@ -785,6 +809,8 @@ msgid ""
"If you select this checkbox, the system allows the employees to take more "
"leaves than the available ones for this type."
msgstr ""
"Caso esta caixa seja selecionada, o sistema autoriza os empregados deste "
"tipo a tirarem mais licenças do que as disponíveis para este tipo."
#. module: hr_holidays
#: help:hr.holidays.status,leaves_taken:0
@ -839,7 +865,8 @@ msgid "Approve"
msgstr "Aprovar"
#. module: hr_holidays
#: view:hr.holidays:0 field:hr.holidays,date_from:0
#: view:hr.holidays:0
#: field:hr.holidays,date_from:0
msgid "Start Date"
msgstr "Data Inicial"

View File

@ -8,15 +8,14 @@ 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: 2011-06-11 13:23+0000\n"
"Last-Translator: Christopher Ormaza - (Ecuadorenlinea.net) "
"<chris.ormaza@gmail.com>\n"
"PO-Revision-Date: 2012-10-17 04:38+0000\n"
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
"Language-Team: Spanish (Ecuador) <es_EC@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-08-28 06:33+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: hr_payroll
#: field:hr.payslip.line,condition_select:0
@ -170,7 +169,7 @@ msgstr "Todas las reglas hijas"
#. module: hr_payroll
#: view:hr.payslip:0 view:hr.salary.rule:0
msgid "Input Data"
msgstr ""
msgstr "Datos de entrada"
#. module: hr_payroll
#: constraint:hr.payslip:0
@ -228,7 +227,7 @@ msgstr "Detalle regla salarial"
#. module: hr_payroll
#: report:paylip.details:0 report:payslip:0
msgid "Note"
msgstr ""
msgstr "Notas"
#. module: hr_payroll
#: field:hr.payroll.structure,code:0 field:hr.payslip,number:0
@ -271,7 +270,7 @@ msgstr "Suma de el sueldo de todos los contratos actuales del empleado"
#. module: hr_payroll
#: view:hr.payslip:0
msgid "Total Working Days"
msgstr ""
msgstr "Total de días trabajado"
#. module: hr_payroll
#: help:hr.payslip.line,code:0 help:hr.salary.rule,code:0
@ -363,7 +362,7 @@ msgstr "Semi-anualmente"
#. module: hr_payroll
#: view:hr.salary.rule:0
msgid "Children Definition"
msgstr ""
msgstr "Definición de Hijos"
#. module: hr_payroll
#: report:paylip.details:0 report:payslip:0
@ -373,29 +372,29 @@ msgstr "Correo electrónico"
#. module: hr_payroll
#: view:hr.payslip.run:0
msgid "Search Payslip Batches"
msgstr ""
msgstr "Buscar bloque de roles"
#. module: hr_payroll
#: field:hr.payslip.line,amount_percentage_base:0
#: field:hr.salary.rule,amount_percentage_base:0
msgid "Percentage based on"
msgstr ""
msgstr "Porcentaje basado en"
#. module: hr_payroll
#: help:hr.payslip.line,amount_percentage:0
#: help:hr.salary.rule,amount_percentage:0
msgid "For example, enter 50.0 to apply a percentage of 50%"
msgstr ""
msgstr "Por ejemplo, ingrese 50.0 para aplicar el 50%"
#. module: hr_payroll
#: field:hr.payslip,paid:0
msgid "Made Payment Order ? "
msgstr ""
msgstr "Orden de Pago generada ? "
#. module: hr_payroll
#: report:contribution.register.lines:0
msgid "PaySlip Lines by Contribution Register"
msgstr ""
msgstr "Detalle de nómina por contribución registrada"
#. module: hr_payroll
#: help:hr.payslip,state:0
@ -513,7 +512,7 @@ msgstr "Regla de salario hija"
#: field:hr.payslip.run,date_end:0 report:paylip.details:0 report:payslip:0
#: field:payslip.lines.contribution.register,date_to:0
msgid "Date To"
msgstr ""
msgstr "Fecha hasta"
#. module: hr_payroll
#: selection:hr.payslip.line,condition_select:0
@ -576,7 +575,7 @@ msgstr "El contrato al cual aplica este ingreso"
#. module: hr_payroll
#: view:hr.salary.rule:0
msgid "Computation"
msgstr ""
msgstr "Cálculo"
#. module: hr_payroll
#: help:hr.payslip.input,amount:0
@ -711,7 +710,7 @@ msgstr "Expresión de python"
#. module: hr_payroll
#: report:paylip.details:0 report:payslip:0
msgid "Designation"
msgstr ""
msgstr "Designación"
#. module: hr_payroll
#: code:addons/hr_payroll/wizard/hr_payroll_payslips_by_employees.py:52
@ -839,7 +838,7 @@ msgstr "Registrar Nombre"
#. module: hr_payroll
#: view:hr.salary.rule:0
msgid "General"
msgstr ""
msgstr "General"
#. module: hr_payroll
#: code:addons/hr_payroll/hr_payroll.py:664
@ -913,7 +912,7 @@ msgstr "Detalle del rol"
#: model:ir.actions.act_window,name:hr_payroll.action_view_hr_payslip_form
#: model:ir.ui.menu,name:hr_payroll.menu_department_tree
msgid "Employee Payslips"
msgstr ""
msgstr "Roles de Empleado"
#. module: hr_payroll
#: view:hr.payslip.line:0 field:hr.payslip.line,register_id:0
@ -1004,7 +1003,7 @@ msgstr "Lineas de roles por registro de contribuciones"
#. module: hr_payroll
#: selection:hr.payslip,state:0
msgid "Waiting"
msgstr ""
msgstr "Esperando"
#. module: hr_payroll
#: report:paylip.details:0 report:payslip:0

View File

@ -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: 2011-12-23 09:56+0000\n"
"PO-Revision-Date: 2011-03-10 23:28+0000\n"
"Last-Translator: Emerson <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:22+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 06:22+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:40+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: l10n_be
#: field:partner.vat.intra,test_xml:0
@ -25,6 +25,7 @@ msgstr "Test XML file"
#: view:partner.vat.list_13:0
msgid "You can remove customers which you do not want in exported xml file"
msgstr ""
"Você pode remover os clientes não quer incluir no arquivo xml a ser exportado"
#. module: l10n_be
#: view:partner.vat_13:0
@ -32,11 +33,13 @@ msgid ""
"This wizard will create an XML file for VAT details and total invoiced "
"amounts per partner."
msgstr ""
"Este assistente irá criar um arquivo XML para detalhamento de VAT e "
"quantidades totais faturadas por parceiro."
#. module: l10n_be
#: model:account.account.type,name:l10n_be.user_type_tiers_receiv
msgid "Tiers - Recevable"
msgstr ""
msgstr "Níveis - Contas a Receber"
#. module: l10n_be
#: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:102
@ -59,7 +62,7 @@ msgstr "Error! You can not create recursive companies."
#. module: l10n_be
#: model:account.account.type,name:l10n_be.user_type_tiers
msgid "Tiers"
msgstr ""
msgstr "Níveis"
#. module: l10n_be
#: field:l1on_be.vat.declaration,period_id:0
@ -80,7 +83,7 @@ msgstr "Save the File with '.xml' extension."
#. module: l10n_be
#: model:account.account.type,name:l10n_be.user_type_charge
msgid "Charge"
msgstr ""
msgstr "Despesa"
#. module: l10n_be
#: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:47
@ -100,12 +103,12 @@ msgstr "Create XML"
#. module: l10n_be
#: model:account.account.type,name:l10n_be.user_type_capitaux
msgid "Capital"
msgstr ""
msgstr "Capital"
#. module: l10n_be
#: view:partner.vat.list_13:0
msgid "Print"
msgstr ""
msgstr "Impressão"
#. module: l10n_be
#: view:partner.vat.intra:0
@ -121,7 +124,7 @@ msgstr "Save"
#. module: l10n_be
#: sql_constraint:res.company:0
msgid "The company name must be unique !"
msgstr ""
msgstr "O nome da empresa deve ser único!"
#. module: l10n_be
#: field:l1on_be.vat.declaration,msg:0
@ -133,7 +136,7 @@ msgstr "File created"
#. module: l10n_be
#: view:partner.vat.intra:0
msgid "_Close"
msgstr ""
msgstr "_Fechar"
#. module: l10n_be
#: code:addons/l10n_be/wizard/l10n_be_account_vat_declaration.py:131
@ -144,7 +147,7 @@ msgstr "Save XML For Vat declaration"
#. module: l10n_be
#: view:partner.vat.list_13:0
msgid "Customers"
msgstr ""
msgstr "Clientes"
#. module: l10n_be
#: model:account.account.type,name:l10n_be.user_type_tax_in

View File

@ -0,0 +1,162 @@
# Brazilian Portuguese 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-10-16 23:34+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: l10n_be_hr_payroll
#: help:hr.employee,disabled_spouse_bool:0
msgid "if recipient spouse is declared disabled by law"
msgstr "Caso o cônjuge beneficiário seja considerado incapaz perante a lei"
#. module: l10n_be_hr_payroll
#: help:hr.employee,disabled_children_bool:0
msgid "if recipient children is/are declared disabled by law"
msgstr ""
"Caso o(s) filho(s) beneficiário(s) seja(m) considerado(s) incapaz(es) "
"perante a lei"
#. module: l10n_be_hr_payroll
#: field:hr.contract,misc_onss_deduction:0
msgid "Miscellaneous exempt ONSS "
msgstr "Outros isentos de INSS "
#. module: l10n_be_hr_payroll
#: model:ir.model,name:l10n_be_hr_payroll.model_hr_employee
msgid "Employee"
msgstr "Empregado"
#. module: l10n_be_hr_payroll
#: field:hr.employee,disabled_spouse_bool:0
msgid "Disabled Spouse"
msgstr "Cõnjuge incapaz"
#. module: l10n_be_hr_payroll
#: field:hr.contract,retained_net_amount:0
msgid "Net retained "
msgstr "Líquido retido "
#. module: l10n_be_hr_payroll
#: field:hr.employee,resident_bool:0
msgid "Nonresident"
msgstr "Não residente no país local"
#. module: l10n_be_hr_payroll
#: help:hr.employee,resident_bool:0
msgid "if recipient lives in a foreign country"
msgstr "Caso o beneficiário resida em outro país"
#. module: l10n_be_hr_payroll
#: view:hr.employee:0
msgid "if spouse has professionnel income or not"
msgstr "Caso o cônjuge possua renda"
#. module: l10n_be_hr_payroll
#: view:hr.contract:0
msgid "Miscellaneous"
msgstr "Outros"
#. module: l10n_be_hr_payroll
#: field:hr.contract,insurance_employee_deduction:0
msgid "Insurance Group - by worker "
msgstr "Categoria do Seguro - por empregado "
#. module: l10n_be_hr_payroll
#: selection:hr.employee,spouse_fiscal_status:0
msgid "With Income"
msgstr "Com renda"
#. module: l10n_be_hr_payroll
#: selection:hr.employee,spouse_fiscal_status:0
msgid "Without Income"
msgstr "Sem renda"
#. module: l10n_be_hr_payroll
#: field:hr.employee,disabled_children_number:0
msgid "Number of disabled children"
msgstr "Quantidade de filho(s) incapaz(es)"
#. module: l10n_be_hr_payroll
#: field:hr.contract,additional_net_amount:0
msgid "Net supplements"
msgstr "Renda suplementar"
#. module: l10n_be_hr_payroll
#: constraint:hr.employee:0
msgid "Error ! You cannot create recursive Hierarchy of Employees."
msgstr "Erro! Você não pode criar uma Hierarquia de Empregados recursiva."
#. module: l10n_be_hr_payroll
#: field:hr.contract,car_company_amount:0
msgid "Company car employer"
msgstr "Carro da empresa"
#. module: l10n_be_hr_payroll
#: field:hr.contract,misc_advantage_amount:0
msgid "Benefits of various nature "
msgstr "Benefícios de outras naturezas "
#. module: l10n_be_hr_payroll
#: field:hr.contract,car_employee_deduction:0
msgid "Company Car Deduction for Worker"
msgstr "Dedução referente ao carro da empresa"
#. module: l10n_be_hr_payroll
#: field:hr.employee,disabled_children_bool:0
msgid "Disabled Children"
msgstr "Filho(s) incapaz(es)"
#. module: l10n_be_hr_payroll
#: model:ir.model,name:l10n_be_hr_payroll.model_hr_contract
msgid "Contract"
msgstr "Contrato"
#. module: l10n_be_hr_payroll
#: field:hr.contract,meal_voucher_amount:0
msgid "Check Value Meal "
msgstr "Vale refeição "
#. module: l10n_be_hr_payroll
#: field:hr.contract,travel_reimbursement_amount:0
msgid "Reimbursement of travel expenses"
msgstr "Reembolso de despeza de viagem"
#. module: l10n_be_hr_payroll
#: constraint:hr.contract:0
msgid "Error! contract start-date must be lower then contract end-date."
msgstr ""
"Erro! A data de início do contrato deve ser menor que a data de término do "
"contrato."
#. module: l10n_be_hr_payroll
#: field:hr.employee,spouse_fiscal_status:0
msgid "Tax status for spouse"
msgstr "Situação fiscal do cônjuge"
#. module: l10n_be_hr_payroll
#: view:hr.contract:0
msgid "by Worker"
msgstr "por Empregado"
#. module: l10n_be_hr_payroll
#: view:hr.employee:0
msgid "number of dependent children declared as disabled"
msgstr "Quantidade de filhos declarados como incapazes"
#. module: l10n_be_hr_payroll
#: field:hr.contract,meal_voucher_employee_deduction:0
msgid "Check Value Meal - by worker "
msgstr "Vale refeição - por empregado "

View File

@ -8,29 +8,29 @@ 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: 2011-03-09 22:08+0000\n"
"Last-Translator: Emerson <Unknown>\n"
"PO-Revision-Date: 2012-10-16 23:56+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:42+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_profit_and_loss
msgid "损益类"
msgstr ""
msgstr "Categoria Lucro ou Prejuízo"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_all
msgid "所有科目"
msgstr ""
msgstr "Todos os assuntos"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_equity
msgid "所有者权益类"
msgstr ""
msgstr "Capital Próprio"
#. module: l10n_cn
#: model:ir.actions.todo,note:l10n_cn.config_call_account_template_cn_chart
@ -43,28 +43,28 @@ msgid ""
"Management/Configuration/Financial Accounting/Financial Accounts/Generate "
"Chart of Accounts from a Chart Template."
msgstr ""
"Generate Chart of Accounts from a 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."
"Gerar Gráfico de Contas apartir de um modelo. Você deverá informar o nome da "
"empresa, o gráfico modelo, o número de dígitos para gerar o código para suas "
"contas, a conta bancária e a moeda para gerar a sequência. Em seguida uma "
"cópia do gráfico modelo é gerada.\n"
"Este é o mesmo assistente que é executado a partir de Gerenciamento "
"Financeiro/Configuração/Contabilidade Financeira/Contas Financeiras/Gerar "
"Gráfico de Contas a partir de um Gráfico Modelo."
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_debt
msgid "负债类"
msgstr ""
msgstr "Classe Passivos"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_cost
msgid "成本类"
msgstr ""
msgstr "Custo da Classe"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_capital
msgid "资产类"
msgstr ""
msgstr "Classe Ativos"
#~ msgid "中国会计科目表"
#~ msgstr "中国会计科目表"

View File

@ -8,24 +8,24 @@ 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: 2011-04-11 18:21+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"PO-Revision-Date: 2012-10-17 04:39+0000\n"
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
"Language-Team: Spanish (Ecuador) <es_EC@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-08-28 06:42+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_expense
msgid "Gasto"
msgstr ""
msgstr "Gasto"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_stock
msgid "Inventario"
msgstr ""
msgstr "Inventario"
#. module: l10n_ec
#: model:ir.actions.todo,note:l10n_ec.config_call_account_template_ec
@ -50,47 +50,47 @@ msgstr ""
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_receivable
msgid "Por Cobrar"
msgstr ""
msgstr "Por Cobrar"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_asset
msgid "Activo"
msgstr ""
msgstr "Activo"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_tax
msgid "Impuesto"
msgstr ""
msgstr "Impuesto"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_liability
msgid "Pasivo"
msgstr ""
msgstr "Pasivo"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_capital
msgid "Capital"
msgstr ""
msgstr "Capital"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_cash
msgid "Efectivo"
msgstr ""
msgstr "Efectivo"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_payable
msgid "Por Pagar"
msgstr ""
msgstr "Por Pagar"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_income
msgid "Ingreso"
msgstr ""
msgstr "Ingreso"
#. module: l10n_ec
#: model:account.account.type,name:l10n_ec.account_type_view
msgid "View"
msgstr ""
msgstr "Vista"
#~ msgid ""
#~ "\n"

View File

@ -8,14 +8,14 @@ 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: 2011-03-10 23:15+0000\n"
"Last-Translator: Emerson <Unknown>\n"
"PO-Revision-Date: 2012-10-16 23:59+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:41+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: l10n_ma
#: model:account.account.type,name:l10n_ma.cpt_type_imm
@ -81,7 +81,7 @@ msgstr "Name"
#. module: l10n_ma
#: field:l10n.ma.report,line_ids:0
msgid "Lines"
msgstr "Lines"
msgstr "Linhas"
#. module: l10n_ma
#: model:account.account.type,name:l10n_ma.cpt_type_tax

View File

@ -69,29 +69,29 @@
"51800_advertising","51800","Merchant Account Fees","other","l10n_us.user_type_cogs","cost_of_goods_sold","FALSE","l10n_us.account_chart_template_advertising"
"53500_advertising","53500","Subcontracted Services","other","l10n_us.user_type_cogs","cost_of_goods_sold","FALSE","l10n_us.account_chart_template_advertising"
"64200_advertising","64200","Marketing Expense","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_advertising"
"41200_agriculture","41200","Agricultural Program Payments","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"42500_agriculture","42500","Commodity Credit Loans","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"42800_agriculture","42800","Cooperative Distributions","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"42900_agriculture","42900","Crop Insurance Proceeds","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"43000_agriculture","43000","Crop Sales","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"43100_agriculture","43100","Custom Hire Income","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"43600_agriculture","43600","Farmers Market Sales","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"44100_agriculture","44100","Fuel Tax Credits and Other Inc.","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"45500_agriculture","45500","Livestock Sales","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"47400_agriculture","47400","Rental Income","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agricultar"
"61100_agriculture","61100","Car and Truck Expenses","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"61500_agriculture","61500","Chemicals Purchased","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"61900_agriculture","61900","Conservation Expenses","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"62300_agriculture","62300","Custom Hire and Contract Labor","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"62900_agriculture","62900","Feed Purchased","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"63000_agriculture","63000","Fertilizers and Lime","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"63100_agriculture","63100","Freight and Trucking","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"63200_agriculture","63200","Gasoline, Fuel and Oil","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"67500_agriculture","67500","Seeds and Plants Purchased","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"67800_agriculture","67800","Small Tools and Equipment","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"67900_agriculture","67900","Storage and Warehousing","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"68500_agriculture","68500","Uniforms","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"68800_agriculture","68800","Veterinary, Breeding, Medicine","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agricultar"
"41200_agriculture","41200","Agricultural Program Payments","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"42500_agriculture","42500","Commodity Credit Loans","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"42800_agriculture","42800","Cooperative Distributions","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"42900_agriculture","42900","Crop Insurance Proceeds","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"43000_agriculture","43000","Crop Sales","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"43100_agriculture","43100","Custom Hire Income","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"43600_agriculture","43600","Farmers Market Sales","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"44100_agriculture","44100","Fuel Tax Credits and Other Inc.","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"45500_agriculture","45500","Livestock Sales","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"47400_agriculture","47400","Rental Income","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_agriculture"
"61100_agriculture","61100","Car and Truck Expenses","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"61500_agriculture","61500","Chemicals Purchased","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"61900_agriculture","61900","Conservation Expenses","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"62300_agriculture","62300","Custom Hire and Contract Labor","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"62900_agriculture","62900","Feed Purchased","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"63000_agriculture","63000","Fertilizers and Lime","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"63100_agriculture","63100","Freight and Trucking","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"63200_agriculture","63200","Gasoline, Fuel and Oil","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"67500_agriculture","67500","Seeds and Plants Purchased","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"67800_agriculture","67800","Small Tools and Equipment","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"67900_agriculture","67900","Storage and Warehousing","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"68500_agriculture","68500","Uniforms","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"68800_agriculture","68800","Veterinary, Breeding, Medicine","other","l10n_us.user_type_expense","expense","FALSE","l10n_us.account_chart_template_agriculture"
"24600_construction_trades","24600","Customer Deposits Received","other","l10n_us.user_type_other_current_liability","other_current_liability","FALSE","l10n_us.account_chart_template_construction"
"45100_construction_trades","45100","Job Income","other","l10n_us.user_type_income","income","FALSE","l10n_us.account_chart_template_construction"
"50800_construction_trades","50800","Commissions Paid","other","l10n_us.user_type_cogs","cost_of_goods_sold","FALSE","l10n_us.account_chart_template_construction"

1 id code name type user_type:id parent_id:id reconcile chart_template_id:id
69 51800_advertising 51800 Merchant Account Fees other l10n_us.user_type_cogs cost_of_goods_sold FALSE l10n_us.account_chart_template_advertising
70 53500_advertising 53500 Subcontracted Services other l10n_us.user_type_cogs cost_of_goods_sold FALSE l10n_us.account_chart_template_advertising
71 64200_advertising 64200 Marketing Expense other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_advertising
72 41200_agriculture 41200 Agricultural Program Payments other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
73 42500_agriculture 42500 Commodity Credit Loans other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
74 42800_agriculture 42800 Cooperative Distributions other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
75 42900_agriculture 42900 Crop Insurance Proceeds other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
76 43000_agriculture 43000 Crop Sales other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
77 43100_agriculture 43100 Custom Hire Income other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
78 43600_agriculture 43600 Farmers Market Sales other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
79 44100_agriculture 44100 Fuel Tax Credits and Other Inc. other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
80 45500_agriculture 45500 Livestock Sales other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
81 47400_agriculture 47400 Rental Income other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
82 61100_agriculture 61100 Car and Truck Expenses other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
83 61500_agriculture 61500 Chemicals Purchased other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
84 61900_agriculture 61900 Conservation Expenses other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
85 62300_agriculture 62300 Custom Hire and Contract Labor other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
86 62900_agriculture 62900 Feed Purchased other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
87 63000_agriculture 63000 Fertilizers and Lime other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
88 63100_agriculture 63100 Freight and Trucking other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
89 63200_agriculture 63200 Gasoline, Fuel and Oil other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
90 67500_agriculture 67500 Seeds and Plants Purchased other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
91 67800_agriculture 67800 Small Tools and Equipment other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
92 67900_agriculture 67900 Storage and Warehousing other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
93 68500_agriculture 68500 Uniforms other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
94 68800_agriculture 68800 Veterinary, Breeding, Medicine other l10n_us.user_type_expense expense FALSE l10n_us.account_chart_template_agricultar l10n_us.account_chart_template_agriculture
95 24600_construction_trades 24600 Customer Deposits Received other l10n_us.user_type_other_current_liability other_current_liability FALSE l10n_us.account_chart_template_construction
96 45100_construction_trades 45100 Job Income other l10n_us.user_type_income income FALSE l10n_us.account_chart_template_construction
97 50800_construction_trades 50800 Commissions Paid other l10n_us.user_type_cogs cost_of_goods_sold FALSE l10n_us.account_chart_template_construction

View File

@ -19,8 +19,8 @@
<field name="complete_tax_set" eval="False" />
<field name="parent_id" ref="account_chart_template_cogs"/>
</record>
<record id="account_chart_template_agricultar" model="account.chart.template">
<field name="name">Agricultar</field>
<record id="account_chart_template_agriculture" model="account.chart.template">
<field name="name">Agriculture</field>
<field name="complete_tax_set" eval="False" />
<field name="parent_id" ref="account_chart_template_basic"/>
</record>

View File

@ -11,7 +11,7 @@
<field name="bank_account_view_id" ref="cash_expenditure"/>
</record>
<record id="account_chart_template_agricultar" model="account.chart.template">
<record id="account_chart_template_agriculture" model="account.chart.template">
<field name="bank_account_view_id" ref="cash_expenditure"/>
</record>

View File

@ -8,31 +8,31 @@ 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: 2011-03-15 01:10+0000\n"
"Last-Translator: Emerson <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:27+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:40+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: lunch
#: view:lunch.cashbox.clean:0
msgid "Reset cashbox"
msgstr ""
msgstr "Reiniciar Caixa"
#. module: lunch
#: view:report.lunch.amount:0
msgid "Box amount in current year"
msgstr ""
msgstr "Valor do Caixa total no ano atual"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_lunch_order_form
#: model:ir.ui.menu,name:lunch.menu_lunch_order_form
#: model:ir.ui.menu,name:lunch.menu_lunch_reporting_order
msgid "Lunch Orders"
msgstr ""
msgstr "Pedidos de Almoço"
#. module: lunch
#: view:lunch.order.cancel:0
@ -43,7 +43,7 @@ msgstr "Tem certeza que deseja cancelar este pedido?"
#: model:ir.actions.act_window,name:lunch.action_lunch_cashmove_form
#: model:ir.ui.menu,name:lunch.menu_lunch_cashmove_form
msgid "Cash Moves"
msgstr ""
msgstr "Movimentações Financeiras"
#. module: lunch
#: view:lunch.cashmove:0 view:lunch.order:0 view:report.lunch.amount:0
@ -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 ""
"Você pode criar um caixa por funcionário se você deseja rastrear o valor "
"devido pelo funcionário de acordo com o que ele solicitou."
#. module: lunch
#: field:lunch.cashmove,amount:0 field:report.lunch.amount,amount:0
@ -111,7 +113,7 @@ msgstr "Produtos"
#. module: lunch
#: model:ir.model,name:lunch.model_report_lunch_amount
msgid "Amount available by user and box"
msgstr ""
msgstr "Valor disponível por usuário e caixa"
#. module: lunch
#: view:report.lunch.amount:0
@ -121,12 +123,12 @@ msgstr " Mês "
#. module: lunch
#: model:ir.model,name:lunch.model_report_lunch_order
msgid "Lunch Orders Statistics"
msgstr ""
msgstr "Estatísticas de Pedido de Almoço"
#. module: lunch
#: view:lunch.cashmove:0 field:lunch.order,cashmove:0
msgid "CashMove"
msgstr ""
msgstr "Movimentações de Caixa"
#. module: lunch
#: view:lunch.order:0 selection:lunch.order,state:0
@ -141,17 +143,17 @@ msgstr "Confirmar"
#. module: lunch
#: view:lunch.order:0
msgid "Search Lunch Order"
msgstr ""
msgstr "Procurar Pedido de Almoço"
#. module: lunch
#: field:lunch.order,state:0
msgid "State"
msgstr "Status"
msgstr "Situação"
#. module: lunch
#: selection:lunch.order,state:0
msgid "New"
msgstr ""
msgstr "Novo"
#. module: lunch
#: field:report.lunch.order,price_total:0
@ -161,7 +163,7 @@ msgstr "Preço Total"
#. module: lunch
#: view:report.lunch.amount:0
msgid "Box Amount by User"
msgstr ""
msgstr "Valor do Caixa por usuário"
#. module: lunch
#: field:lunch.cashmove,create_date:0
@ -181,7 +183,7 @@ msgstr "Descrição do Pedido"
#. module: lunch
#: view:report.lunch.amount:0
msgid "Box amount in last month"
msgstr ""
msgstr "Valor do Caixa no último mês"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_lunch_order_confirm
@ -218,7 +220,7 @@ msgstr "Data de Criação"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_lunch_category_form
msgid " Product Categories "
msgstr ""
msgstr " Categorias de Produto "
#. module: lunch
#: view:lunch.cashbox.clean:0
@ -228,12 +230,12 @@ msgstr "Definir como Zero"
#. module: lunch
#: model:ir.model,name:lunch.model_lunch_cashmove
msgid "Cash Move"
msgstr ""
msgstr "Movimentos do Caixa"
#. module: lunch
#: view:report.lunch.order:0
msgid "Tasks performed in last 365 days"
msgstr ""
msgstr "Tarefas realizadas nos últimos 365 dias"
#. module: lunch
#: selection:report.lunch.amount,month:0 selection:report.lunch.order,month:0
@ -259,7 +261,7 @@ msgstr "Mês"
#. module: lunch
#: field:lunch.order.confirm,confirm_cashbox:0
msgid "Name of box"
msgstr ""
msgstr "Nome do Caixa"
#. module: lunch
#: view:lunch.order.cancel:0
@ -291,12 +293,12 @@ msgstr "Não"
#. module: lunch
#: view:lunch.order.confirm:0
msgid "Orders Confirmation"
msgstr ""
msgstr "Confirmação dos Pedidos"
#. module: lunch
#: view:lunch.cashbox.clean:0
msgid "Are you sure you want to reset this cashbox ?"
msgstr ""
msgstr "Tem certeza de que quer reiniciar este caixa?"
#. module: lunch
#: model:ir.actions.act_window,help:lunch.view_lunch_product_form_installer
@ -306,6 +308,10 @@ msgid ""
"by supplier. It will be easier for the lunch manager to filter lunch orders "
"by categories."
msgstr ""
"Definir todos os produtos que os funcionários podem pedir para a hora do "
"almoço. Se encomendar o almoço em vários lugares, você pode usar as "
"categorias de produtos para dividir por fornecedor. Será mais fácil para o "
"gerente de almoço para filtrar almoço pedidos por categorias."
#. module: lunch
#: selection:report.lunch.amount,month:0 selection:report.lunch.order,month:0
@ -316,7 +322,7 @@ msgstr "Agosto"
#: model:ir.actions.act_window,name:lunch.action_report_lunch_order_all
#: view:report.lunch.order:0
msgid "Lunch Order Analysis"
msgstr ""
msgstr "Análise de Pedidos de Almoço"
#. module: lunch
#: selection:report.lunch.amount,month:0 selection:report.lunch.order,month:0
@ -337,7 +343,7 @@ msgstr "Análise de Vendas"
#. module: lunch
#: model:ir.ui.menu,name:lunch.menu_lunch_category_root_configuration
msgid "Lunch"
msgstr ""
msgstr "Almoço"
#. module: lunch
#: view:lunch.cashmove:0 view:report.lunch.order:0
@ -367,12 +373,12 @@ msgstr "Janeiro"
#. module: lunch
#: field:lunch.cashmove,box:0 field:report.lunch.amount,box:0
msgid "Box Name"
msgstr ""
msgstr "Nome do Caixa"
#. module: lunch
#: model:ir.model,name:lunch.model_lunch_cashbox_clean
msgid "clean cashbox"
msgstr ""
msgstr "Limpar caixa"
#. module: lunch
#: field:lunch.cashmove,active:0 field:lunch.product,active:0
@ -387,18 +393,18 @@ msgstr "Data do Pedido"
#. module: lunch
#: model:ir.model,name:lunch.model_lunch_cashbox
msgid "Cashbox for Lunch "
msgstr ""
msgstr "Caixa do Almoço "
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_lunch_cashbox_clean
#: model:ir.actions.act_window,name:lunch.action_lunch_cashbox_clean_values
msgid "Set CashBox to Zero"
msgstr ""
msgstr "Zerar Caixa"
#. module: lunch
#: view:lunch.product:0
msgid "General Information"
msgstr ""
msgstr "Informações Gerais"
#. module: lunch
#: view:lunch.order.confirm:0
@ -408,7 +414,7 @@ msgstr "Cancelar"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_lunch_cashbox_form
msgid " Cashboxes "
msgstr ""
msgstr " Caixas "
#. module: lunch
#: report:lunch.order:0
@ -439,27 +445,27 @@ msgstr "Preço"
#. module: lunch
#: view:lunch.cashmove:0
msgid "Search CashMove"
msgstr ""
msgstr "Procurar Movimento do Caixa"
#. module: lunch
#: view:report.lunch.amount:0
msgid "Total box"
msgstr ""
msgstr "Total do Caixa"
#. module: lunch
#: model:ir.model,name:lunch.model_lunch_product
msgid "Lunch Product"
msgstr ""
msgstr "Produto do Almoço"
#. module: lunch
#: field:lunch.cashbox,sum_remain:0
msgid "Total Remaining"
msgstr ""
msgstr "Total Restante"
#. module: lunch
#: view:lunch.order:0
msgid "Total price"
msgstr ""
msgstr "Preço Total"
#. module: lunch
#: selection:report.lunch.amount,month:0 selection:report.lunch.order,month:0
@ -480,17 +486,17 @@ msgstr "Valor total"
#. module: lunch
#: view:report.lunch.order:0
msgid "Tasks performed in last 30 days"
msgstr ""
msgstr "Tarefas realizadas nos últimos 30 dias"
#. module: lunch
#: view:lunch.category:0
msgid "Category Related to Products"
msgstr ""
msgstr "Categoria Relativa a Produtos"
#. module: lunch
#: model:ir.ui.menu,name:lunch.menu_lunch_cashbox_form view:lunch.cashbox:0
msgid "Cashboxes"
msgstr ""
msgstr "Caixa"
#. module: lunch
#: view:lunch.category:0 report:lunch.order:0 view:lunch.order:0
@ -502,28 +508,28 @@ msgstr "Pedido"
#: model:ir.model,name:lunch.model_lunch_order
#: model:ir.ui.menu,name:lunch.menu_lunch report:lunch.order:0
msgid "Lunch Order"
msgstr ""
msgstr "Pedido de Almoço"
#. module: lunch
#: view:report.lunch.amount:0
msgid "Box amount in current month"
msgstr ""
msgstr "Valor do Caixa este mês"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.view_lunch_product_form_installer
msgid "Define Your Lunch Products"
msgstr ""
msgstr "Definir seus produtos de almoço"
#. module: lunch
#: view:report.lunch.order:0
msgid "Tasks during last 7 days"
msgstr ""
msgstr "Tarefas durante os últimos 7 dias"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_report_lunch_amount_tree
#: model:ir.ui.menu,name:lunch.menu_lunch_report_amount_tree
msgid "Cash Position by User"
msgstr ""
msgstr "Caixa por usuário"
#. module: lunch
#: field:lunch.cashbox,manager:0
@ -538,18 +544,21 @@ msgstr " 30 Dias "
#. module: lunch
#: view:lunch.order:0
msgid "To Confirm"
msgstr ""
msgstr "Para Confirmar"
#. module: lunch
#: field:report.lunch.amount,year:0 view:report.lunch.order:0
#: field:report.lunch.order,year:0
msgid "Year"
msgstr ""
msgstr "Ano"
#. module: lunch
#: model:ir.actions.act_window,name:lunch.action_create_cashbox
msgid "Create Lunch Cash Boxes"
msgstr ""
msgstr "Criar Caixa de Almoço"
#~ msgid "Draft"
#~ msgstr "Provisório"
#~ msgid "Category related to Products"
#~ msgstr "Categorias relacionadas a Produtos"

View File

@ -8,20 +8,20 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-09 00:36+0000\n"
"PO-Revision-Date: 2011-01-17 18:39+0000\n"
"Last-Translator: Emerson <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:25+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:40+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: mail
#: field:mail.compose.message,subtype:0 field:mail.message,subtype:0
#: field:mail.message.common,subtype:0
msgid "Message Type"
msgstr ""
msgstr "Tipo de Mensagem"
#. module: mail
#: help:mail.compose.message,auto_delete:0
@ -80,7 +80,7 @@ msgstr "Destinatários da mensagem"
#: field:mail.compose.message,body_text:0 field:mail.message,body_text:0
#: field:mail.message.common,body_text:0
msgid "Text Contents"
msgstr ""
msgstr "Conteúdo do Texto"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
@ -196,7 +196,7 @@ msgstr "Destinatários"
#. module: mail
#: model:ir.model,name:mail.model_mail_compose_message
msgid "Email composition wizard"
msgstr ""
msgstr "Assistente para compor Email"
#. module: mail
#: field:mail.compose.message,res_id:0 field:mail.message,res_id:0
@ -219,7 +219,7 @@ msgstr "Re:"
#: field:mail.compose.message,model:0 field:mail.message,model:0
#: field:mail.message.common,model:0
msgid "Related Document Model"
msgstr ""
msgstr "Modelo de Documento Relacionado"
#. module: mail
#: view:mail.message:0
@ -287,7 +287,7 @@ msgstr "%(sender_name)s escreveu:"
#: field:mail.compose.message,body_html:0 field:mail.message,body_html:0
#: field:mail.message.common,body_html:0
msgid "Rich-text Contents"
msgstr ""
msgstr "Conteúdo Rich-text"
#. module: mail
#: field:mail.message,original:0
@ -360,7 +360,7 @@ msgstr "[OpenERP-Forward-Failed] %s"
#. module: mail
#: field:mail.message,user_id:0
msgid "Related User"
msgstr ""
msgstr "Usuário Relacionado"
#. module: mail
#: help:mail.compose.message,headers:0 help:mail.message,headers:0
@ -455,7 +455,7 @@ msgstr "Mensagens"
#: field:mail.compose.message,headers:0 field:mail.message,headers:0
#: field:mail.message.common,headers:0
msgid "Message Headers"
msgstr ""
msgstr "Cabeçalhos da Mensagem"
#. module: mail
#: field:mail.compose.message,email_bcc:0 field:mail.message,email_bcc:0

View File

@ -84,14 +84,20 @@ class mail_notification(osv.Model):
return False
def set_message_read(self, cr, uid, msg_ids, read=None, context=None):
if msg_ids == None:
return False
if type(msg_ids) is not list:
msg_ids=[msg_ids]
""" TDE note: add a comment, verify method calls, because js seems obfuscated. """
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
notif_ids = self.search(cr, uid, [('partner_id', '=', user_pid), ('message_id', 'in', msg_ids)], context=context)
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
notif_ids = self.search(cr, uid, [('partner_id', '=', partner_id), ('message_id', 'in', msg_ids)], context=context)
# all message have notifications: already set them as (un)read
if len(notif_ids) == len(msg_ids):
return self.write(cr, uid, notif_ids, {'read': read}, context=context)
# some messages do not have notifications: find which one, create notification, update read status
exist_notification = dict.fromkeys(msg_ids, False)
for notification in self.browse(cr, uid, notif_ids, context=context):
exist_notification[notification.message_id] = True
for msg_id in exist_notification.keys():
self.create(cr, uid, {'partner_id': user_pid, 'read': read, 'message_id': msg_id}, context=context)
return self.write(cr, uid, notif_ids, {'read': read}, context=context)
def get_partners_to_notify(self, cr, uid, message, context=None):

View File

@ -25,12 +25,13 @@ from osv import osv
from osv import fields
from openerp import SUPERUSER_ID
class mail_group(osv.Model):
""" A mail_group is a collection of users sharing messages in a discussion
group. The group mechanics are based on the followers. """
_description = 'Discussion group'
_name = 'mail.group'
_mail_autothread = False
_mail_flat_thread = False
_inherit = ['mail.thread']
_inherits = {'mail.alias': 'alias_id', 'ir.ui.menu': 'menu_id'}

View File

@ -57,19 +57,19 @@ class mail_message(osv.Model):
def _get_record_name(self, cr, uid, ids, name, arg, context=None):
""" Return the related document name, using get_name. """
result = dict.fromkeys(ids, '')
for message in self.browse(cr, uid, ids, context=context):
if not message.model or not message.res_id:
result = dict.fromkeys(ids, False)
for message in self.read(cr, uid, ids, ['model', 'res_id'], context=context):
if not message['model'] or not message['res_id']:
continue
try:
result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
result[message['id']] = self._shorten_name(self.pool.get(message['model']).name_get(cr, uid, [message['res_id']], context=context)[0][1])
except (orm.except_orm, osv.except_osv):
pass
return result
def _get_unread(self, cr, uid, ids, name, arg, context=None):
def _get_to_read(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
res = dict((id, {'unread': False}) for id in ids)
res = dict((id, {'to_read': False}) for id in ids)
partner_id = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
notif_obj = self.pool.get('mail.notification')
notif_ids = notif_obj.search(cr, uid, [
@ -78,11 +78,11 @@ class mail_message(osv.Model):
('read', '=', False)
], context=context)
for notif in notif_obj.browse(cr, uid, notif_ids, context=context):
res[notif.message_id.id]['unread'] = True
res[notif.message_id.id]['to_read'] = True
return res
def _search_unread(self, cr, uid, obj, name, domain, context=None):
""" Search for messages unread by the current user. Condition is
def _search_to_read(self, cr, uid, obj, name, domain, context=None):
""" Search for messages to read by the current user. Condition is
inversed because we search unread message on a read column. """
if domain[0][2]:
read_cond = '(read = false or read is null)'
@ -128,18 +128,17 @@ class mail_message(osv.Model):
'date': fields.datetime('Date'),
'message_id': fields.char('Message-Id', help='Message unique identifier', select=1, readonly=1),
'body': fields.html('Contents', help='Automatically sanitized HTML contents'),
'unread': fields.function(_get_unread, fnct_search=_search_unread,
type='boolean', string='Unread',
help='Functional field to search for unread messages linked to uid'),
'to_read': fields.function(_get_to_read, fnct_search=_search_to_read,
type='boolean', string='To read',
help='Functional field to search for messages the current user has to read'),
'subtype_id': fields.many2one('mail.message.subtype', 'Subtype'),
'vote_user_ids': fields.many2many('res.users', 'mail_vote', 'message_id', 'user_id', string='Votes',
help='Users that voted for this message'),
'is_private': fields.boolean('Private message'),
}
def _needaction_domain_get(self, cr, uid, context=None):
if self._needaction:
return [('unread', '=', True)]
return [('to_read', '=', True)]
return []
def _get_default_author(self, cr, uid, context=None):
@ -151,7 +150,6 @@ class mail_message(osv.Model):
'date': lambda *a: fields.datetime.now(),
'author_id': lambda self, cr, uid, ctx={}: self._get_default_author(cr, uid, ctx),
'body': '',
'is_private': True,
}
#------------------------------------------------------
@ -176,180 +174,197 @@ class mail_message(osv.Model):
# Message loading for web interface
#------------------------------------------------------
def _message_dict_get(self, cr, uid, msg, context=None):
""" Return a dict representation of the message browse record. A read
is performed to because of access rights issues (reading many2one
fields allow to have the foreign record name without having
to check external access rights).
def _message_get_dict(self, cr, uid, message, context=None):
""" Return a dict representation of the message.
:param dict message: read result of a mail.message
"""
has_voted = False
vote_ids = self.pool.get('res.users').name_get(cr, SUPERUSER_ID, [user.id for user in msg.vote_user_ids], context=context)
for vote in vote_ids:
if vote[0] == uid:
has_voted = True
break
if uid in message['vote_user_ids']:
has_voted = True
else:
has_voted = False
try:
attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)]
attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, message['attachment_ids'], context=context)]
except (orm.except_orm, osv.except_osv):
attachment_ids = []
try:
author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0]
is_author = uid == msg.author_id.user_ids[0].id
except Exception:
author_id = False
is_author = False
try:
partner_ids = self.pool.get('res.partner').name_get(cr, uid, [x.id for x in msg.partner_ids], context=context)
partner_ids = self.pool.get('res.partner').name_get(cr, uid, message['partner_ids'], context=context)
except (orm.except_orm, osv.except_osv):
partner_ids = []
return {
'id': msg.id,
'type': msg.type,
'id': message['id'],
'type': message['type'],
'attachment_ids': attachment_ids,
'body': msg.body,
'model': msg.model,
'res_id': msg.res_id,
'record_name': msg.record_name,
'subject': msg.subject,
'date': msg.date,
'author_id': author_id,
'is_author': is_author,
'body': message['body'],
'model': message['model'],
'res_id': message['res_id'],
'record_name': message['record_name'],
'subject': message['subject'],
'date': message['date'],
'author_id': message['author_id'],
'is_author': message['author_id'] and message['author_id'][0] == uid,
'partner_ids': partner_ids,
'parent_id': msg.parent_id and msg.parent_id.id or False,
'vote_user_ids': vote_ids,
'parent_id': message['parent_id'] and message['parent_id'][0] or False,
# TDE note: see with CHM about votes, how they are displayed (only number, or name_get ?)
# 'vote_user_ids': vote_ids,
'has_voted': has_voted,
'unread': msg.unread and msg.unread['unread'] or False
'to_read': message['to_read'],
}
def _message_read_expandable(self, cr, uid, tree, result, message_loaded, domain, context, parent_id, limit):
"""
create the expandable message for all parent message read
this function is used by message_read
"""
""" Create the expandable message for all parent message read
this function is used by message_read
TDE note: add default values for args, add some comments
tree_not = []
:param dict tree: tree of message ids
"""
tree_not = []
# expandable for not show message
for id_msg in tree:
for msg_id in tree:
# get all childs
not_loaded_ids = self.search(cr, SUPERUSER_ID, [['parent_id','=',id_msg],['id','not in',message_loaded]], None, limit=1000)
not_loaded_ids = self.search(cr, SUPERUSER_ID, [
('parent_id', '=', msg_id),
('id', 'not in', message_loaded)
], context=context, limit=1000)
# group childs not read
id_min=None
id_max=None
nb=0
id_min = None
id_max = None
nb = 0
for not_loaded_id in not_loaded_ids:
if not_loaded_id not in tree:
nb+=1
if id_min==None or id_min>not_loaded_id:
id_min=not_loaded_id
if id_max==None or id_max<not_loaded_id:
id_max=not_loaded_id
nb += 1
if id_min == None or id_min > not_loaded_id:
id_min = not_loaded_id
if id_max == None or id_max < not_loaded_id:
id_max = not_loaded_id
tree_not.append(not_loaded_id)
else:
if nb>0:
if nb > 0:
result.append({
'domain': [['id','>=',id_min],['id','<=',id_max],['parent_id','=',id_msg]],
'domain': [('id', '>=', id_min), ('id', '<=', id_max), ('parent_id', '=', msg_id)],
'nb_messages': nb,
'type': 'expandable',
'parent_id': id_msg,
'id': id_min
'type': 'expandable',
'parent_id': msg_id,
'id': id_min,
})
id_min=None
id_max=None
nb=0
if nb>0:
id_min = None
id_max = None
nb = 0
if nb > 0:
result.append({
'domain': [['id','>=',id_min],['id','<=',id_max],['parent_id','=',id_msg]],
'domain': [('id', '>=', id_min), ('id', '<=', id_max), ('parent_id', '=', msg_id)],
'nb_messages': nb,
'type': 'expandable',
'parent_id': id_msg,
'type': 'expandable',
'parent_id': msg_id,
'id': id_min
})
# expandable for limit max
ids = self.search(cr, SUPERUSER_ID, domain+[['id','not in',message_loaded+tree+tree_not]], context=context, limit=1)
ids = self.search(cr, SUPERUSER_ID, domain + [('id', 'not in', message_loaded + tree + tree_not)], context=context, limit=1)
if len(ids) > 0:
result.append(
{
result.append({
'domain': domain,
'nb_messages': 0,
'type': 'expandable',
'parent_id': parent_id,
'type': 'expandable',
'parent_id': parent_id,
'id': -1
});
})
result = sorted(result, key=lambda k: k['id'])
return result
def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, parent_id=False, limit=None):
_message_read_fields = ['id', 'parent_id', 'model', 'res_id', 'body', 'subject', 'date', 'to_read',
'type', 'vote_user_ids', 'attachment_ids', 'author_id', 'partner_ids', 'record_name']
def _get_parent(self, cr, uid, message, context=None):
""" Tools method that tries to get the parent of a mail.message. If
no parent, or if uid has no access right on the parent, False
is returned.
:param dict message: read result of a mail.message
"""
if not message['parent_id']:
return False
parent_id = message['parent_id'][0]
try:
return self.read(cr, uid, parent_id, self._message_read_fields, context=context)
except (orm.except_orm, osv.except_osv):
return False
def message_read(self, cr, uid, ids=False, domain=[], context=None, parent_id=False, limit=None):
""" Read messages from mail.message, and get back a structured tree
of messages to be displayed as discussion threads. If IDs is set,
fetch these records. Otherwise use the domain to fetch messages.
After having fetch messages, their parents will be added to obtain
well formed threads.
TDE note: update this comment after final method implementation
:param domain: optional domain for searching ids
:param limit: number of messages to fetch
:param parent_id: if parent_id reached, stop searching for
further parents
:return list: list of trees of messages
"""
message_loaded = context and context.get('message_loaded') or [0]
# don't read the message display by .js, in context message_loaded list
if context and context.get('message_loaded'):
domain += [ ['id','not in',message_loaded] ];
# TDE note: use an argument, do not use context
if context is None:
context = {}
if context.get('message_loaded'):
domain += [('id', 'not in', context.get('message_loaded'))]
limit = limit or self._message_read_limit
context = context or {}
tree = []
result = []
id_tree = []
message_list = []
record = None
# select ids
if ids and ids!=[None]:
for msg in self.browse(cr, uid, ids, context=context):
result.append(self._message_dict_get(cr, uid, msg, context=context))
return result
# TDE note: should not receive [None] -> investigate
if ids and ids != [None]:
for message in self.read(cr, uid, ids, self._message_read_fields, context=context):
message_list.append(self._message_get_dict(cr, uid, message, context=context))
return message_list
# key: ID, value: record
ids = self.search(cr, SUPERUSER_ID, domain, context=context, limit=limit)
for msg in self.browse(cr, uid, ids, context=context):
for message in self.read(cr, uid, ids, self._message_read_fields, context=context):
# if not in record and not in message_loded list
if msg.id not in tree and msg.id not in message_loaded :
record = self._message_dict_get(cr, uid, msg, context=context)
tree.append(msg.id)
result.append(record)
if message['id'] not in id_tree and message['id'] not in context.get('message_loaded', []):
record = self._message_get_dict(cr, uid, message, context=context)
id_tree.append(message['id'])
message_list.append(record)
while msg.parent_id and msg.parent_id.id != parent_id:
parent_id = msg.parent_id.id
if msg.parent_id.id not in tree:
msg = msg.parent_id
tree.append(msg.id)
parent = self._get_parent(cr, uid, message, context=context)
while parent and parent['id'] != parent_id:
if parent['id'] not in id_tree:
message = parent
id_tree.append(message['id'])
# if not in record and not in message_loded list
if msg.id not in message_loaded :
record = self._message_dict_get(cr, uid, msg, context=context)
result.append(record)
if message['id'] not in context.get('message_loaded', []):
record = self._message_get_dict(cr, uid, message, context=context)
message_list.append(record)
parent = self._get_parent(cr, uid, parent, context=context)
result = sorted(result, key=lambda k: k['id'])
message_list = sorted(message_list, key=lambda k: k['id'])
result = self._message_read_expandable(cr, uid, tree, result, message_loaded, domain, context, parent_id, limit)
message_list = self._message_read_expandable(cr, uid, id_tree, message_list, context.get('message_loaded', []), domain, context, parent_id, limit)
return result
return message_list
def user_free_attachment(self, cr, uid, context=None):
attachment_list = []
# TDE Note: do we need this ?
# def user_free_attachment(self, cr, uid, context=None):
# attachment_list = []
attachment = self.pool.get('ir.attachment')
attachment_ids = attachment.search(cr, uid, [('res_model','=',''),('create_uid','=',uid)])
if len(attachment_ids):
attachment_list = [{'id': attach.id, 'name': attach.name, 'date': attach.create_date} for attach in attachment.browse(cr, uid, attachment_ids, context=context)]
# attachment = self.pool.get('ir.attachment')
# attachment_ids = attachment.search(cr, uid, [('res_model','=',''),('create_uid','=',uid)])
# if len(attachment_ids):
# attachment_list = [{'id': attach.id, 'name': attach.name, 'date': attach.create_date} for attach in attachment.browse(cr, uid, attachment_ids, context=context)]
return attachment_list
# return attachment_list
#------------------------------------------------------
# Email api
@ -502,19 +517,17 @@ class mail_message(osv.Model):
missing_notified = missing_notified
if missing_notified:
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, p_id) for p_id in missing_notified]}, context=context)
partners_to_notify |= extra_notified
def _notify(self, cr, uid, newid, context=None):
""" Add the related record followers to the destination partner_ids if is not a private message.
Call mail_notification.notify to manage the email sending
"""
message = self.browse(cr, uid, newid, context=context)
if message and (message.is_private!=False and message.is_private!=None):
if message and message.model and message.res_id:
self._notify_followers(cr, uid, newid, message, context=context)
# add myself if I wrote on my wall,
# unless remove myself author
if ((message.model=="res.partner" and message.res_id==message.author_id.id)):
# add myself if I wrote on my wall, otherwise remove myself author
if ((message.model == "res.partner" and message.res_id == message.author_id.id)):
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, message.author_id.id)]}, context=context)
else:
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(3, message.author_id.id)]}, context=context)

View File

@ -57,8 +57,8 @@
<field name="type"/>
<field name="author_id"/>
<filter string="Unread"
name="unread_message" help="Show unread message"
domain="[('unread', '=', True)]"/>
name="messages_unread" help="Show messages to read"
domain="[('to_read', '=', True)]"/>
<filter string="Comments"
name="comments" help="Comments"
domain="[('type', '=', 'comment')]"/>
@ -78,7 +78,7 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_message_search"/>
<field name="context">{'search_default_unread_message':True}</field>
<field name="context">{'search_default_to_read_message':True}</field>
</record>
<!-- Add menu entry in Settings/Email -->
@ -87,22 +87,22 @@
<record id="action_mail_inbox_feeds" model="ir.actions.client">
<field name="name">Inbox</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]),('unread', '=', True)],
'context': {'default_model': 'res.partner'} }&quot;"/>
<field name="params" eval="&quot;{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]), ('to_read', '=', True)],
'context': {'default_model': 'res.users', 'default_res_id': uid} }&quot;"/>
</record>
<record id="action_mail_archives_feeds" model="ir.actions.client">
<field name="name">Archives</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]),('unread', '=', False)],
'context': {'default_model': 'res.partner'} }&quot;"/>
<field name="params" eval="&quot;{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]), ('to_read', '=', False)],
'context': {'default_model': 'res.users', 'default_res_id': uid} }&quot;"/>
</record>
<record id="action_mail_sent_feeds" model="ir.actions.client">
<field name="name">Sent</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('author_id.user_ids', 'in', [uid])],
'context': {'default_model': 'res.partner'} }&quot;"/>
'context': {'default_model': 'res.users', 'default_res_id': uid} }&quot;"/>
</record>
</data>
</openerp>

View File

@ -36,6 +36,7 @@ from tools.safe_eval import safe_eval as eval
_logger = logging.getLogger(__name__)
def decode_header(message, header, separator=' '):
return separator.join(map(decode, message.get_all(header, [])))
@ -57,10 +58,16 @@ class mail_thread(osv.AbstractModel):
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 when processing incoming emails.
Options:
- _mail_flat_thread: if set to True, all messages without parent_id
are automatically attached to the first message posted on the
ressource. If set to False, the display of Chatter is done using
threads, and no parent_id is automatically set.
'''
_name = 'mail.thread'
_description = 'Email Thread'
_mail_autothread = True
_mail_flat_thread = True
def _get_message_data(self, cr, uid, ids, name, args, context=None):
""" Computes:
@ -84,13 +91,12 @@ class mail_thread(osv.AbstractModel):
res[thread.id]['message_summary'] = "<span%s><span class='oe_e'>9</span> %d</span> <span><span class='oe_e'>+</span> %d</span>" % (cls, len(thread.message_comment_ids), len(thread.message_follower_ids))
return res
def _get_subscription_data(self, cr, uid, ids, name, args, context=None):
""" Computes:
- message_is_follower: is uid in the document followers
- message_subtype_data: data about document subtypes: which are
available, which are followed if any """
res = dict((id, dict(message_subtype_data='', message_is_follower=False)) for id in ids)
res = dict((id, dict(message_subtype_data='')) for id in ids)
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
# find current model subtypes, add them to a dictionary
@ -109,11 +115,10 @@ class mail_thread(osv.AbstractModel):
], context=context)
for fol in fol_obj.browse(cr, uid, fol_ids, context=context):
thread_subtype_dict = res[fol.res_id]['message_subtype_data']
res[fol.res_id]['message_is_follower'] = True
for subtype in fol.subtype_ids:
thread_subtype_dict[subtype.name]['followed'] = True
res[fol.res_id]['message_subtype_data'] = thread_subtype_dict
return res
def _search_unread(self, cr, uid, obj=None, name=None, domain=None, context=None):
@ -132,9 +137,12 @@ class mail_thread(osv.AbstractModel):
def _get_followers(self, cr, uid, ids, name, arg, context=None):
fol_obj = self.pool.get('mail.followers')
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids)])
res = dict((res_id, []) for res_id in ids)
res = dict((id, dict(message_follower_ids=[], message_is_follower=False)) for id in ids)
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
for fol in fol_obj.browse(cr, SUPERUSER_ID, fol_ids):
res[fol.res_id].append(fol.partner_id.id)
res[fol.res_id]['message_follower_ids'].append(fol.partner_id.id)
if fol.partner_id.id == user_pid:
res[fol.res_id]['message_is_follower'] = True
return res
def _set_followers(self, cr, uid, id, name, value, arg, context=None):
@ -188,15 +196,11 @@ class mail_thread(osv.AbstractModel):
return res
_columns = {
'message_is_follower': fields.function(_get_subscription_data,
type='boolean', string='Is a Follower', multi='_get_subscription_data,'),
'message_subtype_data': fields.function(_get_subscription_data,
type='text', string='Subscription data', multi="_get_subscription_data",
help="Holds data about the subtypes. The content of this field "\
"is a structure holding the current model subtypes, and the "\
"current document followed subtypes."),
'message_is_follower': fields.function(_get_followers,
type='boolean', string='Is a Follower', multi='_get_followers,'),
'message_follower_ids': fields.function(_get_followers, fnct_inv=_set_followers,
fnct_search=_search_followers, type='many2many', obj='res.partner', string='Followers'),
fnct_search=_search_followers, type='many2many',
obj='res.partner', string='Followers', multi='_get_followers'),
'message_comment_ids': fields.one2many('mail.message', 'res_id',
domain=lambda self: [('model', '=', self._name), ('type', 'in', ('comment', 'email'))],
string='Comments and emails',
@ -398,7 +402,8 @@ class mail_thread(osv.AbstractModel):
overrides the automatic detection based on the message
headers.
"""
if context is None: context = {}
if context is None:
context = {}
# extract message bytes - we are forced to pass the message as binary because
# we don't know its encoding until we parse its headers and hence can't
@ -414,7 +419,8 @@ class mail_thread(osv.AbstractModel):
thread_id, custom_values,
context=context)
msg = self.message_parse(cr, uid, msg_txt, save_original=save_original, context=context)
if strip_attachments: msg.pop('attachments', None)
if strip_attachments:
msg.pop('attachments', None)
thread_id = False
for model, thread_id, custom_values, user_id in routes:
if self._name != model:
@ -633,8 +639,10 @@ class mail_thread(osv.AbstractModel):
(isinstance(thread_id, (list, tuple)) and len(thread_id) == 1), "Invalid thread_id"
if isinstance(thread_id, (list, tuple)):
thread_id = thread_id and thread_id[0]
mail_message = self.pool.get('mail.message')
model = context.get('thread_model', self._name) if thread_id else False
attachment_ids=[]
attachment_ids = []
for name, content in attachments:
if isinstance(content, unicode):
content = content.encode('utf-8')
@ -648,24 +656,20 @@ class mail_thread(osv.AbstractModel):
}
attachment_ids.append((0, 0, data_attach))
# get subtype
if not subtype:
subtype = 'mail.mt_comment'
s = subtype.split('.')
if len(s)==1:
s = ('mail', s[0])
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, s[0], s[1])
subtype_id = ref and ref[1] or False
model = context.get('thread_model', self._name) if thread_id else False
messages = self.pool.get('mail.message')
#auto link messages for same id and object
if self._mail_autothread and thread_id:
message_ids = messages.search(cr, uid, ['&',('res_id', '=', thread_id),('model','=',model)], context=context)
if len(message_ids):
parent_id = min(message_ids)
# fetch subtype
if subtype:
s_data = subtype.split('.')
if len(s_data) == 1:
s_data = ('mail', s_data[0])
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, s_data[0], s_data[1])
subtype_id = ref and ref[1] or False
else:
subtype_id = False
# _mail_flat_thread: automatically set free messages to the first posted message
if self._mail_flat_thread and not parent_id and thread_id:
message_ids = mail_message.search(cr, uid, ['&', ('res_id', '=', thread_id), ('model', '=', model)], context=context, order="id ASC", limit=1)
parent_id = message_ids and message_ids[0] or False
values = kwargs
values.update({
@ -679,53 +683,47 @@ class mail_thread(osv.AbstractModel):
'subtype_id': subtype_id,
})
# if the parent is private, the message must be private
if parent_id:
msg = messages.browse(cr, uid, parent_id, context=context)
if msg.is_private:
values["is_private"] = msg.is_private
# Avoid warnings about non-existing fields
for x in ('from', 'to', 'cc'):
values.pop(x, None)
return messages.create(cr, uid, values, context=context)
return mail_message.create(cr, uid, values, context=context)
def message_post_api(self, cr, uid, thread_id, body='', subject=False, type='notification',
subtype=None, parent_id=False, attachments=None, context=None, **kwargs):
# TDE FIXME: body is plaintext: convert it into html
# when writing on res.partner, without specific thread_id -> redirect to the user's partner
if self._name == 'res.partner' and not thread_id:
thread_id = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
new_message_id = self.message_post(cr, uid, thread_id=thread_id, body=body, subject=subject, type=type,
subtype=subtype, parent_id=parent_id, context=context)
# Chatter: attachments linked to the document (not done JS-side), load the message
if attachments:
ir_attachment = self.pool.get('ir.attachment')
mail_message = self.pool.get('mail.message')
attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [('res_model', '=', False), ('res_id', '=', False), ('user_id', '=', uid), ('id', 'in', attachments)], context=context)
if attachment_ids:
ir_attachment.write(cr, SUPERUSER_ID, attachment_ids, {'res_model': self._name, 'res_id': thread_id}, context=context)
mail_message.write(cr, SUPERUSER_ID, [new_message_id], {'attachment_ids': [(6, 0, [pid for pid in attachment_ids])]}, context=context)
new_message = self.pool.get('mail.message').message_read(cr, uid, [new_message_id], context=context)
return new_message
#------------------------------------------------------
# Followers API
#------------------------------------------------------
def message_post_api(self, cr, uid, thread_id, body='', subject=False, type='notification',
subtype=None, parent_id=False, attachments=None, context=None, **kwargs):
# if the user write on his wall
if self._name=='res.partner' and not thread_id:
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
thread_id = user.partner_id.id
added_message_id = self.message_post(cr, uid, thread_id=thread_id, body=body, subject=subject, type=type,
subtype=subtype, parent_id=parent_id, context=context)
attachment_ids=[]
if attachments:
ir_attachment = self.pool.get('ir.attachment')
attachment_ids = ir_attachment.search(cr, 1, [('res_model', '=', ""), ('res_id', '=', ""), ('user_id', '=', uid), ('id', 'in', attachments)], context=context)
if attachment_ids:
self.pool.get('ir.attachment').write(cr, 1, attachment_ids, { 'res_model': self._name, 'res_id': thread_id }, context=context)
self.pool.get('mail.message').write(cr, 1, [added_message_id], {'attachment_ids': [(6, 0, [pid for pid in attachment_ids])]} )
added_message = self.pool.get('mail.message').message_read(cr, uid, [added_message_id])
return added_message
def get_message_subtypes(self, cr, uid, ids, context=None):
""" message_subtype_data: data about document subtypes: which are
available, which are followed if any """
def message_get_subscription_data(self, cr, uid, ids, context=None):
""" Wrapper to get subtypes. """
return self._get_subscription_data(cr, uid, ids, None, None, context=context)
def message_subscribe_users(self, cr, uid, ids, user_ids=None, subtype_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
provided, subscribe uid instead. """
if not user_ids:
return False
if user_ids is None:
user_ids = [uid]
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_subscribe(cr, uid, ids, partner_ids, subtype_ids=subtype_ids, context=context)
@ -738,14 +736,14 @@ class mail_thread(osv.AbstractModel):
subtype_ids = subtype_obj.search(cr, uid, [('default', '=', True), '|', ('res_model', '=', self._name), ('res_model', '=', False)], context=context)
# update the subscriptions
fol_obj = self.pool.get('mail.followers')
fol_ids = fol_obj.search(cr, 1, [('res_model', '=', self._name), ('res_id', 'in', ids), ('partner_id', 'in', partner_ids)], context=context)
fol_obj.write(cr, 1, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context)
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids), ('partner_id', 'in', partner_ids)], context=context)
fol_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context)
return True
def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
provided, unsubscribe uid instead. """
if not user_ids:
if user_ids is None:
user_ids = [uid]
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)

View File

@ -25,7 +25,7 @@ class res_partner_mail(osv.Model):
""" Update partner to add a field about notification preferences """
_name = "res.partner"
_inherit = ['res.partner', 'mail.thread']
_mail_autothread = False
_mail_flat_thread = False
_columns = {
'notification_email_send': fields.selection([

View File

@ -99,7 +99,8 @@ class res_users(osv.Model):
def write(self, cr, uid, ids, vals, context=None):
# User alias is sync'ed with login
if vals.get('login'): vals['alias_name'] = vals['login']
if vals.get('login'):
vals['alias_name'] = vals['login']
return super(res_users, self).write(cr, uid, ids, vals, context=context)
def unlink(self, cr, uid, ids, context=None):
@ -110,14 +111,20 @@ class res_users(osv.Model):
alias_pool.unlink(cr, uid, alias_ids, context=context)
return res
def message_post(self, cr, uid, thread_id, context=None, **kwargs):
def message_post_api(self, cr, uid, thread_id, body='', subject=False, type='notification',
subtype=None, parent_id=False, attachments=None, context=None, **kwargs):
""" Redirect the posting of message on res.users to the related partner.
This is done because when giving the context of Chatter on the
various mailboxes, we do not have access to the current partner_id.
We therefore post on the user and redirect on its partner. """
assert thread_id, "res.users does not support posting global messages"
if context and 'thread_model' in context:
context['thread_model'] = 'res.partner'
if isinstance(thread_id, (list, tuple)):
thread_id = thread_id[0]
partner_id = self.pool.get('res.users').browse(cr, uid, thread_id).partner_id.id
return self.pool.get('res.partner').message_post(cr, uid, partner_id, context=context, **kwargs)
partner_id = self.pool.get('res.users').read(cr, uid, thread_id, ['partner_id'], context=context)['partner_id'][0]
return self.pool.get('res.partner').message_post_api(cr, uid, partner_id, body=body, subject=subject,
type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, **kwargs)
def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
partner_id = self.pool.get('res.users').browse(cr, uid, ids)[0].partner_id.id

View File

@ -3,7 +3,7 @@ access_mail_message_all,mail.message.all,model_mail_message,,1,0,1,0
access_mail_message_group_user,mail.message.group.user,model_mail_message,base.group_user,1,1,1,1
access_mail_mail_all,mail.mail.all,model_mail_mail,,0,0,1,0
access_mail_mail_system,mail.mail.system,model_mail_mail,base.group_system,1,1,1,1
access_mail_followers_all,mail.followers.all,model_mail_followers,,0,0,0,0
access_mail_followers_all,mail.followers.all,model_mail_followers,,1,0,0,0
access_mail_followers_system,mail.followers.system,model_mail_followers,base.group_system,1,1,1,1
access_mail_notification_all,mail.notification.all,model_mail_notification,,1,0,0,0
access_mail_notification_aystem,mail.notification.system,model_mail_notification,base.group_system,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
3 access_mail_message_group_user mail.message.group.user model_mail_message base.group_user 1 1 1 1
4 access_mail_mail_all mail.mail.all model_mail_mail 0 0 1 0
5 access_mail_mail_system mail.mail.system model_mail_mail base.group_system 1 1 1 1
6 access_mail_followers_all mail.followers.all model_mail_followers 0 1 0 0 0
7 access_mail_followers_system mail.followers.system model_mail_followers base.group_system 1 1 1 1
8 access_mail_notification_all mail.notification.all model_mail_notification 1 0 0 0
9 access_mail_notification_aystem mail.notification.system model_mail_notification base.group_system 1 1 1 1

View File

@ -3,16 +3,23 @@
<data>
<!-- RULES -->
<record id="group_rule_public_and_joined" model="ir.rule">
<record id="mail_group_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"/>
<!-- This rule has to be improved for employee only groups -->
<field name="domain_force">['|', '|', ('public', '=', 'public'), ('message_follower_ids', 'in', [user.partner_id.id]), '&amp;', ('public','=','groups'), ('group_public_id','in', [g.id for g in user.groups_id])]</field>
</record>
<record id="mail_followers_read_own" model="ir.rule">
<field name="name">mail.followers: read its own entries</field>
<field name="model_id" ref="model_mail_followers"/>
<field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
<!--
This rule can not be uncommented, because we have a more wide method in mail.message. When we implement a many2one_variable field, we will be able to uncomment this.
<record id="mail_message_read_partner_or_author" model="ir.rule">
<field name="name">mail.message: read if notified or author</field>
<field name="model_id" ref="model_mail_message"/>

View File

@ -143,12 +143,12 @@
/* subtypes
/* ------------------------------------------------------------ */
.openerp .oe_mouse_subtypes {
.openerp .oe_mail_subtypes {
display:inline-block;
position: relative;
z-index: 5;
}
.openerp .oe_mouse_subtypes .oe_recthread_subtypes {
.openerp .oe_mail_subtypes .oe_recthread_subtypes {
background: #fff;
padding: 2px;
border: 1px solid #aaaaaa;
@ -156,10 +156,10 @@
position: absolute;
z-index: 2;
}
.openerp .oe_mouse_subtypes.oe_mouseout .oe_recthread_subtypes {
.openerp .oe_mail_subtypes.oe_mouseout .oe_recthread_subtypes {
display: none;
}
.openerp .oe_mouse_subtypes.oe_mouseover .oe_recthread_subtypes {
.openerp .oe_mail_subtypes.oe_mouseover .oe_recthread_subtypes {
display: block;
}

View File

@ -17,7 +17,7 @@ openerp.mail = function(session) {
*/
session.web.FormView = session.web.FormView.extend({
do_action: function(action, on_close) {
do_action: function(action) {
if (action.res_model == 'mail.compose.message') {
/* hack for stop context propagation of wrong value
@ -25,8 +25,8 @@ openerp.mail = function(session) {
*/
for(var key in action.context){
if( key!='default_template_id' &&
key!='default_composition_mode' &&
key!='default_use_template' &&
key!='default_is_private' &&
key!='default_model' &&
key!='default_res_id' &&
key!='default_subtype' &&
@ -44,7 +44,7 @@ openerp.mail = function(session) {
$('.openerp .oe_mail_wall_threads .oe_mail_thread button.oe_mail_wall_button_fetch').click();
}
return this._super(action, on_close);
return this._super.apply(this, arguments);
},
});
@ -131,7 +131,6 @@ openerp.mail = function(session) {
this.id = options.parameters.id;
this.model = options.parameters.model;
this.res_id = options.parameters.res_id;
this.is_private = options.parameters.is_private;
this.partner_ids = options.parameters.partner_ids;
this.options={thread:{}};
this.options.thread.show_header_compose = options.parameters.options.thread.show_header_compose;
@ -299,22 +298,23 @@ openerp.mail = function(session) {
/* to avoid having unsorted file on the server.
we will show the users files of the first message post
TDE note: unnecessary call to server I think
*/
set_free_attachments: function(){
var self=this;
this.parent_thread.ds_message.call('user_free_attachment').then(function(attachments){
this.attachment_ids=[];
for(var i in attachments){
self.attachment_ids[i]={
'id': attachments[i].id,
'name': attachments[i].name,
'filename': attachments[i].filename,
'url': mail.ChatterUtils.get_attachment_url(self.session, attachments[i])
};
}
self.display_attachments();
});
},
// set_free_attachments: function(){
// var self=this;
// this.parent_thread.ds_message.call('user_free_attachment').then(function(attachments){
// this.attachment_ids=[];
// for(var i in attachments){
// self.attachment_ids[i]={
// 'id': attachments[i].id,
// 'name': attachments[i].name,
// 'filename': attachments[i].filename,
// 'url': mail.ChatterUtils.get_attachment_url(self.session, attachments[i])
// };
// }
// self.display_attachments();
// });
// },
bind_events: function() {
var self = this;
@ -340,13 +340,12 @@ openerp.mail = function(session) {
views: [[false, 'form']],
target: 'new',
context: {
'default_res_model': this.context.default_res_model,
'default_res_id': this.context.default_res_id,
'default_model': false,
'default_res_id': 0,
'default_content_subtype': 'html',
'default_is_private': true,
'default_parent_id': this.id,
'default_body': mail.ChatterUtils.get_text2html(this.$('textarea').val() || ''),
'default_attachment_ids': attachments
'default_attachment_ids': attachments,
},
};
this.do_action(action);
@ -387,7 +386,7 @@ openerp.mail = function(session) {
mail.ChatterUtils.get_text2html(body),
false,
'comment',
false,
'mail.mt_comment',,
this.context.default_parent_id,
attachments]
).then(this.parent_thread.proxy('switch_new_message'));
@ -520,7 +519,7 @@ openerp.mail = function(session) {
this.vote_user_ids = param.vote_user_ids || [];
this.unread = param.unread || false;
this.to_read = param.to_read || false;
this._date = param.date;
this.author_id = param.author_id || [];
this.attachment_ids = param.attachment_ids || [];
@ -680,10 +679,10 @@ openerp.mail = function(session) {
var ids = [this.id].concat( this.get_child_ids() );
if($(event.srcElement).hasClass("oe_read")) {
this.ds_notification.call('set_message_read', [ids,true]);
this.ds_notification.call('set_message_read', [ids, true]);
this.$el.removeClass("oe_mail_unread").addClass("oe_mail_read");
} else {
this.ds_notification.call('set_message_read', [ids,false]);
this.ds_notification.call('set_message_read', [ids, false]);
this.$el.removeClass("oe_mail_read").addClass("oe_mail_unread");
}
return false;
@ -830,7 +829,6 @@ openerp.mail = function(session) {
this.id= param.id || false;
this.model= param.model || false;
this.parent_id= param.parent_id || false;
this.is_private = param.is_private || false;
this.author_id = param.author_id || false;
this.partner_ids = [];
for(var i in param.partner_ids){
@ -866,7 +864,7 @@ openerp.mail = function(session) {
return display_done && compose_done;
},
instantiate_ComposeMessage: function(){
instantiate_ComposeMessage: function() {
// add message composition form view
this.ComposeMessage = new mail.ThreadComposeMessage(this,{
'context': this.context,
@ -1014,7 +1012,7 @@ openerp.mail = function(session) {
fetch_context = replace_context ? replace_context : this.context;
fetch_context.message_loaded= [this.id||0].concat( self.options.thread._parents[0].get_child_ids() );
return this.ds_message.call('message_read', [ids, fetch_domain, fetch_context, 0, this.context.default_parent_id || undefined]
return this.ds_message.call('message_read', [ids, fetch_domain, fetch_context, this.context.default_parent_id || undefined]
).then(this.proxy('switch_new_message'));
},
@ -1155,14 +1153,7 @@ openerp.mail = function(session) {
_check_visibility: function() {
this.$el.toggle(this.view.get("actual_mode") !== "create");
},
/**
* Reinitialize the widget field and Display the threads
* @param {Object} new_context: context of the refresh
*/
set_value: function() {
var self = this;
this._super.apply(this, arguments);
render_value: function() {
if (! this.view.datarecord.id || session.web.BufferedDataSet.virtual_id_regex.test(this.view.datarecord.id)) {
this.$('oe_mail_thread').hide();
return;
@ -1174,6 +1165,7 @@ openerp.mail = function(session) {
// update domain
var domain = this.options.domain.concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]);
// create and render Thread widget
// TDE note: replace message_is_follower by a check in message_follower_ids, as message_is_follower is not used in views anymore
var show_header_compose = this.view.is_action_enabled('edit') ||
(this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value());
@ -1250,7 +1242,7 @@ openerp.mail = function(session) {
var self = this;
this.searchview = new session.web.SearchView(this, this.ds_msg, false, defaults || {}, hidden || false);
return this.searchview.appendTo(this.$('.oe_view_manager_view_search')).then(function () {
self.searchview.on_search.add(self.do_searchview_search);
self.searchview.on('search_data', self, self.do_searchview_search);
});
},

View File

@ -26,12 +26,11 @@ openerp_mail_followers = function(session, mail) {
this._super.apply(this, arguments);
this.options.image = this.node.attrs.image || 'image_small';
this.options.title = this.node.attrs.title || 'Followers';
this.options.context = this.node.attrs.context;
this.options.comment = this.node.attrs.help || false;
this.options.displayed_nb = this.node.attrs.displayed_nb || 10;
this.ds_model = new session.web.DataSetSearch(this, this.view.model);
this.sub_model = new session.web.DataSetSearch(this,'mail.message.subtype');
this.ds_follow = new session.web.DataSetSearch(this, this.field.relation);
this.follower_model = new session.web.DataSetSearch(this,'mail.followers');
this.ds_users = new session.web.DataSetSearch(this, 'res.users');
},
start: function() {
@ -40,7 +39,6 @@ openerp_mail_followers = function(session, mail) {
this._check_visibility();
this.reinit();
this.bind_events();
this.display_subtypes();
},
_check_visibility: function() {
@ -54,17 +52,17 @@ openerp_mail_followers = function(session, mail) {
bind_events: function() {
var self = this;
this.$('button.oe_follower')
.on('click', function () {
if($(this).hasClass('oe_notfollow'))
self.do_follow();
else
self.do_unfollow();
});
this.$el.on('click', 'ul.oe_subtypes input', self.do_update_subscription );
this.$el.on('click', 'button.oe_invite', function(event) {
// event: click on '(Un)Follow' button, that toggles the follow for uid
this.$('.oe_follower').on('click', function (event) {
if($(this).hasClass('oe_notfollow'))
self.do_follow();
else
self.do_unfollow();
});
// event: click on a subtype, that (un)subscribe for this subtype
this.$el.on('click', 'ul.oe_subtypes input', self.do_update_subscription);
// event: click on 'invite' button, that opens the invite wizard
this.$('.oe_invite').on('click', function (event) {
action = {
type: 'ir.actions.act_window',
res_model: 'mail.wizard.invite',
@ -77,69 +75,90 @@ openerp_mail_followers = function(session, mail) {
'default_res_id': self.view.datarecord.id
},
}
self.do_action(action, function() { self.read_value(); });
self.do_action(action, {
on_close: function() {
self.read_value();
},
});
});
},
read_value: function() {
read_value: function () {
var self = this;
return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).pipe(function (results) {
self.set_value(results[0].message_follower_ids);
});
},
set_value: function(value_) {
this.reinit();
return this.fetch_followers(value_ || this.get_value());
set_value: function (value_) {
this._super(value_);
// TDE FIXME: render_value is never called... ask to niv
this.render_value();
},
set_is_follower: function(value_) {
for(var i in value_){
if(value_[i]['user_ids'][0]==this.session.uid)
this.message_is_follower=true;
this.display_buttons();
return true;
}
this.message_is_follower=false;
this.display_buttons();
return false;
render_value: function () {
this.reinit();
return this.fetch_followers(this.get("value"));
},
fetch_followers: function (value_) {
this.value = value_ || {};
this.message_is_follower = (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value());
if(value_)
return this.ds_follow.call('read', [this.value, ['name', 'user_ids']]).pipe(this.proxy('display_followers'), this.proxy('display_generic'));
return this.ds_follow.call('read', [this.value, ['name', 'user_ids']])
.pipe(this.proxy('display_followers'), this.proxy('fetch_generic'))
.pipe(this.proxy('display_buttons'))
.pipe(this.proxy('fetch_subtypes'));
},
/** Read on res.partner failed: fall back on a generic case
- fetch current user partner_id (call because no other smart solution currently) FIXME
- then display a generic message about followers */
fetch_generic: function (error, event) {
var self = this;
event.preventDefault();
return this.ds_users.call('read', [this.session.uid, ['partner_id']]).pipe(function (results) {
var pid = results['partner_id'][0];
self.message_is_follower = (_.indexOf(self.get('value'), pid) != -1);
}).pipe(self.proxy('display_generic'));
},
/* Display generic info about follower, for people not having access to res_partner */
display_generic: function (error, event) {
event.preventDefault();
display_generic: function () {
var self = this;
var node_user_list = this.$('ul.oe_mail_followers_display').empty();
// format content: Followers (You and 0 other) // Followers (3)
var content = this.options.title;
if (this.message_is_follower) {
content += ' (You and ' + (this.value.length-1) + ' other)';
content += ' (You and ' + (this.get('value').length-1) + ' other)';
}
else {
content += ' (' + this.value.length + ')'
content += ' (' + this.get('value').length + ')'
}
this.$('div.oe_mail_recthread_followers h4').html(content);
this.display_buttons();
return $.when();
},
/** Display the followers, evaluate is_follower directly */
/** Display the followers */
display_followers: function (records) {
var self = this;
records = records || [];
this.message_is_follower = this.set_is_follower(records);
// clean and display title
var node_user_list = this.$('ul.oe_mail_followers_display').empty();
this.$('div.oe_mail_recthread_followers h4').html(this.options.title + (records.length>=5 ? ' (' + records.length + ')' : '') );
for(var i=0; i<records.length&&i<5; i++) {
var record=records[i];
this.$('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')');
// truncate number of displayed followers
truncated = records.splice(0, this.options.displayed_nb);
_(truncated).each(function (record) {
record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id);
$(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list);
});
if (truncated.length < records.length) {
$('<li>And ' + (records.length - truncated.length) + ' more.</li>').appendTo(node_user_list);
}
self.set_is_follower(records);
},
/** Computes whether the current user is in the followers */
set_is_follower: function (records) {
var user_ids = _.pluck(_.pluck(records, 'user_ids'), 0);
return _.indexOf(user_ids, this.session.uid) != -1;
},
display_buttons: function () {
@ -149,15 +168,25 @@ openerp_mail_followers = function(session, mail) {
else {
this.$('button.oe_follower').removeClass('oe_following').addClass('oe_notfollow');
}
if (this.view.is_action_enabled('edit'))
this.$('span.oe_mail_invite_wrapper').hide();
else
this.$('span.oe_mail_invite_wrapper').show();
},
set_subtypes:function(data){
/** Fetch subtypes, only if current user is follower */
fetch_subtypes: function () {
var subtype_list_ul = this.$('.oe_subtypes').empty();
if (! this.message_is_follower) return;
var context = new session.web.CompoundContext(this.build_context(), {});
this.ds_model.call('message_get_subscription_data', [[this.view.datarecord.id], context]).pipe(this.proxy('display_subtypes'));
},
/** Display subtypes: {'name': default, followed} */
display_subtypes:function (data) {
var self = this;
var subtype_list_ul = this.$('.oe_subtypes');
var records = (data[this.view.datarecord.id] || data[null]).message_subtype_data;
_(records).each(function (record, record_name) {
@ -167,27 +196,15 @@ openerp_mail_followers = function(session, mail) {
});
},
/** Display subtypes: {'name': default, followed} */
display_subtypes: function (visible) {
var self = this;
var recthread_subtypes = self.$('.oe_recthread_subtypes');
subtype_list_ul = self.$('ul.oe_subtypes');
if(subtype_list_ul.is(":empty")) {
var context = new session.web.CompoundContext(this.build_context(), {});
this.ds_model.call('get_message_subtypes',[[self.view.datarecord.id], context]).pipe(this.proxy('set_subtypes'));
}
},
do_follow: function () {
_(this.$('.oe_msg_subtype_check')).each(function(record){
$(record).attr('checked','checked');
_(this.$('.oe_msg_subtype_check')).each(function (record) {
$(record).attr('checked', 'checked');
});
this.do_update_subscription();
},
do_unfollow: function () {
_(this.$('.oe_msg_subtype_check')).each(function(record){
_(this.$('.oe_msg_subtype_check')).each(function (record) {
$(record).attr('checked',false);
});
var context = new session.web.CompoundContext(this.build_context(), {});
@ -198,22 +215,15 @@ openerp_mail_followers = function(session, mail) {
var self = this;
var checklist = new Array();
_(this.$('.oe_mail_recthread_actions input[type="checkbox"]')).each(function(record){
if($(record).is(':checked')) {
checklist.push(parseInt($(record).data('id')))}
_(this.$('.oe_mail_recthread_actions input[type="checkbox"]')).each(function (record) {
if ($(record).is(':checked')) {
checklist.push(parseInt($(record).data('id')));
}
});
if(!checklist.length)
return this.do_unfollow();
else{
var context = new session.web.CompoundContext(this.build_context(), {});
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], undefined, context]).pipe(function(value_){
self.read_value(value_);
self.display_subtypes(true);
});
}
var context = new session.web.CompoundContext(this.build_context(), {});
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], this.message_is_follower ? checklist:undefined, context])
.pipe(this.proxy('read_value'));
},
});
};
};

View File

@ -42,7 +42,7 @@
<t t-call="HiddenInputFile">
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
<t t-set="fileupload_action">/web/binary/upload_attachment</t>
<input type="hidden" name="model" value=""/>
<input type="hidden" name="model" value="mail.message"/>
<input type="hidden" name="id" value="0"/>
<input type="hidden" name="session_id" t-att-value="widget.session.session_id"/>
</t>
@ -95,8 +95,8 @@
<t t-name="mail.thread.list_recipients">
<div class="oe_mail_list_recipients">
Post to:
<span t-if="!widget.is_private" class="oe_all_follower">All Followers</span>
<t t-if="!widget.is_private and widget.partner_ids.length"> and </t>
<span t-if="widget.context.default_res_id and widget.context.default_res_id" class="oe_all_follower">All Followers</span>
<t t-if="!widget.context.default_res_id and widget.context.default_res_id and widget.partner_ids.length"> and </t>
<t t-set="inc" t-value="0"/>
<t t-if="widget.partner_ids.length" t-foreach="widget.partner_ids" t-as="partner"><span t-attf-class="oe_partner_follower #{inc>=3?'oe_hidden':''}"><t t-if="inc" t-raw="', '"/><a t-attf-href="#model=res.partner&amp;id=#{partner[0]}"><t t-raw="partner[1]"/></a></span><t t-set="inc" t-value="inc+1"/>
</t>
@ -186,7 +186,7 @@
</div>
<!-- default layout -->
<li t-name="mail.thread.message" t-attf-class="oe_mail oe_mail_thread_msg #{widget.unread?'oe_mail_unread':'oe_mail_read'}">
<li t-name="mail.thread.message" t-attf-class="oe_mail oe_mail_thread_msg #{widget.to_read ?'oe_mail_unread':'oe_mail_read'}">
<div t-attf-class="oe_mail_msg_#{widget.type} oe_semantic_html_override">
<!-- message actions (read/unread, reply, delete...) -->
<ul class="oe_header">

View File

@ -7,7 +7,7 @@
-->
<div t-name="mail.followers" class="oe_mail_recthread_aside oe_semantic_html_override">
<div class="oe_mail_recthread_actions">
<div class="oe_mouse_subtypes">
<div class="oe_mail_subtypes">
<button type="button" class="oe_follower oe_notfollow">
<span class="oe_follow">Follow</span>
<span class="oe_unfollow">Unfollow</span>
@ -18,11 +18,9 @@
<ul class="oe_subtypes"></ul>
</div>
</div>
<div class="oe_grey">
<t t-if="widget.options.comment">
<h5><t t-raw="widget.options.comment"/></h5>
</t>
</div>
<t t-if="widget.options.comment">
<h5 class="oe_grey"><t t-raw="widget.options.comment"/></h5>
</t>
<div class="oe_mail_recthread_followers">
<button type="button" class="oe_invite"><span>Invite</span></button>
<t t-if="widget.options.title">

View File

@ -135,7 +135,9 @@ class test_mail(TestMailMockups):
self.res_users = self.registry('res.users')
self.res_partner = self.registry('res.partner')
self.user_demo = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1]
# Test users
self.user_demo_id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1]
self.user_admin = self.res_users.browse(self.cr, self.uid, self.uid)
# Mock send_get_mail_body to test its functionality without other addons override
self._send_get_mail_body = self.registry('mail.mail').send_get_mail_body
@ -148,6 +150,7 @@ class test_mail(TestMailMockups):
# create a 'pigs' group that will be used through the various tests
self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
self.group_pigs = self.mail_group.browse(self.cr, self.uid, self.group_pigs_id)
def tearDown(self):
# Remove mocks
@ -155,6 +158,7 @@ class test_mail(TestMailMockups):
super(test_mail, self).tearDown()
def test_00_message_process(self):
""" Testing incoming emails processing. """
cr, uid = self.cr, self.uid
# Incoming mail creates a new mail_group "frogs"
self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', 'frogs')]), [])
@ -193,18 +197,15 @@ class test_mail(TestMailMockups):
self.assertEqual(new_mail.body, '\n<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>\n',
'plaintext mail incorrectly parsed')
def test_10_many2many_reference_field(self):
def test_10_followers_function_field(self):
""" Tests designed for the many2many function field 'follower_ids'.
We will test to perform writes using the many2many commands 0, 3, 4,
5 and 6. """
cr, uid = self.cr, self.uid
user_admin = self.res_users.browse(cr, uid, uid)
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
# Create partner Bert Poilu
# Data: create partner Bert Poilu
partner_bert_id = self.res_partner.create(cr, uid, {'name': 'Bert Poilu'})
# Create 'disturbing' values in mail.followers: same res_id, other res_model; same res_model, other res_id
# Data: create 'disturbing' values in mail.followers: same res_id, other res_model; same res_model, other res_id
group_dummy_id = self.mail_group.create(cr, uid,
{'name': 'Dummy group'})
self.mail_followers.create(cr, uid,
@ -257,9 +258,7 @@ class test_mail(TestMailMockups):
def test_11_message_followers_and_subtypes(self):
""" Tests designed for the subscriber API as well as message subtypes """
cr, uid = self.cr, self.uid
user_admin = self.res_users.browse(cr, uid, uid)
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
# Data: user Raoul
user_raoul_id = self.res_users.create(cr, uid, {'name': 'Raoul Grosbedon', 'login': 'raoul'})
user_raoul = self.res_users.browse(cr, uid, user_raoul_id)
@ -281,7 +280,6 @@ class test_mail(TestMailMockups):
group_pigs.refresh()
# Test: 2 followers (Admin and Raoul)
follower_ids = [follower.id for follower in group_pigs.message_follower_ids]
self.assertEqual(len(follower_ids), 2, 'There should be 2 Pigs fans')
self.assertEqual(set(follower_ids), set([user_raoul.partner_id.id, user_admin.partner_id.id]), 'Admin and Raoul should be the only 2 Pigs fans')
# Test: Raoul follows default subtypes
fol_ids = self.mail_followers.search(cr, uid, [('res_model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id), ('partner_id', '=', user_raoul.partner_id.id)])
@ -307,19 +305,16 @@ class test_mail(TestMailMockups):
# CASE2: test mail_thread fields
# ----------------------------------------
group_pigs.refresh()
self.assertEqual(set(group_pigs.message_subtype_data.keys()), set(['comment', 'mt_mg_def', 'mt_all_def', 'mt_mg_nodef', 'mt_all_nodef']), 'mail.group available subtypes incorrect')
self.assertFalse(group_pigs.message_subtype_data['comment']['followed'], 'Admin should not follow comments in pigs')
self.assertTrue(group_pigs.message_subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs')
self.assertTrue(group_pigs.message_subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs')
subtype_data = group_pigs._get_subscription_data(None, None)[group_pigs.id]['message_subtype_data']
self.assertEqual(set(subtype_data.keys()), set(['comment', 'mt_mg_def', 'mt_all_def', 'mt_mg_nodef', 'mt_all_nodef']), 'mail.group available subtypes incorrect')
self.assertFalse(subtype_data['comment']['followed'], 'Admin should not follow comments in pigs')
self.assertTrue(subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs')
self.assertTrue(subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs')
def test_20_message_post(self):
""" Tests designed for message_post. """
cr, uid = self.cr, self.uid
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
user_admin = self.res_users.browse(cr, uid, uid)
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
# 2 - Carine Poilvache, with email, should never receive emails
@ -345,11 +340,12 @@ class test_mail(TestMailMockups):
# CASE1: post comment, body and subject specified
# ----------------------------------------
# 1. Post a new comment on Pigs
self._init_mock_build_email()
msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment', subtype='mt_comment')
message = self.mail_message.browse(cr, uid, msg_id)
sent_emails = self._build_email_kwargs_list
# Test: notifications have been deleted
# Test: mail.mail notifications have been deleted
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id)]), 'mail.mail notifications should have been auto-deleted!')
# Test: mail_message: subject is _subject, body is _body1 (no formatting done)
self.assertEqual(message.subject, _subject, 'mail.message subject incorrect')
@ -377,19 +373,18 @@ class test_mail(TestMailMockups):
# CASE2: post an email with attachments, parent_id, partner_ids
# ----------------------------------------
# TESTS: automatic subject, signature in body_html, attachments propagation
# 1. Post a new email comment on Pigs
self._init_mock_build_email()
msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email', subtype='mt_comment',
partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments)
message = self.mail_message.browse(cr, uid, msg_id2)
sent_emails = self._build_email_kwargs_list
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id2)]), 'mail.mail notifications should have been auto-deleted!')
# Test: mail_message: subject is False, body is _body2 (no formatting done), parent_id is msg_id
self.assertEqual(message.subject, False, 'mail.message subject incorrect')
self.assertEqual(message.body, html_sanitize(_body2), 'mail.message body incorrect')
self.assertEqual(message.parent_id.id, msg_id, 'mail.message parent_id incorrect')
# Test: sent_email: email send by server: correct subject, body, body_alternative
# Test: sent_email: email send by server: correct automatic subject, body, body_alternative
self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
for sent_email in sent_emails:
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
@ -413,13 +408,11 @@ class test_mail(TestMailMockups):
self.assertIn((attach.name, attach.datas.decode('base64')), _attachments,
'mail.message attachment name / data incorrect')
def test_21_message_compose_wizard(self):
def test_25_message_compose_wizard(self):
""" Tests designed for the mail.compose.message wizard. """
cr, uid = self.cr, self.uid
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
mail_compose = self.registry('mail.compose.message')
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
user_admin = self.res_users.browse(cr, uid, uid)
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
group_bird_id = self.mail_group.create(cr, uid, {'name': 'Bird', 'description': 'Bird resistance'})
group_bird = self.mail_group.browse(cr, uid, group_bird_id)
@ -434,7 +427,6 @@ class test_mail(TestMailMockups):
]
_attachments_test = [('first.txt', 'My first attachment'), ('second.txt', 'My second attachment')]
# Create partners
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
# 2 - Carine Poilvache, with email, should never receive emails
@ -470,7 +462,6 @@ class test_mail(TestMailMockups):
msg_pids = [partner.id for partner in message.partner_ids]
test_pids = [p_b_id, p_c_id, p_d_id]
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
self.assertEqual(len(notif_ids), 3, 'mail.message: too much notifications created')
self.assertEqual(set(msg_pids), set(test_pids), 'mail.message partner_ids incorrect')
@ -505,7 +496,7 @@ class test_mail(TestMailMockups):
# 1. mass_mail on pigs and bird
compose_id = mail_compose.create(cr, uid,
{'subject': _subject, 'body': '${object.description}', 'content_type': 'html'},
{'subject': _subject, 'body': '${object.description}', 'content_subtype': 'html'},
{'default_composition_mode': 'mass_mail', 'default_model': 'mail.group', 'default_res_id': False,
'active_ids': [self.group_pigs_id, group_bird_id]})
compose = mail_compose.browse(cr, uid, compose_id)
@ -531,12 +522,13 @@ class test_mail(TestMailMockups):
def test_40_needaction(self):
""" Tests for mail.message needaction. """
cr, uid = self.cr, self.uid
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
group_pigs_demo = self.mail_group.browse(cr, self.user_demo, self.group_pigs_id)
user_admin = self.res_users.browse(cr, uid, uid)
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
user_demo = self.res_users.browse(cr, uid, self.user_demo_id)
group_pigs_demo = self.mail_group.browse(cr, self.user_demo_id, self.group_pigs_id)
na_admin_base = self.mail_message._needaction_count(cr, uid, domain=[])
na_demo_base = self.mail_message._needaction_count(cr, user_demo.id, domain=[])
# Demo values: check unread notification = needaction on mail.message
# Test: number of unread notification = needaction on mail.message
notif_ids = self.mail_notification.search(cr, uid, [
('partner_id', '=', user_admin.partner_id.id),
('read', '=', False)
@ -544,36 +536,32 @@ class test_mail(TestMailMockups):
na_count = self.mail_message._needaction_count(cr, uid, domain=[])
self.assertEqual(len(notif_ids), na_count, 'unread notifications count does not match needaction count')
na_count1 = self.mail_message._needaction_count(cr, uid, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
# Post 2 message on group_pigs as admin, 3 messages as demo user
# Do: post 2 message on group_pigs as admin, 3 messages as demo user
for dummy in range(2):
group_pigs.message_post(body='My Body', subtype='mt_comment')
for dummy in range(3):
group_pigs_demo.message_post(body='My Demo Body', subtype='mt_comment')
# Check there are 4 new needaction on mail.message
# Test: admin has 3 new notifications (from demo), and 3 new needaction
notif_ids = self.mail_notification.search(cr, uid, [
('partner_id', '=', user_admin.partner_id.id),
('read', '=', False)
])
na_count = self.mail_message._needaction_count(cr, uid, domain=[])
self.assertEqual(len(notif_ids), na_count, 'unread notifications count does not match needaction count')
# Check there are 4 needaction on mail.message with particular domain
na_count = self.mail_message._needaction_count(cr, uid, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
self.assertEqual(len(notif_ids), na_admin_base + 3, 'Admin should have 3 new unread notifications')
na_admin = self.mail_message._needaction_count(cr, uid, domain=[])
na_admin_group = self.mail_message._needaction_count(cr, uid, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
self.assertEqual(na_admin, na_admin_base + 3, 'Admin should have 3 new needaction')
self.assertEqual(na_admin_group, 3, 'Admin should have 3 needaction related to Pigs')
# Test: demo has 0 new notifications (not a follower, not receiving its own messages), and 0 new needaction
notif_ids = self.mail_notification.search(cr, uid, [
('partner_id', '=', user_admin.partner_id.id),
('read', '=', False),
('message_id.model','=','mail.group'),
('message_id.res_id','=',self.group_pigs_id)
('partner_id', '=', user_demo.partner_id.id),
('read', '=', False)
])
self.assertEqual(len(notif_ids), na_count, 'posted message count does not match needaction count')
na_count3 = self.mail_message._needaction_count(cr, self.user_demo, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
self.assertEqual(na_count3-na_count1, 0, 'demo has 0 message: not a follower and do not follow his own messages')
na_count2 = self.mail_message._needaction_count(cr, uid, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
self.assertEqual(na_count2-na_count1, 3, 'admin has 3 messages: 0 from itself as they are marked as read, 3 from demo')
self.assertEqual(len(notif_ids), na_demo_base + 0, 'Demo should have 0 new unread notifications')
na_demo = self.mail_message._needaction_count(cr, user_demo.id, domain=[])
na_demo_group = self.mail_message._needaction_count(cr, user_demo.id, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
self.assertEqual(na_demo, na_demo_base + 0, 'Demo should have 0 new needaction')
self.assertEqual(na_demo_group, 0, 'Demo should have 0 needaction related to Pigs')
def test_50_thread_parent_resolution(self):
"""Verify parent/child relationships are correctly established when processing incoming mails"""

View File

@ -102,53 +102,69 @@ class test_mail_access_rights(test_mail.TestMailMockups):
""" Test mail_message search override about access rights. """
self.assertTrue(1 == 1, 'Test not implemented, do not replace by return True')
# def test_10_mail_flow_access_rights(self):
# """ Test a Chatter-looks alike flow. """
# cr, uid = self.cr, self.uid
# partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
# user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
def test_10_mail_flow_access_rights(self):
""" Test a Chatter-looks alike flow. """
cr, uid = self.cr, self.uid
mail_compose = self.registry('mail.compose.message')
partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
# # Prepare groups: Pigs (employee), Jobs (public)
# self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
# self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
# Prepare groups: Pigs (employee), Jobs (public)
self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
# # ----------------------------------------
# # CASE1: Bert, without groups
# # ----------------------------------------
# # Do: Bert creates a group, should crash because perm_create only for employees
# self.assertRaises(except_orm,
# self.mail_group.create,
# cr, user_bert_id, {'name': 'Bert\'s Group'})
# # Do: Bert reads Jobs basic fields, ok because public = read access on the group
# self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['name', 'description'])
# # Do: Bert browse Pigs, ok (no direct browse of partners)
# self.mail_group.browse(cr, user_bert_id, self.group_jobs_id)
# # Do: Bert reads Jobs messages, ok because read access on the group => read access on its messages
# jobs_message_ids = self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['message_ids'])['message_ids']
# self.mail_message.read(cr, user_bert_id, jobs_message_ids)
# # Do: Bert reads Jobs followers, ko because partner are accessible to employees or partner manager
# jobs_followers_ids = self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['message_follower_ids'])['message_follower_ids']
# self.assertRaises(except_orm,
# self.res_partner.read,
# cr, user_bert_id, jobs_followers_ids)
# # Do: Bert comments Jobs, ko because no write access on the group and not in the followers
# self.assertRaises(except_orm,
# self.mail_group.message_post,
# cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
# # Do: add Bert to jobs followers
# self.mail_group.message_subscribe(cr, uid, [self.group_jobs_id], [partner_bert_id])
# # Do: Bert comments Jobs, ok because he is now in the followers
# self.mail_group.message_post(cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
# ----------------------------------------
# CASE1: Bert, without groups
# ----------------------------------------
# Do: Bert creates a group, should crash because perm_create only for employees
self.assertRaises(except_orm,
self.mail_group.create,
cr, user_bert_id, {'name': 'Bert\'s Group'})
# # Do: Bert reads Pigs, should crash because mail.group security=groups only for employee group
# self.assertRaises(except_orm,
# self.mail_group.read,
# cr, user_bert_id, self.group_pigs_id)
# Do: Bert reads Jobs basic fields, ok because public = read access on the group
self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['name', 'description'])
# Do: Bert browse Pigs, ok (no direct browse of partners)
self.mail_group.browse(cr, user_bert_id, self.group_jobs_id)
# Do: Bert reads Jobs messages, ok because read access on the group => read access on its messages
jobs_message_ids = self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['message_ids'])['message_ids']
self.mail_message.read(cr, user_bert_id, jobs_message_ids)
# Do: Bert reads Jobs followers, ko because partner are accessible to employees or partner manager
jobs_followers_ids = self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['message_follower_ids'])['message_follower_ids']
self.assertRaises(except_orm,
self.res_partner.read,
cr, user_bert_id, jobs_followers_ids)
# Do: Bert comments Jobs, ko because no write access on the group and not in the followers
self.assertRaises(except_orm,
self.mail_group.message_post,
cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
# Do: add Bert to jobs followers
self.mail_group.message_subscribe(cr, uid, [self.group_jobs_id], [partner_bert_id])
# Do: Bert comments Jobs, ok because he is now in the followers
self.mail_group.message_post(cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
# # ----------------------------------------
# # CASE1: Raoul, employee
# # ----------------------------------------
# # Do: Bert read Pigs, ok because public
# self.mail_group.read(cr, user_raoul_id, self.group_pigs_id)
# # Do: Bert read Jobs, ok because group_public_id = employee
# self.mail_group.read(cr, user_raoul_id, self.group_jobs_id)
# Do: Bert reads Pigs, should crash because mail.group security=groups only for employee group
self.assertRaises(except_orm,
self.mail_group.read,
cr, user_bert_id, self.group_pigs_id)
# Do: Bert create a mail.compose.message record, because he uses the wizard
compose_id = mail_compose.create(cr, user_bert_id,
{'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': []},
# {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': [(4, p_c_id), (4, p_d_id)]},
{'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id})
mail_compose.send_mail(cr, user_bert_id, [compose_id])
self.user_demo_id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1]
compose_id = mail_compose.create(cr, self.user_demo_id,
{'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': []},
# {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': [(4, p_c_id), (4, p_d_id)]},
{'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id})
mail_compose.send_mail(cr, self.user_demo_id, [compose_id])
# ----------------------------------------
# CASE2: Raoul, employee
# ----------------------------------------
# Do: Bert read Pigs, ok because public
self.mail_group.read(cr, user_raoul_id, self.group_pigs_id)
# Do: Bert read Jobs, ok because group_public_id = employee
self.mail_group.read(cr, user_raoul_id, self.group_jobs_id)

View File

@ -41,6 +41,8 @@ def get_sys_logs(cr, uid):
nbr_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True)], count=True)
nbr_active_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True), ("date", ">=", limit_date_str)], count=True)
user = pool.get("res.users").browse(cr, uid, uid)
web_base_url = safe_eval(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', 'False'))
msg = {
"dbuuid": dbuuid,
"nbr_users": nbr_users,
@ -51,6 +53,7 @@ def get_sys_logs(cr, uid):
"db_create_date": db_create_date,
"version": release.version,
"language": user.lang,
"web_base_url": web_base_url,
}
msg.update(pool.get("res.company").read(cr,uid,[1],["name","email","phone"])[0])

View File

@ -81,11 +81,7 @@ class mail_compose_message(osv.TransientModel):
elif composition_mode == 'comment' and model and res_id:
vals = self.get_record_data(cr, uid, model, res_id, context=context)
elif composition_mode == 'mass_mail' and model and active_ids:
if context.get('default_template_id'):
vals = self.pool.get('email.template').generate_email(cr, uid, context.get('default_template_id'), res_id, context=context)
vals.update({'content_subtype': 'html'})
else:
vals = {'model': model, 'res_id': res_id, 'content_subtype': 'html'}
vals = {'model': model, 'res_id': res_id, 'content_subtype': 'html'}
else:
vals = {'model': model, 'res_id': res_id}
if composition_mode:
@ -229,22 +225,13 @@ class mail_compose_message(osv.TransientModel):
mass_mail_mode = wizard.composition_mode == 'mass_mail'
active_model_pool = self.pool.get(wizard.model if wizard.model else 'mail.thread')
if wizard.content_subtype == 'html':
if not wizard.body:
return False
body = wizard.body
else: # wizard.content_subtype == 'plain':
if not wizard.body_text:
return False
body = '<pre>%s</pre>' % tools.ustr(wizard.body_text or '')
# wizard works in batch mode: [res_id] or active_ids
res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id]
for res_id in res_ids:
# default values, according to the wizard options
post_values = {
'subject': wizard.subject if wizard.content_subtype == 'html' else False,
'body': body,
'body': wizard.body if wizard.content_subtype == 'html' else '<pre>%s</pre>' % tools.ustr(wizard.body_text),
'parent_id': wizard.parent_id and wizard.parent_id.id,
'partner_ids': [(4, partner.id) for partner in wizard.partner_ids],
'attachments': [(attach.datas_fname or attach.name, base64.b64decode(attach.datas)) for attach in wizard.attachment_ids],
@ -258,13 +245,13 @@ class mail_compose_message(osv.TransientModel):
post_values['attachments'] += new_attachments
post_values.update(email_dict)
# post the message
id=active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype='mt_comment', context=context, **post_values)
active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype='mt_comment', context=context, **post_values)
# post process: update attachments, because id is not necessarily known when adding attachments in Chatter
# self.pool.get('ir.attachment').write(cr, uid, [attach.id for attach in wizard.attachment_ids], {
# 'res_id': wizard.id, 'res_model': wizard.model or False}, context=context)
return {'type': 'ir.actions.act_window_close', 'res_model':'mail.compose.message', 'id': id}
return {'type': 'ir.actions.act_window_close'}
def render_message(self, cr, uid, wizard, res_id, context=None):
""" Generate an email from the template for given (wizard.model, res_id)

View File

@ -6,17 +6,19 @@
<field name="model">mail.compose.message</field>
<field name="arch" type="xml">
<form string="Compose Email" version="7.0">
<field name="composition_mode" nolabel="1" invisible="1"/>
<field name="model" nolabel="1" invisible="1"/>
<field name="res_id" nolabel="1" invisible="1"/>
<field name="parent_id" nolabel="1" invisible="1"/>
<field name="content_subtype" nolabel="1" invisible="1"/>
<!-- truly invisible fields for control and options -->
<field name="composition_mode" nolabel="1" invisible="0"/>
<field name="model" nolabel="1" invisible="0"/>
<field name="res_id" nolabel="1" invisible="0"/>
<field name="parent_id" nolabel="1" invisible="0"/>
<field name="content_subtype" nolabel="1" invisible="0"/>
<!-- visible wizard -->
<group>
<field name="subject" placeholder="Subject..."/>
<field name="subject" placeholder="Subject..."
attrs="{'invisible':[('content_subtype', '=', 'plain')]}"/>/>
<field name="partner_ids" widget="many2many_tags" placeholder="Add contacts to notify..."
context="{'force_email':True}"
on_change="onchange_partner_ids(partner_ids)"/>
<field name="is_private" help="If this message is not private, this message will send to all your followers or all followers of the parented message."/>
</group>
<notebook>
<page string="Body">
@ -30,68 +32,11 @@
<button string="Send" name="send_mail" type="object" class="oe_highlight" />
or
<button string="Cancel" class="oe_link" special="cancel" />
<!--div class="oe_right">
<button string="" name="toggle_content_subtype" type="object" icon="/mail/static/src/img/formatting.png"
help="Toggle advanced formatting mode"/>
</div-->
</footer>
</form>
</field>
</record>
<record model="ir.ui.view" id="email_compose_message_wizard_form_chatter">
<field name="name">mail.compose.message.form.chatter</field>
<field name="model">mail.compose.message</field>
<field name="priority">18</field>
<field name="arch" type="xml">
<form string="Compose Email" version="7.0" >
<group>
<!-- truly invisible fields for control and options -->
<field name="composition_mode" colspan="2" nolabel="1" invisible="1"/>
<field name="model" colspan="2" nolabel="1" invisible="1"/>
<field name="res_id" colspan="2" nolabel="1" invisible="1"/>
<field name="parent_id" colspan="2" nolabel="1" invisible="1"/>
<field name="content_subtype" colspan="2" nolabel="1" invisible="1"/>
<!-- visible wizard -->
<field name="subject" colspan="2" nolabel="1" placeholder="Subject..."
class="oe_mail_compose_message_subject"
attrs="{'invisible':[('content_subtype', '=', 'plain')]}"/>
<field name="body_text" colspan="2" nolabel="1" placeholder="What are you working on ?"
class="oe_mail_compose_message_body"
attrs="{'invisible':[('content_subtype', '=', 'html')]}"/>
<field name="body" colspan="2" nolabel="1" placeholder="What are you working on ?"
class="oe_mail_compose_message_body_html"
attrs="{'invisible':[('content_subtype', '=', 'plain')]}"/>
<field name="partner_ids" colspan="2" nolabel="1" widget="many2many_tags" placeholder="Add contacts to notify..."
context="{'force_email':True}"
on_change="onchange_partner_ids(partner_ids)"
class="oe_mail_compose_message_partner_ids"/>
<!--field name="is_private" help="If this message is not private, this message will send to all your followers or all followers of the parented message."/-->
<field name="attachment_ids" colspan="2" nolabel="1" widget="many2many_tags"
placeholder="Add attachments..." invisible="1"
class="oe_mail_compose_message_attachment_ids"/>
<!-- void div to display attachments, Chatter-controlled -->
<div colspan="2" class="oe_mail_compose_message_attachments"/>
<!-- buttons, with as few Chatter logic as possible -->
<div>
<button name="send_mail" string="Post message" type="object"
class="oe_mail_compose_message_button_send"/>
</div>
<div class='oe_mail_compose_message_icons'>
<button icon="/mail/static/src/img/attachment.png"
class="oe_mail_compose_message_attachment" string=""
name="dummy"
help="Add an attachment"/>
<button icon="/mail/static/src/img/formatting.png"
class="oe_mail_compose_message_formatting" string=""
type="object" name="toggle_content_subtype"
help="Toggle advanced formatting mode"/>
</div>
</group>
</form>
</field>
</record>
<record id="action_email_compose_message_wizard" model="ir.actions.act_window">
<field name="name">Compose Email</field>
<field name="res_model">mail.compose.message</field>

View File

@ -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: 2012-05-10 18:03+0000\n"
"Last-Translator: Adriano Prado <adrianojprado@hotmail.com>\n"
"PO-Revision-Date: 2012-10-17 00:28+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 06:29+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:40+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@ -35,6 +35,15 @@ msgid ""
"* The 'Done' state is set when repairing is completed. \n"
"* The 'Cancelled' state is used when user cancel repair order."
msgstr ""
" * 'Provisória' é usada quando um usuário está preparando uma nova ordem de "
"reparo não confirmada.\n"
"* 'Confirmada' é usado quando o usuário confirma a ordem de reparo.\n"
"* 'Pronto para Reparo\" é usado para iniciar o reparo, o usuário pode "
"começar a reparar somente após a confirmação da ordem de reparo.\n"
"* 'Faturar' é usado para gerar a fatura antes ou após o reparo feito.\n"
"* 'Concluído' é definido quando o reparo finalizar.\n"
"* O 'Cancelado' estado é usado quando o usuário cancelar a ordem de "
"reparação."
#. module: mrp_repair
#: field:mrp.repair.line,move_id:0
@ -179,7 +188,7 @@ msgstr "Atenção !"
#. module: mrp_repair
#: report:repair.order:0
msgid "Tax"
msgstr ""
msgstr "Imposto"
#. module: mrp_repair
#: view:mrp.repair:0
@ -312,6 +321,12 @@ msgid ""
" \n"
"* The 'Cancelled' state is set automatically when user cancel repair order."
msgstr ""
" * 'Provisório' é definido automaticamente, quando a ordem de reparo está em "
"situação provisória.\n"
"* 'Confirmado' é definido automaticamente quando a ordem for confirmada.\n"
"* 'Concluído' é definido automaticamente quando o reparo estiver concluído.\n"
"* 'Cancelado' é definido automaticamente quando o usuário cancelar a ordem "
"de reparos."
#. module: mrp_repair
#: report:repair.order:0

View File

@ -4,16 +4,13 @@ openerp.pad = function(instance) {
template: 'FieldPad',
configured: false,
content: "",
set_value: function(val) {
render_value: function() {
var self = this;
var _super = self._super;
_super.apply(self,[val]);
if (val === false || val === "") {
self.field_manager.dataset.call('pad_generate_url',{context:{
model: self.field_manager.model,
if (this.get("value") === false || this.get("value") === "") {
self.view.dataset.call('pad_generate_url',{context:{
model: self.view.model,
field_name: self.name,
object_id: self.field_manager.datarecord.id
object_id: self.view.datarecord.id
}}).then(function(data) {
if(data&&data.url){
_super.apply(self,[data.url]);

View File

@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2009-11-09 18:58+0000\n"
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
"PO-Revision-Date: 2012-10-16 23:09+0000\n"
"Last-Translator: BlueSeptin <Unknown>\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-08-28 06:03+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:39+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: point_of_sale
#: field:report.transaction.pos,product_nb:0
msgid "Product Nb."
msgstr ""
msgstr "Catatan"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_trans_pos_tree_today
@ -37,11 +37,17 @@ msgid ""
"new payment methods directly from menu \"PoS Backend > Configuration > "
"Payment Methods\"."
msgstr ""
"Anda harus menentukan metode pembayaran yang digunakan pada pint of sale "
"berdasarkan bank dan cash yang terdapat pada \"Acconting > Konfigurasi > "
"Financial Akunting > Journals\". Pilih salah satu journal dan centang pada "
"field \"PoS Payment Method\" dari tab \"Point of Sale\". Anda juga bisa "
"langsung membuat Metode Pembayaran secara langsung dari menu \"Pos Backend > "
"Konfigurasi > Payment Methods\""
#. module: point_of_sale
#: view:pos.order:0 view:report.pos.order:0
msgid "Today"
msgstr "Hari Ini"
msgstr "Hari ini"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.plain_water
@ -51,12 +57,12 @@ msgstr ""
#. module: point_of_sale
#: view:report.cash.register:0
msgid "Year from Creation date of cash register"
msgstr ""
msgstr "Tahun dari Tanggal Pembuatan Cash Register"
#. module: point_of_sale
#: view:pos.confirm:0
msgid "Post All Orders"
msgstr ""
msgstr "Posting Semua Transaksi"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.spa_2l_product_template
@ -89,12 +95,12 @@ msgstr "Hari"
#. module: point_of_sale
#: view:pos.make.payment:0
msgid "Add payment :"
msgstr ""
msgstr "Masukkan Pembayaran"
#. module: point_of_sale
#: field:pos.box.out,name:0
msgid "Description / Reason"
msgstr ""
msgstr "Keterangan"
#. module: point_of_sale
#: field:report.sales.by.margin.pos,product_name:0
@ -105,7 +111,7 @@ msgstr "Nama Produk"
#. module: point_of_sale
#: view:report.cash.register:0
msgid "Month from Creation date of cash register"
msgstr ""
msgstr "Bulan dari Tanggal Terbentuknya Cash Register"
#. module: point_of_sale
#: report:account.statement:0 field:pos.box.entries,amount:0
@ -121,12 +127,14 @@ msgid ""
"Configuration error! The currency chosen should be shared by the default "
"accounts too."
msgstr ""
"Konfigurasi salah ! Mata uang yang dipilih harus sama dengan mata uang pada "
"akun"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.pos_category_action
#: model:ir.ui.menu,name:point_of_sale.menu_pos_category view:pos.category:0
msgid "PoS Categories"
msgstr ""
msgstr "Kategori PoS"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_box_out
@ -161,6 +169,8 @@ msgid ""
"You do not have any open cash register. You must create a payment method or "
"open a cash register."
msgstr ""
"Anda tidak memiliki satupun Cash Register yang terbuka. Anda seharusnya "
"membuat Metode Pembayaran atau Open Cash Register terlebih dahulu"
#. module: point_of_sale
#: report:account.statement:0 field:report.pos.order,partner_id:0
@ -180,7 +190,7 @@ msgstr "Harga Rata-rata"
#. module: point_of_sale
#: report:pos.lines:0
msgid "Disc. (%)"
msgstr ""
msgstr "Diskon"
#. module: point_of_sale
#: model:ir.ui.menu,name:point_of_sale.menu_point_open_config

File diff suppressed because it is too large Load Diff

View File

@ -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 01:37+0100\n"
"PO-Revision-Date: 2011-07-23 01:46+0000\n"
"Last-Translator: Raphael Collet (OpenERP) <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:01+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 06:04+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:39+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: point_of_sale
#: field:report.transaction.pos,product_nb:0
@ -304,7 +304,7 @@ msgstr "Vendas Mensais por Usuário"
#. module: point_of_sale
#: report:all.closed.cashbox.of.the.day:0
msgid "Today's Closed Cashbox"
msgstr ""
msgstr "Fechamento de Caixa do dia"
#. module: point_of_sale
#: view:report.cash.register:0
@ -916,7 +916,7 @@ msgstr "Linhas da Ordem de Venda"
#. module: point_of_sale
#: view:pos.receipt:0
msgid "Receipt :"
msgstr ""
msgstr "Recibo"
#. module: point_of_sale
#: field:account.bank.statement.line,pos_statement_id:0
@ -1177,7 +1177,7 @@ msgstr ""
#: report:pos.payment.report.user:0 report:pos.sales.user:0
#: report:pos.sales.user.today:0 report:pos.user.product:0
msgid "Print Date"
msgstr ""
msgstr "Data de Impressão"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:282
@ -2323,7 +2323,7 @@ msgstr "PRO-FORMA"
#: code:addons/point_of_sale/point_of_sale.py:358
#, python-format
msgid "Please provide a partner for the sale."
msgstr ""
msgstr "Por favor informe um parceiro para a venda"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.fruity_beers
@ -2422,7 +2422,7 @@ msgstr "Reembolso"
#: code:addons/point_of_sale/report/pos_invoice.py:46
#, python-format
msgid "Please create an invoice for this sale."
msgstr ""
msgstr "Por favor crie uma fatura para esta venda."
#. module: point_of_sale
#: model:product.template,name:point_of_sale.oetker_mozzarella_product_template

View File

@ -897,7 +897,7 @@
width: 100%;
height: 100%;
margin: 0;
margin-right: 18px
margin-right: 18px;
font-family: "Inconsolata";
color: #6c6c6c;
text-shadow: 0px 3px 3px rgba(0,0,0, 0.2);

View File

@ -44,7 +44,7 @@ a.cta-a strong {
background-color:#FFF;
}
.process_canvas svg{
height:500px;!important;
height:500px;
padding:15px;
}
.oe_process {

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: pt_BR\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-02-20 19:37+0000\n"
"Last-Translator: Rafael Sales - http://www.tompast.com.br <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:02+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: <pt@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-09-21 04:42+0000\n"
"X-Generator: Launchpad (build 15985)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:39+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: project
#: view:report.project.task.user:0
@ -663,7 +663,7 @@ msgstr "Horas Restantes"
#. module: project
#: model:ir.model,name:project.model_mail_compose_message
msgid "Email composition wizard"
msgstr ""
msgstr "Assistente de composição de Email"
#. module: project
#: view:report.project.task.user:0
@ -1332,7 +1332,7 @@ msgstr ""
#. module: project
#: view:project.task:0
msgid "Delegation"
msgstr ""
msgstr "Delegar Responsabilidade"
#. module: project
#: model:ir.model,name:project.model_res_users

View File

@ -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:37+0000\n"
"PO-Revision-Date: 2012-02-20 19:35+0000\n"
"Last-Translator: Rafael Sales - http://www.tompast.com.br <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:36+0000\n"
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:39+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:41+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: project_long_term
#: model:ir.actions.act_window,name:project_long_term.act_project_phases
@ -62,7 +62,7 @@ msgstr "Fases em Progresso"
#. module: project_long_term
#: view:project.phase:0
msgid "Displaying Settings"
msgstr ""
msgstr "Exibindo Configurações"
#. module: project_long_term
#: field:project.compute.phases,target_project:0

View File

@ -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 01:37+0100\n"
"PO-Revision-Date: 2012-03-20 14:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"PO-Revision-Date: 2012-10-16 16:24+0000\n"
"Last-Translator: Vladimirs Kuzmins <Unknown>\n"
"Language-Team: Latvian <lv@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-09-07 04:56+0000\n"
"X-Generator: Launchpad (build 15914)\n"
"X-Launchpad-Export-Date: 2012-10-17 04:35+0000\n"
"X-Generator: Launchpad (build 16152)\n"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_confirmingpurchaseorder0
@ -1297,7 +1297,7 @@ msgstr ""
#. module: purchase
#: view:purchase.order:0
msgid "Not Invoiced"
msgstr ""
msgstr "Nav Izrakstīts Rēķins"
#. module: purchase
#: report:purchase.order:0 field:purchase.order.line,price_unit:0

View File

@ -294,8 +294,8 @@
<field name="model">sale.order</field>
<field name="res_id" ref="sale_order_2"/>
<field name="body">Hi,
I have a confusion for pricing of Services, I have heard there is a discount above 25 hours.
Can you clarify please?</field>
I have a question regarding services pricing: I heard of a possible discount for quantities exceeding 25 hours.
Could you confirm, please?</field>
<field name="type">comment</field>
<field name="author_id" ref="base.partner_demo"/>
</record>
@ -305,10 +305,9 @@ Can you clarify please?</field>
<field name="res_id" ref="sale_order_2"/>
<field name="parent_id" ref="message_sale_1"/>
<field name="body">Hello,
Sorry but that scheme is not available for now,
We would like to know if you confirm the quotation with pricing we sent to you.
Thanks,
Sales Department</field>
Unfortunately that was a temporary discount that is not available anymore.
Do you still plan to confirm the order based on the quoted prices?
Thanks!</field>
<field name="type">comment</field>
<field name="author_id" ref="base.partner_root"/>
</record>
@ -317,7 +316,7 @@ Sales Department</field>
<field name="model">sale.order</field>
<field name="res_id" ref="sale_order_2"/>
<field name="parent_id" ref="message_sale_2"/>
<field name="body">Ok, fine, we will intimate you after discussing with our team.</field>
<field name="body">Alright, thanks for the clarification. I will confirm the order as soon as I get my manager's approval.</field>
<field name="type">comment</field>
<field name="author_id" ref="base.partner_demo"/>
</record>

File diff suppressed because it is too large Load Diff

View File

@ -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:37+0000\n"
"PO-Revision-Date: 2012-05-10 18:26+0000\n"
"Last-Translator: Raphael Collet (OpenERP) <Unknown>\n"
"PO-Revision-Date: 2012-10-17 00:09+0000\n"
"Last-Translator: ERIVELTON PIRES GUEDES <Unknown>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-08-28 06:31+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-10-18 04:40+0000\n"
"X-Generator: Launchpad (build 16160)\n"
#. module: survey
#: view:survey.print:0
@ -534,6 +534,11 @@ msgid ""
"etc. You can edit survey manually or click on the 'Edit Survey' for a "
"WYSIWYG interface."
msgstr ""
"Você pode criar pesquisas para vários propósitos: entrevistas de "
"recrutamento, avaliação periódica de empregados, campanhas de marketing, "
"etc. Uma pesquisa é feita de páginas contendo questões de vários tipos: "
"texto, múltipla escolha, etc. Você pode editar a pesquisa manualmente ou "
"clicar em \"Editar pesquisa\" para uma interface do tipo WYSIWYG."
#. module: survey
#: view:survey:0
@ -745,7 +750,7 @@ msgstr ""
#: view:survey.page:0
#: view:survey.question:0
msgid "When the question is not answered, display this error message:"
msgstr ""
msgstr "Quando a questão não for respondida mostrar esta mensagem de erro:"
#. module: survey
#: view:survey:0
@ -762,7 +767,7 @@ msgstr ""
#. module: survey
#: model:ir.ui.menu,name:survey.menu_browse_survey_response
msgid "Browse Answers"
msgstr ""
msgstr "Navegar pelas respostas"
#. module: survey
#: field:survey.response.answer,comment_field:0
@ -796,7 +801,7 @@ msgstr "Responder Pesquisa"
#: view:survey.page:0
#: view:survey.question:0
msgid "Comment Field"
msgstr ""
msgstr "Campo de comentário"
#. module: survey
#: selection:survey.response,response_type:0
@ -823,7 +828,7 @@ msgstr "Página"
#. module: survey
#: field:survey.question,comment_column:0
msgid "Add comment column in matrix"
msgstr ""
msgstr "Acrescentar coluna de comentário na matriz"
#. module: survey
#: field:survey.answer,response:0
@ -842,6 +847,8 @@ msgstr ""
#: view:survey.question:0
msgid "When the comment is an invalid format, display this error message"
msgstr ""
"Quando o comentário estiver num formato inválido mostrar esta mensagem de "
"erro"
#. module: survey
#: code:addons/survey/wizard/survey_selection.py:83
@ -860,7 +867,7 @@ msgstr "Questões"
#. module: survey
#: help:survey,response_user:0
msgid "Set to one if you require only one Answer per user"
msgstr ""
msgstr "Informe 1 caso somente uma resposta por usuário sejá requerida"
#. module: survey
#: field:survey,users:0
@ -1645,7 +1652,7 @@ msgstr "Ponto Flutuante"
#. module: survey
#: view:survey.response.line:0
msgid "Single Textboxes"
msgstr ""
msgstr "Caixas de texto simples"
#. module: survey
#: code:addons/survey/wizard/survey_send_invitation.py:74