[MERGE] from trunk-mail-concreting-tde, TODO fix bug
bzr revid: chm@openerp.com-20121029090847-27h3tmyvsv9c8vej
This commit is contained in:
commit
46a60cdac7
|
@ -1007,7 +1007,7 @@ class account_period(osv.osv):
|
|||
'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}),
|
||||
'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
|
||||
'state': fields.selection([('draft','Open'), ('done','Closed')], 'Status', readonly=True,
|
||||
help='When monthly periods are created. The state is \'Draft\'. At the end of monthly period it is in \'Done\' state.'),
|
||||
help='When monthly periods are created. The status is \'Draft\'. At the end of monthly period it is in \'Done\' status.'),
|
||||
'company_id': fields.related('fiscalyear_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
|
||||
}
|
||||
_defaults = {
|
||||
|
@ -1134,7 +1134,7 @@ class account_journal_period(osv.osv):
|
|||
'icon': fields.function(_icon_get, string='Icon', type='char', size=32),
|
||||
'active': fields.boolean('Active', required=True, help="If the active field is set to False, it will allow you to hide the journal period without removing it."),
|
||||
'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'Status', required=True, readonly=True,
|
||||
help='When journal period is created. The state is \'Draft\'. If a report is printed it comes to \'Printed\' state. When all transactions are done, it comes in \'Done\' state.'),
|
||||
help='When journal period is created. The status is \'Draft\'. If a report is printed it comes to \'Printed\' status. When all transactions are done, it comes in \'Done\' status.'),
|
||||
'fiscalyear_id': fields.related('period_id', 'fiscalyear_id', string='Fiscal Year', type='many2one', relation='account.fiscalyear'),
|
||||
'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
|
||||
}
|
||||
|
@ -1282,7 +1282,7 @@ class account_move(osv.osv):
|
|||
'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
|
||||
'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
|
||||
'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'Status', required=True, readonly=True,
|
||||
help='All manually created new journal entries are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
|
||||
help='All manually created new journal entries are usually in the status \'Unposted\', but you can set the option to skip that status on the related journal. In that case, they will behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' status.'),
|
||||
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
|
||||
'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
|
||||
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
|
||||
|
|
|
@ -123,8 +123,8 @@ class account_bank_statement(osv.osv):
|
|||
('open','Open'), # used by cash statements
|
||||
('confirm', 'Closed')],
|
||||
'Status', required=True, readonly="1",
|
||||
help='When new statement is created the state will be \'Draft\'.\n'
|
||||
'And after getting confirmation from the bank it will be in \'Confirmed\' state.'),
|
||||
help='When new statement is created the status will be \'Draft\'.\n'
|
||||
'And after getting confirmation from the bank it will be in \'Confirmed\' status.'),
|
||||
'currency': fields.function(_currency, string='Currency',
|
||||
type='many2one', relation='res.currency'),
|
||||
'account_id': fields.related('journal_id', 'default_debit_account_id', type='many2one', relation='account.account', string='Account used in this journal', readonly=True, help='used in statement reconciliation domain, but shouldn\'t be used elswhere.'),
|
||||
|
|
|
@ -207,12 +207,12 @@ class account_invoice(osv.osv):
|
|||
('open','Open'),
|
||||
('paid','Paid'),
|
||||
('cancel','Cancelled'),
|
||||
],'State', select=True, readonly=True,
|
||||
help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed Invoice. \
|
||||
\n* The \'Pro-forma\' when invoice is in Pro-forma state,invoice does not have an invoice number. \
|
||||
\n* The \'Open\' state is used when user create invoice,a invoice number is generated.Its in open state till user does not pay invoice. \
|
||||
\n* The \'Paid\' state is set automatically when the invoice is paid. Its related journal entries may or may not be reconciled. \
|
||||
\n* The \'Cancelled\' state is used when user cancel invoice.'),
|
||||
],'Status', select=True, readonly=True,
|
||||
help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed Invoice. \
|
||||
\n* The \'Pro-forma\' when invoice is in Pro-forma status,invoice does not have an invoice number. \
|
||||
\n* The \'Open\' status is used when user create invoice,a invoice number is generated.Its in open status till user does not pay invoice. \
|
||||
\n* The \'Paid\' status is set automatically when the invoice is paid. Its related journal entries may or may not be reconciled. \
|
||||
\n* The \'Cancelled\' status is used when user cancel invoice.'),
|
||||
'sent': fields.boolean('Sent', readonly=True, help="It indicates that the invoice has been sent."),
|
||||
'date_invoice': fields.date('Invoice Date', readonly=True, states={'draft':[('readonly',False)]}, select=True, help="Keep empty to use the current date"),
|
||||
'date_due': fields.date('Due Date', readonly=True, states={'draft':[('readonly',False)]}, select=True,
|
||||
|
@ -1360,7 +1360,7 @@ class account_invoice_line(osv.osv):
|
|||
_description = "Invoice Line"
|
||||
_columns = {
|
||||
'name': fields.text('Description', required=True),
|
||||
'origin': fields.char('Source', size=256, help="Reference of the document that produced this invoice."),
|
||||
'origin': fields.char('Source Document', size=256, help="Reference of the document that produced this invoice."),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence of this line when displaying the invoice."),
|
||||
'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='cascade', select=True),
|
||||
'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'),
|
||||
|
|
|
@ -1862,7 +1862,7 @@
|
|||
<field name="model_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Model" icon="terp-folder-orange" domain="[]" context="{'group_by':'model_id'}"/>
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
|
||||
<filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -2414,32 +2414,6 @@
|
|||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<record id="ir_actions_server_action_wizard_multi_chart" model="ir.actions.server">
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="condition">True</field>
|
||||
<field name="state">code</field>
|
||||
<field name="model_id" ref="base.model_ir_actions_todo"/>
|
||||
<field eval="5" name="sequence"/>
|
||||
<field name="code">
|
||||
# check for unconfigured companies
|
||||
account_installer_obj = self.pool.get('account.installer')
|
||||
account_installer_obj.check_unconfigured_cmp(cr, uid, context=context)
|
||||
action_ids = []
|
||||
# fetch the act_window actions related to chart of account configuration
|
||||
# we use ir.actions.todo to enable the possibility for other modules to insert their own
|
||||
# wizards during the configuration process
|
||||
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'action_wizard_multi_chart')
|
||||
if ref:
|
||||
action_ids += [ref[1]]
|
||||
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'action_account_configuration_installer')
|
||||
if ref:
|
||||
action_ids += [ref[1]]
|
||||
todo_ids = pool.get('ir.actions.todo').search(cr, uid, [('action_id', 'in', action_ids)], context=context)
|
||||
pool.get('ir.actions.todo').write(cr, uid, todo_ids, {'state':'open'}, context=context)
|
||||
action = pool.get('res.config').next(cr, uid, [], context)
|
||||
</field>
|
||||
<field name="name">New Company Financial Setting</field>
|
||||
</record>
|
||||
|
||||
<record id="account_account_graph" model="ir.ui.view">
|
||||
<field name="name">account.account.graph</field>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -119,15 +119,6 @@ class account_installer(osv.osv_memory):
|
|||
self.execute_simple(cr, uid, ids, context)
|
||||
super(account_installer, self).execute(cr, uid, ids, context=context)
|
||||
|
||||
def action_next(self, cr, uid, ids, context=None):
|
||||
next = self.execute(cr, uid, ids, context=context)
|
||||
for installer in self.browse(cr, uid, ids, context=context):
|
||||
if installer.charts == 'l10n_be':
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
else :
|
||||
if next : return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
|
||||
def execute_simple(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
|
|
@ -91,7 +91,7 @@ class account_invoice_report(osv.osv):
|
|||
('open','Open'),
|
||||
('paid','Done'),
|
||||
('cancel','Cancelled')
|
||||
], 'Invoice State', readonly=True),
|
||||
], 'Invoice Status', readonly=True),
|
||||
'date_due': fields.date('Due Date', readonly=True),
|
||||
'account_id': fields.many2one('account.account', 'Account',readonly=True),
|
||||
'account_line_id': fields.many2one('account.account', 'Account Line',readonly=True),
|
||||
|
|
|
@ -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:35+0000\n"
|
||||
"PO-Revision-Date: 2011-04-15 19:38+0000\n"
|
||||
"PO-Revision-Date: 2012-10-25 12:32+0000\n"
|
||||
"Last-Translator: Chertykov Denis <chertykov@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-10-19 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:analytic.plan.create.model:0
|
||||
|
@ -136,7 +136,7 @@ msgstr "Определить аналитический план счетов"
|
|||
#. module: account_analytic_plans
|
||||
#: constraint:account.invoice:0
|
||||
msgid "Invalid BBA Structured Communication !"
|
||||
msgstr ""
|
||||
msgstr "Неверна структурная связь BBA!"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:account.bank.statement:0
|
||||
|
@ -149,6 +149,8 @@ msgid ""
|
|||
"The date of your Journal Entry is not in the defined period! You should "
|
||||
"change the date or remove this constraint from the journal."
|
||||
msgstr ""
|
||||
"Дата проводки в журнале не в определённом периоде! Вы должны сменить дату "
|
||||
"или удалить это ограничение из журнала."
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: sql_constraint:account.journal:0
|
||||
|
@ -251,6 +253,8 @@ msgid ""
|
|||
"currency. You should remove the secondary currency on the account or select "
|
||||
"a multi-currency view on the journal."
|
||||
msgstr ""
|
||||
"Выбранный счёт проводки в журнале нуждается во вторичной валюте. Вы должны "
|
||||
"удалить вторичную валюту по счёту или выбрать мульти-валютный вид по журналу."
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: report:account.analytic.account.crossovered.analytic:0
|
||||
|
@ -429,7 +433,7 @@ msgstr "Счет 4 уровня"
|
|||
#. module: account_analytic_plans
|
||||
#: constraint:account.move.line:0
|
||||
msgid "Company must be the same for its related account and period."
|
||||
msgstr ""
|
||||
msgstr "Для счета и периода должна быть одна компания."
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan.instance.line:0
|
||||
|
@ -515,11 +519,14 @@ msgid ""
|
|||
"analytic accounts for each plan set. Then, you must attach a plan set to "
|
||||
"your account journals."
|
||||
msgstr ""
|
||||
"Для настройки нескольких планов счетов аналитики, вы должны определить "
|
||||
"корневые счета аналитики для каждого набора плана. Затем вы можете "
|
||||
"прикрепить набор плана к вашим учётным журналам."
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:account.move.line:0
|
||||
msgid "You can not create journal items on closed account."
|
||||
msgstr ""
|
||||
msgstr "Нельзя создать элемент журнала по закрытому счету ."
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: report:account.analytic.account.crossovered.analytic:0
|
||||
|
|
|
@ -226,9 +226,9 @@ class account_asset_asset(osv.osv):
|
|||
'child_ids': fields.one2many('account.asset.asset', 'parent_id', 'Children Assets'),
|
||||
'purchase_date': fields.date('Purchase Date', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'state': fields.selection([('draft','Draft'),('open','Running'),('close','Close')], 'Status', required=True,
|
||||
help="When an asset is created, the state is 'Draft'.\n" \
|
||||
"If the asset is confirmed, the state goes in 'Running' and the depreciation lines can be posted in the accounting.\n" \
|
||||
"You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that state."),
|
||||
help="When an asset is created, the status is 'Draft'.\n" \
|
||||
"If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n" \
|
||||
"You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that status."),
|
||||
'active': fields.boolean('Active'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'method': fields.selection([('linear','Linear'),('degressive','Degressive')], 'Computation Method', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="Choose the method to use to compute the amount of depreciation lines.\n"\
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
# Polish 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-25 16:56+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Polish <pl@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-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
msgid "Check on Top"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.act_window,help:account_check_writing.action_write_check
|
||||
msgid ""
|
||||
"The check payment form allows you to track the payment you do to your "
|
||||
"suppliers specially by check. When you select a supplier, the payment method "
|
||||
"and an amount for the payment, OpenERP will propose to reconcile your "
|
||||
"payment with the open supplier invoices or bills.You can print the check"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:account.voucher:0
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_bottom
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
|
||||
msgid "Print Check"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
msgid "Check in middle"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: help:res.company,check_layout:0
|
||||
msgid ""
|
||||
"Check on top is compatible with Quicken, QuickBooks and Microsoft Money. "
|
||||
"Check in middle is compatible with Peachtree, ACCPAC and DacEasy. Check on "
|
||||
"bottom is compatible with Peachtree, ACCPAC and DacEasy only"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
msgid "Check on bottom"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: constraint:res.company:0
|
||||
msgid "Error! You can not create recursive companies."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: help:account.journal,allow_check_writing:0
|
||||
msgid "Check this if the journal is to be used for writing checks."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.journal,allow_check_writing:0
|
||||
msgid "Allow Check writing"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Description"
|
||||
msgstr "Opis"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_account_journal
|
||||
msgid "Journal"
|
||||
msgstr "Dziennik"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.act_window,name:account_check_writing.action_write_check
|
||||
#: model:ir.ui.menu,name:account_check_writing.menu_action_write_check
|
||||
msgid "Write Checks"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Discount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Original Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:res.company:0
|
||||
msgid "Configuration"
|
||||
msgstr "Konfiguracja"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.voucher,allow_check:0
|
||||
msgid "Allow Check Writing"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Payment"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.journal,use_preprint_check:0
|
||||
msgid "Use Preprinted Check"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: sql_constraint:res.company:0
|
||||
msgid "The company name must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Due Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:res.company:0
|
||||
msgid "Default Check Layout"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: constraint:account.journal:0
|
||||
msgid ""
|
||||
"Configuration error! The currency chosen should be shared by the default "
|
||||
"accounts too."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
msgid "Balance Due"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Check Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_account_voucher
|
||||
msgid "Accounting Voucher"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The name of the journal must be unique per company !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The code of the journal must be unique per company !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.voucher,amount_in_word:0
|
||||
msgid "Amount in Word"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Open Balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:res.company,check_layout:0
|
||||
msgid "Choose Check layout"
|
||||
msgstr ""
|
|
@ -19,11 +19,14 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from osv import osv, fields
|
||||
import netsvc
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class payment_mode(osv.osv):
|
||||
_name= 'payment.mode'
|
||||
_description= 'Payment Mode'
|
||||
|
@ -70,9 +73,7 @@ class payment_order(osv.osv):
|
|||
|
||||
#dead code
|
||||
def get_wizard(self, type):
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel("Warning!", netsvc.LOG_WARNING,
|
||||
"No wizard is found for the payment type '%s'." % type)
|
||||
_logger.warning("No wizard found for the payment type '%s'.", type)
|
||||
return None
|
||||
|
||||
def _total(self, cursor, user, ids, name, args, context=None):
|
||||
|
@ -95,7 +96,7 @@ class payment_order(osv.osv):
|
|||
('cancel', 'Cancelled'),
|
||||
('open', 'Confirmed'),
|
||||
('done', 'Done')], 'Status', select=True,
|
||||
help='When an order is placed the state is \'Draft\'.\n Once the bank is confirmed the state is set to \'Confirmed\'.\n Then the order is paid the state is \'Done\'.'),
|
||||
help='When an order is placed the status is \'Draft\'.\n Once the bank is confirmed the status is set to \'Confirmed\'.\n Then the order is paid the status is \'Done\'.'),
|
||||
'line_ids': fields.one2many('payment.line', 'order_id', 'Payment lines', states={'done': [('readonly', True)]}),
|
||||
'total': fields.function(_total, string="Total", type='float'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible', required=True, states={'done': [('readonly', True)]}),
|
||||
|
|
|
@ -293,10 +293,10 @@ class account_voucher(osv.osv):
|
|||
('proforma','Pro-forma'),
|
||||
('posted','Posted')
|
||||
], 'Status', readonly=True, size=32,
|
||||
help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed Voucher. \
|
||||
\n* The \'Pro-forma\' when voucher is in Pro-forma state,voucher does not have an voucher number. \
|
||||
\n* The \'Posted\' state is used when user create voucher,a voucher number is generated and voucher entries are created in account \
|
||||
\n* The \'Cancelled\' state is used when user cancel voucher.'),
|
||||
help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed Voucher. \
|
||||
\n* The \'Pro-forma\' when voucher is in Pro-forma status,voucher does not have an voucher number. \
|
||||
\n* The \'Posted\' status is used when user create voucher,a voucher number is generated and voucher entries are created in account \
|
||||
\n* The \'Cancelled\' status is used when user cancel voucher.'),
|
||||
'amount': fields.float('Total', digits_compute=dp.get_precision('Account'), required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'tax_amount':fields.float('Tax Amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'reference': fields.char('Ref #', size=64, readonly=True, states={'draft':[('readonly',False)]}, help="Transaction reference number."),
|
||||
|
|
|
@ -52,7 +52,7 @@ class sale_receipt_report(osv.osv):
|
|||
('proforma','Pro-forma'),
|
||||
('posted','Posted'),
|
||||
('cancel','Cancelled')
|
||||
], 'Voucher State', readonly=True),
|
||||
], 'Voucher Status', readonly=True),
|
||||
'pay_now':fields.selection([
|
||||
('pay_now','Pay Directly'),
|
||||
('pay_later','Pay Later or Group Funds'),
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
<button name="proforma_voucher" string="Validate" states="draft" class="oe_highlight"/>
|
||||
<button name="%(act_pay_voucher)d" context="{'narration':narration, 'title':'Customer Payment', 'type':'receipt', 'partner_id':partner_id, 'reference':reference, 'amount':amount}" type="action" string="Pay" attrs="{'invisible':['|',('pay_now','=','pay_now'),'|',('state','=','draft'), ('paid','=',True)]}" class="oe_highlight"/>
|
||||
<button name="cancel_voucher" string="Cancel" states="draft,proforma" />
|
||||
<button name="cancel_voucher" string="Cancel" type="object" states="posted" confirm="Are you sure to confirm this record ?"/>
|
||||
<button name="cancel_voucher" string="Cancel" type="object" states="posted" confirm="Are you sure you want to cancel this receipt?"/>
|
||||
<button name="action_cancel_draft" type="object" states="cancel" string="Set to Draft"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,posted" statusbar_colors='{"proforma":"blue"}'/>
|
||||
</header>
|
||||
|
@ -209,7 +209,7 @@
|
|||
<button name="proforma_voucher" string="Validate" states="draft" class="oe_highlight"/>
|
||||
<button name="%(act_pay_bills)d" context="{'narration':narration, 'title':'Bill Payment', 'type':'payment', 'partner_id': partner_id, 'reference':reference}" type="action" string="Pay Bill" attrs="{'invisible':['|',('pay_now','=','pay_now'),'|',('state','=','draft'), ('paid','=',True)]}" class="oe_highlight"/>
|
||||
<button name="cancel_voucher" string="Cancel" states="draft,proforma" />
|
||||
<button name="cancel_voucher" string="Cancel" type="object" states="posted" confirm="Are you sure to confirm this record ?"/>
|
||||
<button name="cancel_voucher" string="Cancel" type="object" states="posted" confirm="Are you sure you want to cancel this receipt?"/>
|
||||
<button name="action_cancel_draft" type="object" states="cancel" string="Set to Draft"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,posted" statusbar_colors='{"proforma":"blue"}'/>
|
||||
</header>
|
||||
|
|
|
@ -255,27 +255,27 @@ class account_analytic_account(osv.osv):
|
|||
if context is None:
|
||||
context={}
|
||||
if context.get('current_model') == 'project.project':
|
||||
cr.execute("select analytic_account_id from project_project")
|
||||
project_ids = [x[0] for x in cr.fetchall()]
|
||||
project_obj = self.pool.get("account.analytic.account")
|
||||
project_ids = project_obj.search(cr, uid, args)
|
||||
return self.name_get(cr, uid, project_ids, context=context)
|
||||
if name:
|
||||
account = self.search(cr, uid, [('code', '=', name)] + args, limit=limit, context=context)
|
||||
if not account:
|
||||
account_ids = self.search(cr, uid, [('code', '=', name)] + args, limit=limit, context=context)
|
||||
if not account_ids:
|
||||
names=map(lambda i : i.strip(),name.split('/'))
|
||||
for i in range(len(names)):
|
||||
dom=[('name', operator, names[i])]
|
||||
if i>0:
|
||||
dom+=[('id','child_of',account)]
|
||||
account = self.search(cr, uid, dom, limit=limit, context=context)
|
||||
newacc = account
|
||||
dom+=[('id','child_of',account_ids)]
|
||||
account_ids = self.search(cr, uid, dom, limit=limit, context=context)
|
||||
newacc = account_ids
|
||||
while newacc:
|
||||
newacc = self.search(cr, uid, [('parent_id', 'in', newacc)], limit=limit, context=context)
|
||||
account += newacc
|
||||
account_ids += newacc
|
||||
if args:
|
||||
account = self.search(cr, uid, [('id', 'in', account)] + args, limit=limit, context=context)
|
||||
account_ids = self.search(cr, uid, [('id', 'in', account_ids)] + args, limit=limit, context=context)
|
||||
else:
|
||||
account = self.search(cr, uid, args, limit=limit, context=context)
|
||||
return self.name_get(cr, uid, account, context=context)
|
||||
account_ids = self.search(cr, uid, args, limit=limit, context=context)
|
||||
return self.name_get(cr, uid, account_ids, context=context)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
contract = super(account_analytic_account, self).create(cr, uid, vals, context=context)
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
# Polish translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2012-10-25 17:11+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Polish <pl@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-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. #-#-#-#-# auth_openid.pot (OpenERP Server 6.1rc1) #-#-#-#-#
|
||||
#. module: auth_openid
|
||||
#. #-#-#-#-# auth_openid.pot.web (PROJECT VERSION) #-#-#-#-#
|
||||
#. openerp-web
|
||||
#: view:res.users:0
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:12
|
||||
msgid "OpenID"
|
||||
msgstr ""
|
||||
|
||||
#. #-#-#-#-# auth_openid.pot (OpenERP Server 6.1rc1) #-#-#-#-#
|
||||
#. module: auth_openid
|
||||
#. #-#-#-#-# auth_openid.pot.web (PROJECT VERSION) #-#-#-#-#
|
||||
#. openerp-web
|
||||
#: field:res.users,openid_url:0
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:47
|
||||
msgid "OpenID URL"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_openid
|
||||
#: help:res.users,openid_email:0
|
||||
msgid "Used for disambiguation in case of a shared OpenID URL"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_openid
|
||||
#: sql_constraint:res.users:0
|
||||
msgid "You can not have two users with the same login !"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_openid
|
||||
#: field:res.users,openid_email:0
|
||||
msgid "OpenID Email"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_openid
|
||||
#: constraint:res.users:0
|
||||
msgid "The chosen company is not in the allowed companies for this user"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_openid
|
||||
#: field:res.users,openid_key:0
|
||||
msgid "OpenID Key"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_openid
|
||||
#: model:ir.model,name:auth_openid.model_res_users
|
||||
msgid "res.users"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:8
|
||||
msgid "Password"
|
||||
msgstr "Hasło"
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:9
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:10
|
||||
msgid "Google"
|
||||
msgstr "Google"
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:10
|
||||
msgid "Google Apps"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:11
|
||||
msgid "Launchpad"
|
||||
msgstr "Launchpad"
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:20
|
||||
msgid "Google Apps Domain:"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:24
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:28
|
||||
msgid "OpenID URL:"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:35
|
||||
msgid "Google Apps Domain"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:41
|
||||
msgid "Username"
|
||||
msgstr ""
|
|
@ -138,7 +138,7 @@ class res_users(osv.Model):
|
|||
for user in self.browse(cr, uid, ids, context))
|
||||
|
||||
_columns = {
|
||||
'state': fields.function(_get_state, string='State', type='selection',
|
||||
'state': fields.function(_get_state, string='Status', type='selection',
|
||||
selection=[('new', 'New'), ('active', 'Active'), ('reset', 'Resetting Password')]),
|
||||
}
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-05-10 17:50+0000\n"
|
||||
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
|
||||
"PO-Revision-Date: 2012-10-25 16:32+0000\n"
|
||||
"Last-Translator: ccdos <Unknown>\n"
|
||||
"Language-Team: Chinese (Simplified) <zh_CN@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-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: base_action_rule
|
||||
#: help:base.action.rule,act_mail_to_user:0
|
||||
|
@ -315,7 +315,7 @@ msgstr "激活"
|
|||
#: code:addons/base_action_rule/base_action_rule.py:329
|
||||
#, python-format
|
||||
msgid "No Email ID Found for your Company address!"
|
||||
msgstr ""
|
||||
msgstr "公司地址中没有设置Email !"
|
||||
|
||||
#. module: base_action_rule
|
||||
#: field:base.action.rule,act_remind_user:0
|
||||
|
|
|
@ -1023,10 +1023,10 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
'rrule': fields.function(_get_rulestring, type='char', size=124, \
|
||||
fnct_inv=_rrule_write, store=True, string='Recurrent Rule'),
|
||||
'rrule_type': fields.selection([
|
||||
('daily', 'Daily'),
|
||||
('weekly', 'Weekly'),
|
||||
('monthly', 'Monthly'),
|
||||
('yearly', 'Yearly')
|
||||
('daily', 'Day(s)'),
|
||||
('weekly', 'Week(s)'),
|
||||
('monthly', 'Month(s)'),
|
||||
('yearly', 'Year(s)')
|
||||
], 'Recurrency', states={'done': [('readonly', True)]},
|
||||
help="Let the event automatically repeat at that interval"),
|
||||
'alarm_id': fields.many2one('res.alarm', 'Reminder', states={'done': [('readonly', True)]},
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
</h2>
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Meeting Detail">
|
||||
<page string="Meeting Details">
|
||||
<group>
|
||||
<group>
|
||||
<field name="date" string="Starting at"/>
|
||||
|
@ -170,12 +170,7 @@
|
|||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<!--
|
||||
Temporarily removing invitation feature as the implementation
|
||||
was not clean. Invitation should be trigerred automatically
|
||||
based on partner_ids.
|
||||
-->
|
||||
<page string="Invitations">
|
||||
<page string="Invitations" groups="base.group_no_one">
|
||||
<field name="attendee_ids" widget="one2many" mode="tree">
|
||||
<tree string="Invitation details" editable="top">
|
||||
<field name="partner_id"/>
|
||||
|
|
|
@ -156,5 +156,11 @@
|
|||
border-right: 1px solid #D0D0D0;
|
||||
}
|
||||
|
||||
.oe_import .oe_import_error_report > p {
|
||||
background: #efc9cb;
|
||||
}
|
||||
|
||||
.oe_import .select2-results {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<label for="vat"/>
|
||||
<div>
|
||||
<field name="vat" on_change="vat_change(vat)" placeholder="e.g. BE0477472701" class="oe_inline"/>
|
||||
<button colspan="2" name="button_check_vat" string="Check VAT" type="object" icon="gtk-execute" class="oe_inline"/>
|
||||
<button colspan="2" name="button_check_vat" string="Check Validity" type="object" icon="gtk-execute" class="oe_inline"/>
|
||||
<field name="vat_subjected" class="oe_inline"/>
|
||||
</div>
|
||||
</field>
|
||||
|
|
|
@ -77,7 +77,7 @@ class crm_case_stage(osv.osv):
|
|||
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'Related Status', required=True,
|
||||
help="The status of your document will automatically change regarding the selected stage. " \
|
||||
"For example, if a stage is related to the state 'Close', when your document reaches this stage, it is automatically closed."),
|
||||
"For example, if a stage is related to the status 'Close', when your document reaches this stage, it is automatically closed."),
|
||||
'case_default': fields.boolean('Common to All Teams',
|
||||
help="If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams."),
|
||||
'fold': fields.boolean('Hide in Views when Empty',
|
||||
|
|
|
@ -223,11 +223,11 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
'day_close': fields.function(_compute_day, string='Days to Close', \
|
||||
multi='day_close', type="float", store=True),
|
||||
'state': fields.related('stage_id', 'state', type="selection", store=True,
|
||||
selection=crm.AVAILABLE_STATES, string="State", readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
If the case is in progress the state is set to \'Open\'.\
|
||||
When the case is over, the state is set to \'Done\'.\
|
||||
If the case needs to be reviewed then the state is \
|
||||
selection=crm.AVAILABLE_STATES, string="Status", readonly=True,
|
||||
help='The Status is set to \'Draft\', when a case is created.\
|
||||
If the case is in progress the Status is set to \'Open\'.\
|
||||
When the case is over, the Status is set to \'Done\'.\
|
||||
If the case needs to be reviewed then the Status is \
|
||||
set to \'Pending\'.'),
|
||||
|
||||
# Only used for type opportunity
|
||||
|
|
|
@ -50,10 +50,10 @@ class crm_phonecall(base_state, osv.osv):
|
|||
('cancel', 'Cancelled'),
|
||||
('done', 'Held'),],
|
||||
string='Status', size=16, readonly=True,
|
||||
help='The state is set to \'Todo\', when a case is created.\
|
||||
If the case is in progress the state is set to \'Open\'.\
|
||||
When the call is over, the state is set to \'Held\'.\
|
||||
If the call needs to be done then the state is set to \'Not Held\'.'),
|
||||
help='The status is set to \'Todo\', when a case is created.\
|
||||
If the case is in progress the status is set to \'Open\'.\
|
||||
When the call is over, the status is set to \'Held\'.\
|
||||
If the call needs to be done then the status is set to \'Not Held\'.'),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'date_open': fields.datetime('Opened', readonly=True),
|
||||
# phonecall fields
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
</div>
|
||||
<div class="oe_title">
|
||||
<div class="oe_edit_only">
|
||||
<label for="name" string="Title"/>
|
||||
<label for="name"/>
|
||||
</div>
|
||||
<h1><field name="name" required="1"/></h1>
|
||||
<div class="oe_edit_only">
|
||||
|
|
|
@ -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-03-22 16:17+0000\n"
|
||||
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
|
||||
"PO-Revision-Date: 2012-10-25 16:22+0000\n"
|
||||
"Last-Translator: fenshuajiang <openerp@126.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:06+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead.report:0
|
||||
|
@ -172,7 +172,7 @@ msgstr "预计结束月份"
|
|||
#. module: crm
|
||||
#: view:crm.lead2opportunity.partner.mass:0
|
||||
msgid "Assigned Opportunities to"
|
||||
msgstr ""
|
||||
msgstr "分配商机给"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0 field:crm.lead,partner_id:0 view:crm.lead.report:0
|
||||
|
@ -583,7 +583,7 @@ msgstr "结束日期"
|
|||
#. module: crm
|
||||
#: view:crm.opportunity2phonecall:0 view:crm.phonecall2phonecall:0
|
||||
msgid "Schedule/Log a Call"
|
||||
msgstr ""
|
||||
msgstr "计划/记录一个电话"
|
||||
|
||||
#. module: crm
|
||||
#: constraint:base.action.rule:0
|
||||
|
@ -763,7 +763,7 @@ msgstr "继续"
|
|||
#. module: crm
|
||||
#: field:crm.segmentation,som_interval:0
|
||||
msgid "Days per Period"
|
||||
msgstr ""
|
||||
msgstr "每阶段的天数"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.meeting,byday:0
|
||||
|
@ -926,7 +926,7 @@ msgstr "开启天数"
|
|||
#. module: crm
|
||||
#: view:crm.meeting:0
|
||||
msgid "Show Time as"
|
||||
msgstr ""
|
||||
msgstr "显示时间为"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.phonecall2partner:0
|
||||
|
@ -1299,7 +1299,7 @@ msgstr "写日期"
|
|||
#. module: crm
|
||||
#: view:crm.meeting:0
|
||||
msgid "End of Recurrency"
|
||||
msgstr ""
|
||||
msgstr "结束循环"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.meeting:0
|
||||
|
@ -1835,7 +1835,7 @@ msgstr "回复到"
|
|||
#. module: crm
|
||||
#: view:crm.case.section:0
|
||||
msgid "Select Stages for this Sales Team"
|
||||
msgstr ""
|
||||
msgstr "为这个销售团队选择阶段"
|
||||
|
||||
#. module: crm
|
||||
#: view:board.board:0
|
||||
|
@ -2683,7 +2683,7 @@ msgstr "这联系的邮件地址"
|
|||
#. module: crm
|
||||
#: field:crm.lead,referred:0
|
||||
msgid "Referred by"
|
||||
msgstr ""
|
||||
msgstr "推荐人"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0 model:ir.model,name:crm.model_crm_add_note
|
||||
|
|
|
@ -50,7 +50,7 @@ class crm_claim_stage(osv.osv):
|
|||
'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."),
|
||||
'section_ids':fields.many2many('crm.case.section', 'section_claim_stage_rel', 'stage_id', 'section_id', string='Sections',
|
||||
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', required=True, help="The related state for the stage. The state of your document will automatically change regarding the selected stage. For example, if a stage is related to the state 'Close', when your document reaches this stage, it will be automatically have the 'closed' state."),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'Status', required=True, help="The related status for the stage. The status of your document will automatically change regarding the selected stage. For example, if a stage is related to the status 'Close', when your document reaches this stage, it will be automatically have the 'closed' status."),
|
||||
'case_refused': fields.boolean('Refused stage',
|
||||
help='Refused stages are specific stages for done.'),
|
||||
'case_default': fields.boolean('Common to All Teams',
|
||||
|
@ -108,11 +108,11 @@ class crm_claim(base_stage, osv.osv):
|
|||
domain="['|', ('section_ids', '=', section_id), ('case_default', '=', True)]"),
|
||||
'cause': fields.text('Root Cause'),
|
||||
'state': fields.related('stage_id', 'state', type="selection", store=True,
|
||||
selection=crm.AVAILABLE_STATES, string="State", readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
If the case is in progress the state is set to \'Open\'.\
|
||||
When the case is over, the state is set to \'Done\'.\
|
||||
If the case needs to be reviewed then the state is \
|
||||
selection=crm.AVAILABLE_STATES, string="Status", readonly=True,
|
||||
help='The status is set to \'Draft\', when a case is created.\
|
||||
If the case is in progress the status is set to \'Open\'.\
|
||||
When the case is over, the status is set to \'Done\'.\
|
||||
If the case needs to be reviewed then the status is \
|
||||
set to \'Pending\'.'),
|
||||
}
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2011-03-16 00:04+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2012-10-24 05:01+0000\n"
|
||||
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-25 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16179)\n"
|
||||
|
||||
#. module: crm_claim
|
||||
#: field:crm.claim.report,nbr:0
|
||||
|
@ -85,12 +85,12 @@ msgstr ""
|
|||
#: code:addons/crm_claim/crm_claim.py:132
|
||||
#, python-format
|
||||
msgid "The claim '%s' has been opened."
|
||||
msgstr ""
|
||||
msgstr "Претензия '%s' была открыта"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
msgid "Date Closed"
|
||||
msgstr ""
|
||||
msgstr "Дата закрытия"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
|
@ -151,12 +151,12 @@ msgstr "Ссылка"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Date of claim"
|
||||
msgstr ""
|
||||
msgstr "Дата претензии"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
msgid "All pending Claims"
|
||||
msgstr ""
|
||||
msgstr "Все ожидающие претензии"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
|
@ -187,7 +187,7 @@ msgstr "Контрагент"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Month of claim"
|
||||
msgstr ""
|
||||
msgstr "Месяц претензии"
|
||||
|
||||
#. module: crm_claim
|
||||
#: selection:crm.claim,type_action:0
|
||||
|
@ -227,7 +227,7 @@ msgstr "Отправить новое эл. письмо"
|
|||
#: selection:crm.claim,state:0
|
||||
#: view:crm.claim.report:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
msgstr "Новый"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
|
@ -254,7 +254,7 @@ msgstr "Следующее действие"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "My Sales Team(s)"
|
||||
msgstr ""
|
||||
msgstr "Мои отделы продаж"
|
||||
|
||||
#. module: crm_claim
|
||||
#: model:crm.case.stage,name:crm_claim.stage_claim3
|
||||
|
@ -321,7 +321,7 @@ msgstr "Контакт"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Month-1"
|
||||
msgstr ""
|
||||
msgstr "Месяц-1"
|
||||
|
||||
#. module: crm_claim
|
||||
#: model:ir.actions.act_window,name:crm_claim.action_report_crm_claim
|
||||
|
@ -380,7 +380,7 @@ msgstr "Дата изменения"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Year of claim"
|
||||
msgstr ""
|
||||
msgstr "Год претензи"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
|
@ -402,7 +402,7 @@ msgstr "Значение претензии"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
msgid "Responsible User"
|
||||
msgstr ""
|
||||
msgstr "Ответственный пользователь"
|
||||
|
||||
#. module: crm_claim
|
||||
#: help:crm.claim,email_cc:0
|
||||
|
@ -474,7 +474,7 @@ msgstr "Июнь"
|
|||
#. module: crm_claim
|
||||
#: view:res.partner:0
|
||||
msgid "Partners Claim"
|
||||
msgstr ""
|
||||
msgstr "Претензии партнера"
|
||||
|
||||
#. module: crm_claim
|
||||
#: field:crm.claim,partner_phone:0
|
||||
|
@ -489,7 +489,7 @@ msgstr "Пользователь"
|
|||
#. module: crm_claim
|
||||
#: field:crm.claim,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
msgstr "Активен"
|
||||
|
||||
#. module: crm_claim
|
||||
#: selection:crm.claim.report,month:0
|
||||
|
@ -621,13 +621,13 @@ msgstr "Открыть"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
msgid "New Claims"
|
||||
msgstr ""
|
||||
msgstr "Новые претензии"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
#: selection:crm.claim,state:0
|
||||
msgid "In Progress"
|
||||
msgstr "Выполняется"
|
||||
msgstr "В работе"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
|
@ -638,17 +638,17 @@ msgstr "Ответственный"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Claims created in current year"
|
||||
msgstr ""
|
||||
msgstr "Претензии созданные в текущем году"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
msgid "Unassigned Claims"
|
||||
msgstr ""
|
||||
msgstr "Не назначенные претензии"
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Claims created in current month"
|
||||
msgstr ""
|
||||
msgstr "Претензии созданные в текущем месяце"
|
||||
|
||||
#. module: crm_claim
|
||||
#: field:crm.claim.report,delay_expected:0
|
||||
|
@ -718,7 +718,7 @@ msgstr "Выполненные действия"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "Claims created in last month"
|
||||
msgstr ""
|
||||
msgstr "Претензии созданные в прошлом месяце"
|
||||
|
||||
#. module: crm_claim
|
||||
#: model:crm.case.stage,name:crm_claim.stage_claim5
|
||||
|
@ -760,7 +760,7 @@ msgstr "Год"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim.report:0
|
||||
msgid "My company"
|
||||
msgstr ""
|
||||
msgstr "Моя компания"
|
||||
|
||||
#. module: crm_claim
|
||||
#: selection:crm.claim.report,month:0
|
||||
|
@ -780,7 +780,7 @@ msgstr "Идентификатор"
|
|||
#. module: crm_claim
|
||||
#: constraint:res.partner:0
|
||||
msgid "Error ! You cannot create recursive associated members."
|
||||
msgstr ""
|
||||
msgstr "Ошибка! Вы не можете создавать рекурсивные ссылки на участников."
|
||||
|
||||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
|
@ -810,7 +810,7 @@ msgstr "Дата создания"
|
|||
#. module: crm_claim
|
||||
#: view:crm.claim:0
|
||||
msgid "In Progress Claims"
|
||||
msgstr ""
|
||||
msgstr "Претензии \"В работе\""
|
||||
|
||||
#~ msgid "Probability"
|
||||
#~ msgstr "Вероятность"
|
||||
|
|
|
@ -73,10 +73,10 @@ class crm_helpdesk(base_state, base_stage, osv.osv):
|
|||
('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'Status', size=16, readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
help='The status is set to \'Draft\', when a case is created.\
|
||||
\nIf the case is in progress the status is set to \'Open\'.\
|
||||
\nWhen the case is over, the status is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the status is set to \'Pending\'.'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2010-12-20 08:54+0000\n"
|
||||
"PO-Revision-Date: 2012-10-24 05:08+0000\n"
|
||||
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-25 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16179)\n"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk.report,delay_close:0
|
||||
|
@ -46,7 +46,7 @@ msgstr "Март"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Helpdesk requests occurred in current year"
|
||||
msgstr ""
|
||||
msgstr "Запросы на техподдержку в текущем году"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,company_id:0
|
||||
|
@ -80,7 +80,7 @@ msgstr "Добавить внутреннею заметку"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Date of helpdesk requests"
|
||||
msgstr ""
|
||||
msgstr "Дата запросов техподдержки"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
|
@ -95,7 +95,7 @@ msgstr "Сообщения"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "My company"
|
||||
msgstr ""
|
||||
msgstr "Моя компания"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,state:0
|
||||
|
@ -156,7 +156,7 @@ msgstr "Раздел"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Helpdesk requests occurred in last month"
|
||||
msgstr ""
|
||||
msgstr "последний месяц"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
|
@ -166,14 +166,14 @@ msgstr "Отправить новое эл. письмо"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Helpdesk requests during last 7 days"
|
||||
msgstr ""
|
||||
msgstr "Запросы на техподдержку за последние 7 дней"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
#: selection:crm.helpdesk,state:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
msgstr "Новый"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.model,name:crm_helpdesk.model_crm_helpdesk_report
|
||||
|
@ -207,7 +207,7 @@ msgstr "# Писем"
|
|||
#: view:crm.helpdesk:0
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "My Sales Team(s)"
|
||||
msgstr ""
|
||||
msgstr "Мои отделы продаж"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: field:crm.helpdesk,create_date:0
|
||||
|
@ -252,7 +252,7 @@ msgstr "Категории"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "New Helpdesk Request"
|
||||
msgstr ""
|
||||
msgstr "Новый запрос техподдержки"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
|
@ -267,13 +267,13 @@ msgstr "Даты"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Month of helpdesk requests"
|
||||
msgstr ""
|
||||
msgstr "Месяц запросов техподдержки"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: code:addons/crm_helpdesk/crm_helpdesk.py:101
|
||||
#, python-format
|
||||
msgid "No Subject"
|
||||
msgstr ""
|
||||
msgstr "Без темы"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
|
@ -283,12 +283,12 @@ msgstr "№ техподдержки"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "All pending Helpdesk Request"
|
||||
msgstr ""
|
||||
msgstr "Все ожидающие запросы техподдержки"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Year of helpdesk requests"
|
||||
msgstr ""
|
||||
msgstr "Год запросов техподдержки"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
|
@ -324,7 +324,7 @@ msgstr "Дата изменения"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Helpdesk requests occurred in current month"
|
||||
msgstr ""
|
||||
msgstr "Запросы техподдержки в текущем месяце"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
|
@ -345,7 +345,7 @@ msgstr "Категория"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Responsible User"
|
||||
msgstr ""
|
||||
msgstr "Ответственный пользователь"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
|
@ -361,7 +361,7 @@ msgstr "Планируемые затраты"
|
|||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,channel_id:0
|
||||
msgid "Communication channel."
|
||||
msgstr ""
|
||||
msgstr "Канал общения"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: help:crm.helpdesk,email_cc:0
|
||||
|
@ -575,7 +575,7 @@ msgstr "Дерево поддержи"
|
|||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,state:0
|
||||
msgid "In Progress"
|
||||
msgstr ""
|
||||
msgstr "В работе"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
|
@ -660,7 +660,7 @@ msgstr "Название"
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk.report:0
|
||||
msgid "Month-1"
|
||||
msgstr ""
|
||||
msgstr "Месяц-1"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: model:ir.ui.menu,name:crm_helpdesk.menu_help_support_main
|
||||
|
@ -699,17 +699,17 @@ msgstr ""
|
|||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Todays's Helpdesk Requests"
|
||||
msgstr ""
|
||||
msgstr "Запросы техподдержки за сегодня"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Request Date"
|
||||
msgstr ""
|
||||
msgstr "Дата запроса"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: view:crm.helpdesk:0
|
||||
msgid "Open Helpdesk Request"
|
||||
msgstr ""
|
||||
msgstr "Открыть запрос техподдержки"
|
||||
|
||||
#. module: crm_helpdesk
|
||||
#: selection:crm.helpdesk,priority:0
|
||||
|
|
|
@ -87,7 +87,7 @@ class res_partner(osv.osv):
|
|||
help="Gives the probability to assign a lead to this partner. (0 means no assignation.)"),
|
||||
'opportunity_assigned_ids': fields.one2many('crm.lead', 'partner_assigned_id',\
|
||||
'Assigned Opportunities'),
|
||||
'grade_id': fields.many2one('res.partner.grade', 'Partner Grade'),
|
||||
'grade_id': fields.many2one('res.partner.grade', 'Partner Level'),
|
||||
'activation' : fields.many2one('res.partner.activation', 'Activation', select=1),
|
||||
'date_partnership' : fields.date('Partnership Date'),
|
||||
'date_review' : fields.date('Latest Partner Review'),
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Polish 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-25 16:50+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Polish <pl@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-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: field:decimal.precision,digits:0
|
||||
msgid "Digits"
|
||||
msgstr "Cyfry"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: model:ir.actions.act_window,name:decimal_precision.action_decimal_precision_form
|
||||
#: model:ir.ui.menu,name:decimal_precision.menu_decimal_precision_form
|
||||
msgid "Decimal Accuracy"
|
||||
msgstr ""
|
||||
|
||||
#. module: decimal_precision
|
||||
#: field:decimal.precision,name:0
|
||||
msgid "Usage"
|
||||
msgstr "Użycie"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: sql_constraint:decimal.precision:0
|
||||
msgid "Only one value can be defined for each given usage!"
|
||||
msgstr ""
|
||||
|
||||
#. module: decimal_precision
|
||||
#: view:decimal.precision:0
|
||||
msgid "Decimal Precision"
|
||||
msgstr ""
|
||||
|
||||
#. module: decimal_precision
|
||||
#: model:ir.model,name:decimal_precision.model_decimal_precision
|
||||
msgid "decimal.precision"
|
||||
msgstr ""
|
|
@ -103,7 +103,7 @@ class DocIndex(indexer):
|
|||
return _to_unicode(data)
|
||||
except OSError:
|
||||
|
||||
_logger.warn("Failed attempt to execute antiword (MS Word reader). Antiword is necessary to index the file %s of MIME type %s. Detailed error available at DEBUG level.", fname, self._getMimeTypes()[0])
|
||||
_logger.warning("Failed attempt to execute antiword (MS Word reader). Antiword is necessary to index the file %s of MIME type %s. Detailed error available at DEBUG level.", fname, self._getMimeTypes()[0])
|
||||
_logger.debug("Trace of the failed file indexing attempt.", exc_info=True)
|
||||
return False
|
||||
|
||||
|
|
|
@ -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-08-13 12:11+0000\n"
|
||||
"PO-Revision-Date: 2012-10-24 05:09+0000\n"
|
||||
"Last-Translator: Chertykov Denis <chertykov@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-10-19 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-25 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16179)\n"
|
||||
|
||||
#. module: document_page
|
||||
#: field:document.page.type,template:0
|
||||
|
@ -270,7 +270,7 @@ msgstr "История всех страниц"
|
|||
#. 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
|
||||
|
@ -285,7 +285,7 @@ msgstr "Закрыть"
|
|||
#. 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 "Это существенные изменения ?"
|
|||
#: 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 "Типы документов"
|
||||
|
||||
#. module: document_page
|
||||
#: view:document.page:0
|
||||
|
@ -374,7 +374,7 @@ msgstr "Изменено"
|
|||
#: field:document.page,type:0
|
||||
#, python-format
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
msgstr "Тип"
|
||||
|
||||
#. module: document_page
|
||||
#: view:document.page.type:0 view:document.page.page.open:0
|
||||
|
|
|
@ -29,7 +29,7 @@ _logger = logging.getLogger(__name__)
|
|||
try:
|
||||
import controllers
|
||||
except ImportError:
|
||||
_logger.warn(
|
||||
_logger.warning(
|
||||
"""Could not load openerp-web section of EDI, EDI will not behave correctly
|
||||
|
||||
To fix, launch openerp-web in embedded mode""")
|
||||
|
|
|
@ -165,11 +165,8 @@ class test_message_compose(test_mail.TestMailMockups):
|
|||
self.assertEqual(message_pigs.body, _body_html1, 'mail.message body on Pigs incorrect')
|
||||
self.assertEqual(message_bird.body, _body_html2, 'mail.message body on Bird incorrect')
|
||||
# Test: partner_ids: p_a_id (default) + 3 newly created partners
|
||||
message_pigs_pids = [partner.id for partner in message_pigs.partner_ids]
|
||||
message_bird_pids = [partner.id for partner in message_bird.partner_ids]
|
||||
message_pigs_pids = [partner.id for partner in message_pigs.notified_partner_ids]
|
||||
message_bird_pids = [partner.id for partner in message_bird.notified_partner_ids]
|
||||
partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
|
||||
self.assertEqual(len(message_pigs_pids), len(partner_ids), 'mail.message on pigs incorrect number of partner_ids')
|
||||
self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of partner_ids')
|
||||
|
||||
self.assertEqual(len(message_bird_pids), len(partner_ids), 'mail.message on bird partner_ids incorrect')
|
||||
self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird partner_ids incorrect')
|
||||
self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of notified_partner_ids')
|
||||
self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird notified_partner_ids incorrect')
|
||||
|
|
|
@ -201,7 +201,7 @@ class event_event(osv.osv):
|
|||
('confirm', 'Confirmed'),
|
||||
('done', 'Done')],
|
||||
'Status', readonly=True, required=True,
|
||||
help='If event is created, the state is \'Draft\'.If event is confirmed for the particular dates the state is set to \'Confirmed\'. If the event is over, the state is set to \'Done\'.If event is cancelled the state is set to \'Cancelled\'.'),
|
||||
help='If event is created, the status is \'Draft\'.If event is confirmed for the particular dates the status is set to \'Confirmed\'. If the event is over, the status is set to \'Done\'.If event is cancelled the status is set to \'Cancelled\'.'),
|
||||
'email_registration_id' : fields.many2one('email.template','Registration Confirmation Email', help='This field contains the template of the mail that will be automatically sent each time a registration for this event is confirmed.'),
|
||||
'email_confirmation_id' : fields.many2one('email.template','Event Confirmation Email', help="If you set an email template, each participant will receive this email announcing the confirmation of the event."),
|
||||
'reply_to': fields.char('Reply-To Email', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."),
|
||||
|
@ -330,7 +330,7 @@ class event_registration(osv.osv):
|
|||
_inherit = ['ir.needaction_mixin','mail.thread']
|
||||
_columns = {
|
||||
'id': fields.integer('ID'),
|
||||
'origin': fields.char('Source', size=124,readonly=True,help="Name of the sale order which create the registration"),
|
||||
'origin': fields.char('Source Document', size=124,readonly=True,help="Name of the sale order which create the registration"),
|
||||
'nb_register': fields.integer('Number of Participants', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'event_id': fields.many2one('event.event', 'Event', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
id="event_main_menu"
|
||||
groups="base.group_user"
|
||||
sequence="80"/>
|
||||
<menuitem name="Events Organisation" id="base.menu_event_main" parent="event_main_menu"/>
|
||||
<menuitem name="Events Organization" id="base.menu_event_main" parent="event_main_menu"/>
|
||||
|
||||
<!-- EVENTS -->
|
||||
|
||||
|
@ -219,7 +219,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<tree string="Events" fonts="bold:message_unread==True" colors="red:(register_min and register_min>register_current) or (register_max and register_max<register_current);grey:state=='cancel'">
|
||||
<field name="name" string="Name"/>
|
||||
<field name="type"/>
|
||||
<field name="type" string="Event Category"/>
|
||||
<field name="date_begin"/>
|
||||
<field name="date_end"/>
|
||||
<field name="register_current"/>
|
||||
|
@ -267,17 +267,17 @@
|
|||
<t t-if="record.country_id.raw_value">@<field name="country_id"/><br/></t>
|
||||
<t t-if="record.user_id.raw_value">Organized by <field name="user_id"/><br/></t>
|
||||
<t t-if="record.register_avail.raw_value lte 10 and record.register_avail.raw_value gt 0"><i>Only</i></t>
|
||||
<t t-if="record.register_avail.raw_value == 0"><i>No ticket available.</i></t>
|
||||
<t t-if="record.register_avail.raw_value != 0">
|
||||
<t t-if="record.register_avail.raw_value == 9999"><i>No ticket available.</i></t>
|
||||
<t t-if="record.register_avail.raw_value != 9999">
|
||||
<i><b><t t-if="record.register_avail.raw_value != 9999"><field name="register_avail"/></t></b></i>
|
||||
<i>
|
||||
<t t-if="record.register_avail.raw_value > 1">tickets </t>
|
||||
<t t-if="record.register_avail.raw_value == 1 || !record.register_avail.raw_value > 1">ticket </t>
|
||||
<t t-if="record.register_avail.raw_value lte 1">ticket </t>
|
||||
available.
|
||||
</i>
|
||||
</t>
|
||||
</p>
|
||||
<t t-if="record.register_avail.raw_value != 0">
|
||||
<t t-if="record.register_avail.raw_value gt 0 and record.register_avail.raw_value lt 9999">
|
||||
<t t-if="!record.is_subscribed.raw_value">
|
||||
<input t-att-id="record.id.raw_value" type="text" name="subscribe" class="no_of_seats" value="1" onchange="document.getElementById('btn_sub' +this.id).setAttribute('data-context',JSON.stringify({'ticket':this.value}))"/>
|
||||
<button t-att-id="'btn_sub'+record.id.raw_value" type="object" name="subscribe_to_event" class="oe_subscribe_button">
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<form string="Configure Moodle" version="7.0">
|
||||
<header>
|
||||
<button type="object" name="configure_moodle"
|
||||
string="Configure Moodle" class="oe_highlight" />
|
||||
string="Apply" class="oe_highlight" />
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</header>
|
||||
|
@ -16,12 +16,12 @@
|
|||
<separator string="Server" colspan="4"/>
|
||||
<field name="server_moodle"/>
|
||||
<newline/>
|
||||
<separator string="Connexion with a Token" colspan="4"/>
|
||||
<separator string="Connection with a Token" colspan="4"/>
|
||||
<label string="The easiest way to connect OpenERP with a moodle server is to create a 'token' in Moodle. It will be used to authenticate OpenERP as a trustable application." colspan="4"/>
|
||||
<field name="moodle_token"/>
|
||||
<newline/>
|
||||
<separator string="Connexion with Password and Username" colspan="4"/>
|
||||
<label string="Another approach is to create a user for OpenERP in Moodle. If you do so, make sure that this user has enough access rights" colspan="4"/>
|
||||
<separator string="Connection with username and password" colspan="4"/>
|
||||
<label string="Another approach is to create a user for OpenERP in Moodle. If you do so, make sure that this user has appropriate access rights." colspan="4"/>
|
||||
<field name="moodle_username"/>
|
||||
<field name="moodle_password"/>
|
||||
</group>
|
||||
|
|
|
@ -112,7 +112,7 @@ class hr_job(osv.osv):
|
|||
'requirements': fields.text('Requirements'),
|
||||
'department_id': fields.many2one('hr.department', 'Department'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'state': fields.selection([('open', 'In Position'), ('recruit', 'In Recruitement')], 'Status', readonly=True, required=True,
|
||||
'state': fields.selection([('open', 'No Recruitment'), ('recruit', 'Recruitement in Progress')], 'Status', readonly=True, required=True,
|
||||
help="By default 'In position', set it to 'In Recruitment' if recruitment process is going on for this job position."),
|
||||
}
|
||||
_defaults = {
|
||||
|
|
|
@ -330,8 +330,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Job" version="7.0">
|
||||
<header>
|
||||
<button name="job_recruitement" string="In Recruitement" states="open" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="job_open" string="Recruitment Done" states="recruit" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="job_recruitement" string="Launch Recruitement" states="open" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="job_open" string="Stop Recruitment" states="recruit" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="recruit,open"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
|
|
@ -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-08-18 17:32+0000\n"
|
||||
"Last-Translator: Heling Yao <Unknown>\n"
|
||||
"PO-Revision-Date: 2012-10-25 16:29+0000\n"
|
||||
"Last-Translator: fenshuajiang <openerp@126.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-10-19 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_openerpuser0
|
||||
|
@ -181,7 +181,7 @@ msgstr "女性"
|
|||
#: help:hr.job,expected_employees:0
|
||||
msgid ""
|
||||
"Expected number of employees for this job position after new recruitment."
|
||||
msgstr ""
|
||||
msgstr "新的招聘后这个工作岗位上期望的员工人数"
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
|
||||
|
@ -685,7 +685,7 @@ msgstr "下属"
|
|||
#. module: hr
|
||||
#: field:hr.job,no_of_employee:0
|
||||
msgid "Number of employees currently occupying this job position."
|
||||
msgstr ""
|
||||
msgstr "这个工作岗位上现有的员工人数"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,no_of_recruitment:0
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2012-05-10 17:47+0000\n"
|
||||
"Last-Translator: Jeff Wang <wjfonhand@hotmail.com>\n"
|
||||
"PO-Revision-Date: 2012-10-25 17:16+0000\n"
|
||||
"Last-Translator: ccdos <Unknown>\n"
|
||||
"Language-Team: Chinese (Simplified) <zh_CN@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-19 05:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: hr_evaluation
|
||||
#: help:hr_evaluation.plan.phase,send_anonymous_manager:0
|
||||
|
@ -304,7 +304,7 @@ msgstr "上个月完成的评估"
|
|||
#. module: hr_evaluation
|
||||
#: model:ir.model,name:hr_evaluation.model_mail_compose_message
|
||||
msgid "Email composition wizard"
|
||||
msgstr ""
|
||||
msgstr "电子邮件撰写向导"
|
||||
|
||||
#. module: hr_evaluation
|
||||
#: view:hr.evaluation.report:0
|
||||
|
|
|
@ -64,15 +64,15 @@ class hr_expense_expense(osv.osv):
|
|||
_description = "Expense"
|
||||
_order = "id desc"
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=128, required=True),
|
||||
'name': fields.char('Description', size=128),
|
||||
'id': fields.integer('Sheet ID', readonly=True),
|
||||
'date': fields.date('Date', select=True),
|
||||
'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is done."),
|
||||
'employee_id': fields.many2one('hr.employee', "Employee", required=True),
|
||||
'user_id': fields.many2one('res.users', 'User', required=True),
|
||||
'date_confirm': fields.date('Confirmation Date', select=True, help = "Date of the confirmation of the sheet expense. It's filled when the button Confirm is pressed."),
|
||||
'date_valid': fields.date('Validation Date', select=True, help = "Date of the acceptation of the sheet expense. It's filled when the button Accept is pressed."),
|
||||
'user_valid': fields.many2one('res.users', 'Validation User'),
|
||||
'date_confirm': fields.date('Confirmation Date', select=True, help="Date of the confirmation of the sheet expense. It's filled when the button Confirm is pressed."),
|
||||
'date_valid': fields.date('Validation Date', select=True, help="Date of the acceptation of the sheet expense. It's filled when the button Accept is pressed."),
|
||||
'user_valid': fields.many2one('res.users', 'Validation By'),
|
||||
'account_move_id': fields.many2one('account.move', 'Ledger Posting'),
|
||||
'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ),
|
||||
'note': fields.text('Note'),
|
||||
|
@ -189,7 +189,7 @@ class hr_expense_expense(osv.osv):
|
|||
raise osv.except_osv(_('Error!'), _('The employee must have a home address.'))
|
||||
acc = exp.employee_id.address_home_id.property_account_payable.id
|
||||
voucher = {
|
||||
'name': exp.name,
|
||||
'name': exp.name or '/',
|
||||
'reference': sequence_obj.get(cr, uid, 'hr.expense.invoice'),
|
||||
'account_id': acc,
|
||||
'type': 'purchase',
|
||||
|
@ -233,7 +233,7 @@ hr_expense_expense()
|
|||
class product_product(osv.osv):
|
||||
_inherit = "product.product"
|
||||
_columns = {
|
||||
'hr_expense_ok': fields.boolean('Can Constitute an Expense', help="Determines if the product can be visible in the list of product within a selection from an HR expense sheet line."),
|
||||
'hr_expense_ok': fields.boolean('Can be Expensed', help="Determines if the product can be visible in the list of product within a selection from an HR expense sheet line."),
|
||||
}
|
||||
|
||||
def on_change_hr_expense_ok(self, cr, uid, id, hr_expense_ok):
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
</group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="user_valid"/>
|
||||
<field name="user_valid" attrs="{'invisible': [('state','=','draft')]}"/>
|
||||
<field name="currency_id" groups="base.group_multi_currency" on_change="onchange_currency_id(currency_id, company_id)"/>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -128,9 +128,9 @@
|
|||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Other Info">
|
||||
<page string="Accounting" groups="account.group_account_user">
|
||||
<group>
|
||||
<group string="Accounting Data" groups="account.group_account_user">
|
||||
<group string="Accounting Data">
|
||||
<field name="journal_id" widget="selection" domain="[('type', '=', 'purchase')]"/>
|
||||
<field name="voucher_id" context="{'form_view_ref': 'account_voucher.view_purchase_receipt_form'}"/>
|
||||
</group>
|
||||
|
|
|
@ -115,10 +115,10 @@ class hr_holidays(osv.osv):
|
|||
_columns = {
|
||||
'name': fields.char('Description', size=64),
|
||||
'state': fields.selection([('draft', 'To Submit'), ('cancel', 'Cancelled'),('confirm', 'To Approve'), ('refuse', 'Refused'), ('validate1', 'Second Approval'), ('validate', 'Approved')],
|
||||
'State', readonly=True, help='The state is set to \'To Submit\', when a holiday request is created.\
|
||||
\nThe state is \'To Approve\', when holiday request is confirmed by user.\
|
||||
\nThe state is \'Refused\', when holiday request is refused by manager.\
|
||||
\nThe state is \'Approved\', when holiday request is approved by manager.'),
|
||||
'Status', readonly=True, help='The status is set to \'To Submit\', when a holiday request is created.\
|
||||
\nThe status is \'To Approve\', when holiday request is confirmed by user.\
|
||||
\nThe status is \'Refused\', when holiday request is refused by manager.\
|
||||
\nThe status is \'Approved\', when holiday request is approved by manager.'),
|
||||
'user_id':fields.related('employee_id', 'user_id', type='many2one', relation='res.users', string='User', store=True),
|
||||
'date_from': fields.datetime('Start Date', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}, select=True),
|
||||
'date_to': fields.datetime('End Date', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
|
||||
|
|
|
@ -272,10 +272,10 @@ class hr_payslip(osv.osv):
|
|||
('done', 'Done'),
|
||||
('cancel', 'Rejected'),
|
||||
], 'Status', select=True, readonly=True,
|
||||
help='* When the payslip is created the state is \'Draft\'.\
|
||||
\n* If the payslip is under verification, the state is \'Waiting\'. \
|
||||
\n* If the payslip is confirmed then state is set to \'Done\'.\
|
||||
\n* When user cancel payslip the state is \'Rejected\'.'),
|
||||
help='* When the payslip is created the status is \'Draft\'.\
|
||||
\n* If the payslip is under verification, the status is \'Waiting\'. \
|
||||
\n* If the payslip is confirmed then status is set to \'Done\'.\
|
||||
\n* When user cancel payslip the status is \'Rejected\'.'),
|
||||
# 'line_ids': fields.one2many('hr.payslip.line', 'slip_id', 'Payslip Line', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'line_ids': one2many_mod2('hr.payslip.line', 'slip_id', 'Payslip Lines', readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
|
|
|
@ -62,7 +62,7 @@ class hr_recruitment_stage(osv.osv):
|
|||
'name': fields.char('Name', size=64, required=True, translate=True),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of stages."),
|
||||
'department_id':fields.many2one('hr.department', 'Specific to a Department', help="Stages of the recruitment process may be different per department. If this stage is common to all departments, keep this field empty."),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'State', required=True, help="The related state for the stage. The state of your document will automatically change according to the selected stage. Example, a stage is related to the state 'Close', when your document reach this stage, it will be automatically closed."),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'Status', required=True, help="The related status for the stage. The status of your document will automatically change according to the selected stage. Example, a stage is related to the status 'Close', when your document reach this stage, it will be automatically closed."),
|
||||
'fold': fields.boolean('Hide in views if empty', help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
|
||||
'requirements': fields.text('Requirements'),
|
||||
}
|
||||
|
@ -189,11 +189,11 @@ class hr_applicant(base_stage, osv.Model):
|
|||
'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage',
|
||||
domain="['&', ('fold', '=', False), '|', ('department_id', '=', department_id), ('department_id', '=', False)]"),
|
||||
'state': fields.related('stage_id', 'state', type="selection", store=True,
|
||||
selection=AVAILABLE_STATES, string="State", readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
If the case is in progress the state is set to \'Open\'.\
|
||||
When the case is over, the state is set to \'Done\'.\
|
||||
If the case needs to be reviewed then the state is \
|
||||
selection=AVAILABLE_STATES, string="Status", readonly=True,
|
||||
help='The status is set to \'Draft\', when a case is created.\
|
||||
If the case is in progress the status is set to \'Open\'.\
|
||||
When the case is over, the status is set to \'Done\'.\
|
||||
If the case needs to be reviewed then the status is \
|
||||
set to \'Pending\'.'),
|
||||
'categ_ids': fields.many2many('hr.applicant_category', string='Tags'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
<form string="Jobs - Recruitment Form" version="7.0">
|
||||
<header>
|
||||
<button name="case_close_with_emp" string="Hire" type="object"
|
||||
states="draft,open,pending" class="oe_highlight"/>
|
||||
states="draft,open,pending,done" class="oe_highlight"/>
|
||||
<button name="case_cancel" string="Refuse" type="object"
|
||||
states="draft,open,pending" class="oe_highlight"/>
|
||||
<field name="stage_id" widget="statusbar" clickable="True"/>
|
||||
|
|
|
@ -41,7 +41,7 @@ class hr_recruitment_report(osv.osv):
|
|||
_columns = {
|
||||
'user_id': fields.many2one('res.users', 'User', readonly=True),
|
||||
'nbr': fields.integer('# of Applications', readonly=True),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
|
||||
'month':fields.selection([('01', 'January'), ('02', 'February'), \
|
||||
('03', 'March'), ('04', 'April'),\
|
||||
('05', 'May'), ('06', 'June'), \
|
||||
|
|
|
@ -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:19+0000\n"
|
||||
"Last-Translator: Jeff Wang <wjfonhand@hotmail.com>\n"
|
||||
"PO-Revision-Date: 2012-10-25 17:20+0000\n"
|
||||
"Last-Translator: ccdos <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-10-19 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16165)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-26 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 16194)\n"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: code:addons/hr_timesheet/report/user_timesheet.py:43
|
||||
|
@ -468,7 +468,7 @@ msgstr "一般信息"
|
|||
#. module: hr_timesheet
|
||||
#: model:ir.actions.act_window,name:hr_timesheet.action_hr_timesheet_my
|
||||
msgid "My Current Timesheet"
|
||||
msgstr ""
|
||||
msgstr "我当前的时间表"
|
||||
|
||||
#. module: hr_timesheet
|
||||
#: code:addons/hr_timesheet/report/user_timesheet.py:40
|
||||
|
|
|
@ -33,7 +33,7 @@ class hr_so_project(osv.osv_memory):
|
|||
'date': fields.datetime('Closing Date'),
|
||||
'analytic_amount': fields.float('Minimum Analytic Amount'),
|
||||
'name': fields.char('Employees name', size=32, required=True, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current state', type='char', required=True, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current Status', type='char', required=True, readonly=True),
|
||||
'server_date': fields.datetime('Current Date', required=True, readonly=True),
|
||||
'emp_id': fields.many2one('hr.employee', 'Employee ID')
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ class hr_si_project(osv.osv_memory):
|
|||
_description = 'Sign In By Project'
|
||||
_columns = {
|
||||
'name': fields.char('Employees name', size=32, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current state', type='char', required=True, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current Status', type='char', required=True, readonly=True),
|
||||
'date': fields.datetime('Starting Date'),
|
||||
'server_date': fields.datetime('Current Date', readonly=True),
|
||||
'emp_id': fields.many2one('hr.employee', 'Employee ID')
|
||||
|
|
|
@ -206,9 +206,9 @@ class hr_timesheet_sheet(osv.osv):
|
|||
('draft','Open'),
|
||||
('confirm','Waiting Approval'),
|
||||
('done','Approved')], 'Status', select=True, required=True, readonly=True,
|
||||
help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed timesheet. \
|
||||
\n* The \'Confirmed\' state is used for to confirm the timesheet by user. \
|
||||
\n* The \'Done\' state is used when users timesheet is accepted by his/her senior.'),
|
||||
help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed timesheet. \
|
||||
\n* The \'Confirmed\' status is used for to confirm the timesheet by user. \
|
||||
\n* The \'Done\' status is used when users timesheet is accepted by his/her senior.'),
|
||||
'state_attendance' : fields.related('employee_id', 'state', type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Current Status', readonly=True),
|
||||
'total_attendance': fields.function(_total, method=True, string='Total Attendance', multi="_total"),
|
||||
'total_timesheet': fields.function(_total, method=True, string='Total Timesheet', multi="_total"),
|
||||
|
|
|
@ -54,18 +54,18 @@
|
|||
</header>
|
||||
<sheet>
|
||||
<label for="employee_id" class="oe_edit_only"/>
|
||||
<h1><field name="employee_id" on_change="onchange_employee_id(employee_id)"/></h1>
|
||||
<h1><field name="employee_id" on_change="onchange_employee_id(employee_id)" class="oe_inline"/></h1>
|
||||
<group>
|
||||
<group>
|
||||
<label for="date_from" string="Timesheet Period"/>
|
||||
<div><field name="date_from"/> to <field name="date_to"/></div>
|
||||
<div><field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/></div>
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="department_id"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="total_attendance" widget="float_time" groups="base.group_hr_attendance"/>
|
||||
<field name="total_timesheet" widget="float_time"/>
|
||||
<field name="total_timesheet" widget="float_time" groups="base.group_hr_attendance"/>
|
||||
<field name="total_difference" widget="float_time" groups="base.group_hr_attendance"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
</group>
|
||||
|
@ -76,8 +76,8 @@
|
|||
</widget>
|
||||
</page>
|
||||
<page string="Daily">
|
||||
<group colspan="4" col="3">
|
||||
<field context="{'user_id':user_id}" name="attendances_ids" nolabel="1" groups="base.group_hr_attendance">
|
||||
<group groups="base.group_hr_attendance">
|
||||
<field context="{'user_id':user_id}" name="attendances_ids" nolabel="1">
|
||||
<tree string="Attendances" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="action"/>
|
||||
|
@ -85,21 +85,19 @@
|
|||
</tree>
|
||||
</field>
|
||||
<group>
|
||||
<div align="right" groups="base.group_hr_manager,base.group_hr_attendance">
|
||||
<button name="attendance_action_change" attrs="{'invisible': [('state_attendance', '=', 'present')]}" type="object" string="Sign In" groups="base.group_hr_attendance"/>
|
||||
<button name="attendance_action_change" attrs="{'invisible': ['|', ('state_attendance','=',False), ('state_attendance', '=', 'absent')]}" type="object" string="Sign Out" groups="base.group_hr_attendance"/>
|
||||
<field name="state_attendance" nolabel="1"/>
|
||||
<div align="right" groups="base.group_hr_manager">
|
||||
<button name="attendance_action_change" attrs="{'invisible': [('state_attendance', '=', 'present')]}" type="object" string="Sign In"/>
|
||||
<button name="attendance_action_change" attrs="{'invisible': ['|', ('state_attendance','=',False), ('state_attendance', '=', 'absent')]}" type="object" string="Sign Out"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group col="4">
|
||||
<field name="state_attendance" groups="base.group_hr_attendance"/>
|
||||
</group>
|
||||
<field colspan="4" context="{'user_id':user_id}" name="timesheet_ids" nolabel="1">
|
||||
<field context="{'user_id':user_id}" name="timesheet_ids" nolabel="1">
|
||||
<tree editable="top" string="Timesheet Lines">
|
||||
<field name="date"/>
|
||||
<field domain="[('type','in',['normal', 'contract']), ('state', '<>', 'close'),('use_timesheets','=',1)]" name="account_id" on_change="on_change_account_id(account_id, user_id)" context="{'default_use_timesheets': 1}"/>
|
||||
<field name="name"/>
|
||||
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time"/>
|
||||
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time" string="Hours"/>
|
||||
<field name="to_invoice" widget="selection"/>
|
||||
<field invisible="1" name="journal_id"/>
|
||||
<field invisible="1" name="product_id" domain="[('type','=','service')]" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
|
||||
|
@ -123,13 +121,13 @@
|
|||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Summary">
|
||||
<field colspan="4" name="period_ids" nolabel="1">
|
||||
<page string="Summary" groups="base.group_hr_attendance">
|
||||
<field name="period_ids">
|
||||
<tree colors="red:total_difference<0.1;blue:total_difference>=0.1" string="Period">
|
||||
<field name="name"/>
|
||||
<field name="total_attendance" widget="float_time" groups="base.group_hr_attendance"/>
|
||||
<field name="total_attendance" widget="float_time"/>
|
||||
<field name="total_timesheet" widget="float_time"/>
|
||||
<field name="total_difference" widget="float_time" groups="base.group_hr_attendance"/>
|
||||
<field name="total_difference" widget="float_time"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<t t-esc="date.toString('MMM d')"/>
|
||||
</th>
|
||||
</t>
|
||||
<th class="oe_timesheet_weekly_date_head">TOTAL</th>
|
||||
<th class="oe_timesheet_weekly_date_head">Total</th>
|
||||
</tr>
|
||||
<tr t-foreach="widget.accounts" t-as="account">
|
||||
<td class="oe_timesheet_weekly_account"><t t-esc="widget.account_names[account.account]"/></td>
|
||||
|
@ -36,8 +36,8 @@
|
|||
<tr>
|
||||
<td>
|
||||
<div class="oe_timesheet_weekly_adding_tot">
|
||||
<div class="oe_timesheet_weekly_adding"><button>Add Row</button></div>
|
||||
<div class="oe_timesheet_weekly_tottot"><span>TOTAL</span></div>
|
||||
<div class="oe_timesheet_weekly_adding"><button>Add a Project</button></div>
|
||||
<div class="oe_timesheet_weekly_tottot"><span>Total</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<t t-set="day_count" t-value="0"/>
|
||||
|
@ -53,4 +53,4 @@
|
|||
</table>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</templates>
|
||||
|
|
|
@ -2,13 +2,9 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_ar" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_at" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
-
|
||||
!record {model: ir.actions.todo, id: config_call_account_template}:
|
||||
action_id: account.action_wizard_multi_chart
|
||||
type: automatic
|
||||
-
|
||||
!python {model: ir.actions.todo}: |
|
||||
install_todo = self.browse(cr, uid, ref('l10n_be.config_call_account_template'))
|
||||
install_todo = self.browse(cr, uid, ref('account.action_wizard_multi_chart_todo'))
|
||||
if install_todo.state == 'open':
|
||||
wiz = self.pool.get('wizard.multi.charts.accounts')
|
||||
values = {
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_ca" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<record id="config_call_account_template_l10n_ch" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts for l10n_ch</field>
|
||||
<field name="note">Generate Chart of Accounts from a Chart Template. Please let the nuber to 0 for Swiss charts.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial
|
||||
Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_cl" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_cn_chart" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template" model="ir.actions.todo">
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_de" model="ir.actions.todo">
|
||||
<field name="name">Generiert Kontenplan aus Vorlage</field>
|
||||
<field name="note">Der Assistent generiert einen Kontenplan auf Basis eines Templates (Vorlage). Sie werden aufgefordert den Namen der Firma einzugeben, sowie die entsprechende Kontenvorlage zu wählen. Ausserdem können Sie für die Initialisierung der Journale die gewünschte Stellenanzahl der Konten, sowie die Hauptwährung Ihres Betriebes auswählen. Dieser Assistent ist identisch mit dem Open ERP Menü Finanzen/Konfiguration/Finanzkonten/Erzeuge Konten aus Vorlage.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_ec" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="config_call_account_template" model="ir.actions.todo">
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- This ir.actions.todo triggers the screen "Generate your chart of account
|
||||
from a chart template" in the install wizard of the l10n_fr module -->
|
||||
<record id="config_call_account_template_fr" model="ir.actions.todo">
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_gr" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="config_call_account_template_gt_minimal" model="ir.actions.todo">
|
||||
<field name="name">Generar la nomenclatura contable a partir de un modelo</field>
|
||||
<field name="note">Generar la nomenclatura contable a partir de un modelo. Deberá seleccionar una compañía, el modelo a utilizar, el número de digitos a usar en la nomenclatura, la moneda para crear los diarios.</field>
|
||||
<!--<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>-->
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
<!-- Moneda Quetzal -->
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="config_call_account_template_hn_minimal" model="ir.actions.todo">
|
||||
<field name="name">Generar la nomenclatura contable a partir de un modelo</field>
|
||||
<field name="note">Generar la nomenclatura contable a partir de un modelo. Deberá seleccionar una compañía, el modelo a utilizar, el número de digitos a usar en la nomenclatura, la moneda para crear los diarios.</field>
|
||||
<!--<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>-->
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_in_minimal" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -65,7 +65,7 @@ class payroll_advice(osv.osv):
|
|||
('draft', 'Draft'),
|
||||
('confirm', 'Confirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
], 'State', select=True, readonly=True),
|
||||
], 'Status', select=True, readonly=True),
|
||||
'number':fields.char('Reference', size=16, readonly=True),
|
||||
'line_ids':fields.one2many('hr.payroll.advice.line', 'advice_id', 'Employee Salary', states={'draft': [('readonly', False)]}, readonly=True),
|
||||
'chaque_nos':fields.char('Cheque Numbers', size=256),
|
||||
|
|
|
@ -38,7 +38,7 @@ class payment_advice_report(osv.osv):
|
|||
('draft', 'Draft'),
|
||||
('confirm', 'Confirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
], 'State', select=True, readonly=True),
|
||||
], 'Status', select=True, readonly=True),
|
||||
'employee_id': fields.many2one('hr.employee', 'Employee', readonly=True),
|
||||
'nbr': fields.integer('# Payment Lines', readonly=True),
|
||||
'number':fields.char('Number', size=16, readonly=True),
|
||||
|
|
|
@ -39,7 +39,7 @@ class payslip_report(osv.osv):
|
|||
('draft', 'Draft'),
|
||||
('done', 'Done'),
|
||||
('cancel', 'Rejected'),
|
||||
], 'State', readonly=True),
|
||||
], 'Status', readonly=True),
|
||||
'employee_id': fields.many2one('hr.employee', 'Employee', readonly=True),
|
||||
'nbr': fields.integer('# Payslip lines', readonly=True),
|
||||
'number': fields.char('Number', size=16, readonly=True),
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_generic" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_lu" model="ir.actions.todo">
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_ma" model="ir.actions.todo">
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-23 04:48+0000\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-24 04:55+0000\n"
|
||||
"X-Generator: Launchpad (build 16179)\n"
|
||||
|
||||
#. module: l10n_mx
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_mx_chart" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template" model="ir.actions.todo">
|
||||
<field name="name">Genereer Grootboekrekingschema vanuit het Nederlandse Grootboek Template</field>
|
||||
<field name="note">Na installatie van deze module word de configuratie wizard voor "Accounting" aangeroepen.
|
||||
* U krijgt een lijst met grootboektemplates aangeboden waarin zich ook het Nederlandse grootboekschema bevind.
|
||||
* Als de configuratie wizard start, wordt u gevraagd om de naam van uw bedrijf in te voeren, welke grootboekschema te installeren, uit hoeveel cijfers een grootboekrekening mag bestaan, het rekeningnummer van uw bank en de currency om Journalen te creeren.
|
||||
|
||||
Let op!! -> De template van het Nederlandse rekeningschema is opgebouwd uit 4 cijfers. Dit is het minimale aantal welk u moet invullen, u mag het aantal verhogen. De extra cijfers worden dan achter het rekeningnummer aangevult met "nullen"
|
||||
|
||||
* Dit is dezelfe configuratie wizard welke aangeroepen kan worden via Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.
|
||||
</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_pe" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_pl_chart" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_ro" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<record id="config_call_account_template_syscohada" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">Generate Chart of Accounts from a SYSCOHADA Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -643,14 +643,9 @@
|
|||
</record>
|
||||
|
||||
<!-- INSTALL ACTION -->
|
||||
|
||||
<record id="config_call_account_template_th" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp><!-- vim: set fdm=marker : -->
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="config_call_account_template_tr_chart" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial
|
||||
Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,41 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_wizard_multi_chart_uk" model="ir.ui.view">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="model">wizard.multi.charts.accounts</field>
|
||||
<field name="inherit_id" ref="account.view_wizard_multi_chart"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<!--
|
||||
<xpath expr="//group[@string='res_config_contents']/separator" position="attributes">
|
||||
<attribute name="string">
|
||||
Generate Your UK Accounting Chart from a Chart Template
|
||||
</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//group[@string='res_config_contents']/label" position="attributes">
|
||||
<attribute name="string">SELECT 4 DIGIT ACCOUNTS. This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/ Financial Accounts/Generate Chart of Accounts from a Chart Template.</attribute>
|
||||
</xpath>
|
||||
-->
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_wizard_multi_chart_uk" model="ir.actions.act_window">
|
||||
<field name="name">Generate UK Chart of Accounts from a Chart Template</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">wizard.multi.charts.accounts</field>
|
||||
<field name="view_id" ref="view_wizard_multi_chart_uk"/>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record id="l10n_uk_latest_wizard_id" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_wizard_multi_chart_uk"/>
|
||||
<field name="sequence">10</field>
|
||||
<field name="type">once</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="config_call_account_template_uy" model="ir.actions.todo">
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="config_call_account_template_ve_chart" model="ir.actions.todo">
|
||||
<field name="name">Generate Chart of Accounts from a Chart Template</field>
|
||||
<field name="note">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.
|
||||
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.
|
||||
Genere el Plan de cuentas de una Plantilla de Carta. Le pedirán pasar el nombre de la compania, la plantilla de carta para seguir, el no. de digitos para generar el codigo para sus cuentas y cuenta Bancaria, dinero para crear Diarios. Asi, la copia pura de la carta la Plantilla es generada.
|
||||
Esto es el mismo wizard que corre de la Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.
|
||||
</field>
|
||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||
<field name="type">automatic</field>
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<field name="body">Your monthly meal vouchers arrived. You can get them at Christine's office.
|
||||
This month you also get 250 EUR of eco-vouchers if you have been in the company for more than a year.</field>
|
||||
<field name="type">comment</field>
|
||||
<field name="subtype_id" ref="mt_comment"/>
|
||||
</record>
|
||||
|
||||
<record id="message_blogpost0_comment0" model="mail.message">
|
||||
|
@ -16,6 +17,7 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
|
|||
<field name="body"><![CDATA[Great.]]></field>
|
||||
<field name="parent_id" ref="message_blogpost0"/>
|
||||
<field name="type">comment</field>
|
||||
<field name="subtype_id" ref="mt_comment"/>
|
||||
</record>
|
||||
|
||||
<record id="message_blogpost0_comment1" model="mail.message">
|
||||
|
@ -24,22 +26,25 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
|
|||
<field name="body">Thanks, but where is Christine's office, if I may ask? (I'm new here)</field>
|
||||
<field name="parent_id" ref="message_blogpost0"/>
|
||||
<field name="type">comment</field>
|
||||
<field name="subtype_id" ref="mt_comment"/>
|
||||
</record>
|
||||
|
||||
<record id="message_blogpost0_comment2" model="mail.message">
|
||||
<field name="model">mail.group</field>
|
||||
<field name="res_id" ref="group_all_employees"/>
|
||||
<field name="body">Building B3, second floor on the right :-)</field>
|
||||
<field name="parent_id" ref="message_blogpost0"/>
|
||||
<field name="type">comment</field>
|
||||
<field name="subtype_id" ref="mt_comment"/>
|
||||
</record>
|
||||
|
||||
<record id="message_blogpost0_comment3" model="mail.message">
|
||||
<field name="model">mail.group</field>
|
||||
<field name="res_id" ref="group_all_employees"/>
|
||||
<field name="body">Great news, I need to buy a new fridge, I think I can pay it with the eco-vouchers!</field>
|
||||
<field name="parent_id" ref="message_blogpost0"/>
|
||||
<field name="type">comment</field>
|
||||
</record>
|
||||
|
||||
<record id="message_blogpost0_comment1_2" model="mail.message">
|
||||
<field name="model">mail.group</field>
|
||||
<field name="res_id" ref="group_all_employees"/>
|
||||
<field name="body">Building B3, second floor on the right :-)</field>
|
||||
<field name="parent_id" ref="message_blogpost0_comment1"/>
|
||||
<field name="type">comment</field>
|
||||
<field name="subtype_id" ref="mt_comment"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -131,7 +131,8 @@ class mail_notification(osv.Model):
|
|||
|
||||
def _notify(self, cr, uid, msg_id, context=None):
|
||||
""" Send by email the notification depending on the user preferences """
|
||||
context = context or {}
|
||||
if context is None:
|
||||
context = {}
|
||||
# mail_noemail (do not send email) or no partner_ids: do not send, return
|
||||
if context.get('mail_noemail'):
|
||||
return True
|
||||
|
@ -141,9 +142,15 @@ class mail_notification(osv.Model):
|
|||
if not notify_partner_ids:
|
||||
return True
|
||||
|
||||
# add the context in the email
|
||||
# TDE FIXME: commented, to be improved in a future branch
|
||||
# quote_context = self.pool.get('mail.message').message_quote_context(cr, uid, msg_id, context=context)
|
||||
|
||||
mail_mail = self.pool.get('mail.mail')
|
||||
# add signature
|
||||
body_html = msg.body
|
||||
# if quote_context:
|
||||
# body_html = tools.append_content_to_html(body_html, quote_context, plaintext=False)
|
||||
signature = msg.author_id and msg.author_id.user_ids[0].signature or ''
|
||||
if signature:
|
||||
body_html = tools.append_content_to_html(body_html, signature)
|
||||
|
|
|
@ -24,11 +24,17 @@ import tools
|
|||
|
||||
from email.header import decode_header
|
||||
from openerp import SUPERUSER_ID
|
||||
from osv import osv, orm, fields
|
||||
from tools.translate import _
|
||||
from openerp.osv import osv, orm, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from mako.template import Template as MakoTemplate
|
||||
except ImportError:
|
||||
_logger.warning("payment_acquirer: mako templates not available, payment acquirer will not work!")
|
||||
|
||||
|
||||
""" Some tools for parsing / creating email fields """
|
||||
def decode(text):
|
||||
"""Returns unicode() string conversion of the the given encoded smtp header text"""
|
||||
|
@ -45,8 +51,8 @@ class mail_message(osv.Model):
|
|||
_inherit = ['ir.needaction_mixin']
|
||||
_order = 'id desc'
|
||||
|
||||
_message_read_limit = 15
|
||||
_message_read_fields = ['id', 'parent_id', 'model', 'res_id', 'body', 'subject', 'date', 'to_read',
|
||||
_message_read_limit = 10
|
||||
_message_read_fields = ['id', 'parent_id', 'model', 'res_id', 'body', 'subject', 'date', 'to_read', 'email_from',
|
||||
'type', 'vote_user_ids', 'attachment_ids', 'author_id', 'partner_ids', 'record_name', 'favorite_user_ids']
|
||||
_message_record_name_length = 18
|
||||
_message_read_more_limit = 1024
|
||||
|
@ -57,17 +63,13 @@ class mail_message(osv.Model):
|
|||
return name[:self._message_record_name_length] + '...'
|
||||
|
||||
def _get_record_name(self, cr, uid, ids, name, arg, context=None):
|
||||
""" Return the related document name, using name_get. It is included in
|
||||
a try/except statement, because if uid cannot read the related
|
||||
document, he should see a void string instead of crashing. """
|
||||
""" Return the related document name, using name_get. It is done using
|
||||
SUPERUSER_ID, to be sure to have the record name correctly stored. """
|
||||
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']:
|
||||
if not message.get('model') or not message.get('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])
|
||||
except (orm.except_orm, osv.except_osv):
|
||||
pass
|
||||
result[message['id']] = self._shorten_name(self.pool.get(message['model']).name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1])
|
||||
return result
|
||||
|
||||
def _get_to_read(self, cr, uid, ids, name, arg, context=None):
|
||||
|
@ -114,16 +116,21 @@ class mail_message(osv.Model):
|
|||
], 'Type',
|
||||
help="Message type: email for email message, notification for system "\
|
||||
"message, comment for other messages such as user replies"),
|
||||
'author_id': fields.many2one('res.partner', 'Author', required=True),
|
||||
'partner_ids': fields.many2many('res.partner', 'mail_notification', 'message_id', 'partner_id', 'Recipients'),
|
||||
'email_from': fields.char('From',
|
||||
help="Email address of the sender, to use if it does not match any partner."),
|
||||
'author_id': fields.many2one('res.partner', 'Author',
|
||||
help="Partner that did write the message. If not set, try to use the From field instead."),
|
||||
'partner_ids': fields.many2many('res.partner', string='Recipients'),
|
||||
'notified_partner_ids': fields.many2many('res.partner', 'mail_notification',
|
||||
'message_id', 'partner_id', 'Recipients'),
|
||||
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel',
|
||||
'message_id', 'attachment_id', 'Attachments'),
|
||||
'parent_id': fields.many2one('mail.message', 'Parent Message', select=True, ondelete='set null', help="Initial thread message."),
|
||||
'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'),
|
||||
'model': fields.char('Related Document Model', size=128, select=1),
|
||||
'res_id': fields.integer('Related Document ID', select=1),
|
||||
'record_name': fields.function(_get_record_name, type='string',
|
||||
string='Message Record Name',
|
||||
'record_name': fields.function(_get_record_name, type='char',
|
||||
store=True, string='Message Record Name',
|
||||
help="Name get of the related document."),
|
||||
'notification_ids': fields.one2many('mail.notification', 'message_id', 'Notifications'),
|
||||
'subject': fields.char('Subject'),
|
||||
|
@ -200,6 +207,9 @@ class mail_message(osv.Model):
|
|||
is_author = False
|
||||
if message['author_id']:
|
||||
is_author = message['author_id'][0] == self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
|
||||
author_id = message['author_id']
|
||||
elif message['email_from']:
|
||||
author_id = (0, message['email_from'])
|
||||
|
||||
has_voted = False
|
||||
if uid in message.get('vote_user_ids'):
|
||||
|
@ -209,9 +219,9 @@ class mail_message(osv.Model):
|
|||
if uid in message.get('favorite_user_ids'):
|
||||
is_favorite = True
|
||||
|
||||
is_private = False
|
||||
is_private = True
|
||||
if message.get('model') and message.get('res_id'):
|
||||
is_private = True
|
||||
is_private = False
|
||||
|
||||
try:
|
||||
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)]
|
||||
|
@ -235,11 +245,10 @@ class mail_message(osv.Model):
|
|||
'record_name': message['record_name'],
|
||||
'subject': message['subject'],
|
||||
'date': message['date'],
|
||||
'author_id': message['author_id'],
|
||||
'author_id': author_id,
|
||||
'is_author': is_author,
|
||||
# TDE note: is this useful ? to check
|
||||
'partner_ids': partner_ids,
|
||||
'ancestor_id': False,
|
||||
'parent_id': False,
|
||||
'vote_nb': len(message['vote_user_ids']),
|
||||
'has_voted': has_voted,
|
||||
'is_private': is_private,
|
||||
|
@ -269,12 +278,12 @@ class mail_message(osv.Model):
|
|||
easily have access to their values, given their ID
|
||||
:return bool: True
|
||||
"""
|
||||
def _get_expandable(domain, message_nb, ancestor_id, id, model):
|
||||
def _get_expandable(domain, message_nb, parent_id, id, model):
|
||||
return {
|
||||
'domain': domain,
|
||||
'nb_messages': message_nb,
|
||||
'type': 'expandable',
|
||||
'ancestor_id': ancestor_id,
|
||||
'parent_id': parent_id,
|
||||
'id': id,
|
||||
# TDE note: why do we need model sometimes, and sometimes not ???
|
||||
'model': model,
|
||||
|
@ -282,6 +291,8 @@ class mail_message(osv.Model):
|
|||
|
||||
# all_not_loaded_ids = []
|
||||
id_list = sorted(read_messages.keys())
|
||||
if not id_list:
|
||||
return message_list
|
||||
|
||||
# 1. get the expandable for new threads
|
||||
if thread_level == 0:
|
||||
|
@ -351,7 +362,7 @@ class mail_message(osv.Model):
|
|||
except (orm.except_orm, osv.except_osv):
|
||||
return False
|
||||
|
||||
def message_read(self, cr, uid, ids=False, domain=None, message_unload_ids=None, thread_level=0, context=None, parent_id=False, limit=None):
|
||||
def message_read(self, cr, uid, ids=None, domain=None, message_unload_ids=None, thread_level=0, context=None, parent_id=False, limit=None):
|
||||
""" Read messages from mail.message, and get back a list of structured
|
||||
messages to be displayed as discussion threads. If IDs is set,
|
||||
fetch these records. Otherwise use the domain to fetch messages.
|
||||
|
@ -375,6 +386,13 @@ class mail_message(osv.Model):
|
|||
ancestors and expandables
|
||||
:return list: list of message structure for the Chatter widget
|
||||
"""
|
||||
print domain
|
||||
print message_unload_ids
|
||||
print thread_level
|
||||
print context
|
||||
print parent_id
|
||||
print limit
|
||||
|
||||
assert thread_level in [0, 1], 'message_read() thread_level should be 0 (flat) or 1 (1 level of thread); given %s.' % thread_level
|
||||
domain = domain if domain is not None else []
|
||||
message_unload_ids = message_unload_ids if message_unload_ids is not None else []
|
||||
|
@ -384,34 +402,29 @@ class mail_message(osv.Model):
|
|||
read_messages = {}
|
||||
message_list = []
|
||||
|
||||
# specific IDs given: fetch those ids and return directly the message list
|
||||
if ids:
|
||||
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))
|
||||
message_list = sorted(message_list, key=lambda k: k['id'])
|
||||
return message_list
|
||||
|
||||
# TDE FIXME: check access rights on search are implemented for mail.message
|
||||
# fetch messages according to the domain, add their parents if uid has access to
|
||||
ids = self.search(cr, uid, domain, context=context, limit=limit)
|
||||
# no specific IDS given: fetch messages according to the domain, add their parents if uid has access to
|
||||
if ids is None:
|
||||
ids = self.search(cr, uid, domain, context=context, limit=limit)
|
||||
for message in self.read(cr, uid, ids, self._message_read_fields, context=context):
|
||||
message_id = message['id']
|
||||
|
||||
# if not in tree and not in message_loaded list
|
||||
if not read_messages.get(message.get('id')) and message.get('id') not in message_unload_ids:
|
||||
read_messages[message.get('id')] = message
|
||||
if not message_id in read_messages and not message_id in message_unload_ids:
|
||||
read_messages[message_id] = message
|
||||
message_list.append(self._message_get_dict(cr, uid, message, context=context))
|
||||
|
||||
# get the older ancestor the user can read, update its ancestor field
|
||||
if not thread_level:
|
||||
message_list[-1]['ancestor_id'] = parent_id
|
||||
message_list[-1]['parent_id'] = parent_id
|
||||
continue
|
||||
parent = self._get_parent(cr, uid, message, context=context)
|
||||
while parent and parent.get('id') != parent_id:
|
||||
message_list[-1]['ancestor_id'] = parent.get('id')
|
||||
message_list[-1]['parent_id'] = parent.get('id')
|
||||
message = parent
|
||||
parent = self._get_parent(cr, uid, message, context=context)
|
||||
# if in thread: add its ancestor to the list of messages
|
||||
if not read_messages.get(message.get('id')) and message.get('id') not in message_unload_ids:
|
||||
read_messages[message.get('id')] = message
|
||||
if not message['id'] in read_messages and not message['id'] in message_unload_ids:
|
||||
read_messages[message['id']] = message
|
||||
message_list.append(self._message_get_dict(cr, uid, message, context=context))
|
||||
|
||||
# get the child expandable messages for the tree
|
||||
|
@ -419,6 +432,8 @@ class mail_message(osv.Model):
|
|||
self._message_read_add_expandables(cr, uid, message_list, read_messages, thread_level=thread_level,
|
||||
message_loaded_ids=message_unload_ids, domain=domain, parent_id=parent_id, context=context, limit=limit)
|
||||
|
||||
print message_list
|
||||
|
||||
return message_list
|
||||
|
||||
# TDE Note: do we need this ?
|
||||
|
@ -431,7 +446,7 @@ class mail_message(osv.Model):
|
|||
# return attachment_list
|
||||
|
||||
#------------------------------------------------------
|
||||
# Email api
|
||||
# mail_message internals
|
||||
#------------------------------------------------------
|
||||
|
||||
def init(self, cr):
|
||||
|
@ -439,23 +454,74 @@ class mail_message(osv.Model):
|
|||
if not cr.fetchone():
|
||||
cr.execute("""CREATE INDEX mail_message_model_res_id_idx ON mail_message (model, res_id)""")
|
||||
|
||||
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False, access_rights_uid=None):
|
||||
""" Override that adds specific access rights of mail.message, to remove
|
||||
ids uid could not see according to our custom rules. Please refer
|
||||
to check_access_rule for more details about those rules.
|
||||
|
||||
After having received ids of a classic search, keep only:
|
||||
- if author_id == pid, uid is the author, OR
|
||||
- a notification (id, pid) exists, uid has been notified, OR
|
||||
- uid have read access to the related document is model, res_id
|
||||
- otherwise: remove the id
|
||||
"""
|
||||
# Rules do not apply to administrator
|
||||
if uid == SUPERUSER_ID:
|
||||
return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||
context=context, count=count, access_rights_uid=access_rights_uid)
|
||||
# Perform a super with count as False, to have the ids, not a counter
|
||||
ids = super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||
context=context, count=False, access_rights_uid=access_rights_uid)
|
||||
if not ids and count:
|
||||
return 0
|
||||
elif not ids:
|
||||
return ids
|
||||
|
||||
pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'])['partner_id'][0]
|
||||
author_ids, partner_ids, allowed_ids = set([]), set([]), set([])
|
||||
model_ids = {}
|
||||
|
||||
messages = super(mail_message, self).read(cr, uid, ids, ['author_id', 'model', 'res_id', 'notified_partner_ids'], context=context)
|
||||
for message in messages:
|
||||
if message.get('author_id') and message.get('author_id')[0] == pid:
|
||||
author_ids.add(message.get('id'))
|
||||
elif pid in message.get('notified_partner_ids'):
|
||||
partner_ids.add(message.get('id'))
|
||||
elif message.get('model') and message.get('res_id'):
|
||||
model_ids.setdefault(message.get('model'), {}).setdefault(message.get('res_id'), set()).add(message.get('id'))
|
||||
|
||||
model_access_obj = self.pool.get('ir.model.access')
|
||||
for doc_model, doc_dict in model_ids.iteritems():
|
||||
if not model_access_obj.check(cr, uid, doc_model, 'read', False):
|
||||
continue
|
||||
doc_ids = doc_dict.keys()
|
||||
allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context)
|
||||
allowed_ids |= set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]])
|
||||
|
||||
final_ids = author_ids | partner_ids | allowed_ids
|
||||
if count:
|
||||
return len(final_ids)
|
||||
else:
|
||||
return list(final_ids)
|
||||
|
||||
def check_access_rule(self, cr, uid, ids, operation, context=None):
|
||||
""" Access rules of mail.message:
|
||||
- read: if
|
||||
- notification exist (I receive pushed message) OR
|
||||
- author_id = pid (I am the author) OR
|
||||
- I can read the related document if res_model, res_id
|
||||
- Otherwise: raise
|
||||
- author_id == pid, uid is the author, OR
|
||||
- mail_notification (id, pid) exists, uid has been notified, OR
|
||||
- uid have read access to the related document if model, res_id
|
||||
- otherwise: raise
|
||||
- create: if
|
||||
- I am in the document message_follower_ids OR
|
||||
- I can write on the related document if res_model, res_id OR
|
||||
- I create a private message (no model, no res_id)
|
||||
- Otherwise: raise
|
||||
- no model, no res_id, I create a private message
|
||||
- pid in message_follower_ids if model, res_id OR
|
||||
- uid have write access on the related document if model, res_id, OR
|
||||
- otherwise: raise
|
||||
- write: if
|
||||
- I can write on the related document if res_model, res_id
|
||||
- uid has write access on the related document if model, res_id
|
||||
- Otherwise: raise
|
||||
- unlink: if
|
||||
- I can write on the related document if res_model, res_id
|
||||
- uid has write access on the related document if model, res_id
|
||||
- Otherwise: raise
|
||||
"""
|
||||
if uid == SUPERUSER_ID:
|
||||
|
@ -465,15 +531,25 @@ class mail_message(osv.Model):
|
|||
partner_id = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
|
||||
|
||||
# Read mail_message.ids to have their values
|
||||
model_record_ids = {}
|
||||
message_values = dict.fromkeys(ids)
|
||||
model_record_ids = {}
|
||||
cr.execute('SELECT DISTINCT id, model, res_id, author_id FROM "%s" WHERE id = ANY (%%s)' % self._table, (ids,))
|
||||
for id, rmod, rid, author_id in cr.fetchall():
|
||||
message_values[id] = {'res_model': rmod, 'res_id': rid, 'author_id': author_id}
|
||||
if rmod:
|
||||
model_record_ids.setdefault(rmod, set()).add(rid)
|
||||
model_record_ids.setdefault(rmod, dict()).setdefault(rid, set()).add(id)
|
||||
|
||||
# Read: Check for received notifications -> could become an ir.rule, but not till we do not have a many2one variable field
|
||||
# Author condition, for read and create (private message) -> could become an ir.rule, but not till we do not have a many2one variable field
|
||||
if operation == 'read':
|
||||
author_ids = [mid for mid, message in message_values.iteritems()
|
||||
if message.get('author_id') and message.get('author_id') == partner_id]
|
||||
elif operation == 'create':
|
||||
author_ids = [mid for mid, message in message_values.iteritems()
|
||||
if not message.get('model') and not message.get('res_id')]
|
||||
else:
|
||||
author_ids = []
|
||||
|
||||
# Notification condition, for read (check for received notifications and create (in message_follower_ids)) -> could become an ir.rule, but not till we do not have a many2one variable field
|
||||
if operation == 'read':
|
||||
not_obj = self.pool.get('mail.notification')
|
||||
not_ids = not_obj.search(cr, SUPERUSER_ID, [
|
||||
|
@ -481,38 +557,24 @@ class mail_message(osv.Model):
|
|||
('message_id', 'in', ids),
|
||||
], context=context)
|
||||
notified_ids = [notification.message_id.id for notification in not_obj.browse(cr, SUPERUSER_ID, not_ids, context=context)]
|
||||
else:
|
||||
notified_ids = []
|
||||
# Read: Check messages you are author -> could become an ir.rule, but not till we do not have a many2one variable field
|
||||
if operation == 'read':
|
||||
author_ids = [mid for mid, message in message_values.iteritems()
|
||||
if message.get('author_id') and message.get('author_id') == partner_id]
|
||||
# Create: Check messages you create that are private messages -> ir.rule ?
|
||||
elif operation == 'create':
|
||||
author_ids = [mid for mid, message in message_values.iteritems()
|
||||
if not message.get('model') and not message.get('res_id')]
|
||||
else:
|
||||
author_ids = []
|
||||
|
||||
# Create: Check message_follower_ids
|
||||
if operation == 'create':
|
||||
doc_follower_ids = []
|
||||
for model, mids in model_record_ids.items():
|
||||
notified_ids = []
|
||||
for doc_model, doc_dict in model_record_ids.items():
|
||||
fol_obj = self.pool.get('mail.followers')
|
||||
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [
|
||||
('res_model', '=', model),
|
||||
('res_id', 'in', list(mids)),
|
||||
('res_model', '=', doc_model),
|
||||
('res_id', 'in', list(doc_dict.keys())),
|
||||
('partner_id', '=', partner_id),
|
||||
], context=context)
|
||||
fol_mids = [follower.res_id for follower in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context)]
|
||||
doc_follower_ids += [mid for mid, message in message_values.iteritems()
|
||||
if message.get('res_model') == model and message.get('res_id') in fol_mids]
|
||||
notified_ids += [mid for mid, message in message_values.iteritems()
|
||||
if message.get('res_model') == doc_model and message.get('res_id') in fol_mids]
|
||||
else:
|
||||
doc_follower_ids = []
|
||||
notified_ids = []
|
||||
|
||||
# Calculate remaining ids, and related model/res_ids
|
||||
model_record_ids = {}
|
||||
other_ids = set(ids).difference(set(notified_ids), set(author_ids), set(doc_follower_ids))
|
||||
other_ids = set(ids).difference(set(author_ids), set(notified_ids))
|
||||
for id in other_ids:
|
||||
if message_values[id]['res_model']:
|
||||
model_record_ids.setdefault(message_values[id]['res_model'], set()).add(message_values[id]['res_id'])
|
||||
|
@ -532,7 +594,7 @@ class mail_message(osv.Model):
|
|||
if message.get('res_model') == model and message.get('res_id') in mids]
|
||||
|
||||
# Calculate remaining ids: if not void, raise an error
|
||||
other_ids = set(ids).difference(set(notified_ids), set(author_ids), set(doc_follower_ids), set(document_related_ids))
|
||||
other_ids = other_ids - set(document_related_ids)
|
||||
if not other_ids:
|
||||
return
|
||||
raise orm.except_orm(_('Access Denied'),
|
||||
|
@ -566,50 +628,121 @@ class mail_message(osv.Model):
|
|||
self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context)
|
||||
return super(mail_message, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
def _notify_followers(self, cr, uid, newid, message, context=None):
|
||||
""" Add the related record followers to the destination partner_ids.
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
""" Overridden to avoid duplicating fields that are unique to each email """
|
||||
if default is None:
|
||||
default = {}
|
||||
default.update(message_id=False, headers=False)
|
||||
return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Messaging API
|
||||
#------------------------------------------------------
|
||||
|
||||
MAIL_TEMPLATE = """<div>
|
||||
% if message:
|
||||
${display_message(message)}
|
||||
% endif
|
||||
% for ctx_msg in context_messages:
|
||||
${display_message(ctx_msg)}
|
||||
% endfor
|
||||
% if add_expandable:
|
||||
${display_expandable()}
|
||||
% endif
|
||||
${display_message(header_message)}
|
||||
</div>
|
||||
|
||||
<%def name="display_message(message)">
|
||||
<div>
|
||||
Subject: ${message.subject}<br />
|
||||
Body: ${message.body}
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="display_expandable()">
|
||||
<div>This is an expandable.</div>
|
||||
</%def>
|
||||
"""
|
||||
|
||||
def message_quote_context(self, cr, uid, id, context=None, limit=3, add_original=False):
|
||||
"""
|
||||
partners_to_notify = set([])
|
||||
# message has no subtype_id: pure log message -> no partners, no one notified
|
||||
if not message.subtype_id:
|
||||
message.write({'partner_ids': [5]})
|
||||
return True
|
||||
# all partner_ids of the mail.message have to be notified
|
||||
if message.partner_ids:
|
||||
partners_to_notify |= set(partner.id for partner in message.partner_ids)
|
||||
# all followers of the mail.message document have to be added as partners and notified
|
||||
if message.model and message.res_id:
|
||||
fol_obj = self.pool.get("mail.followers")
|
||||
fol_ids = fol_obj.search(cr, uid, [('res_model', '=', message.model), ('res_id', '=', message.res_id), ('subtype_ids', 'in', message.subtype_id.id)], context=context)
|
||||
fol_objs = fol_obj.browse(cr, uid, fol_ids, context=context)
|
||||
extra_notified = set(fol.partner_id.id for fol in fol_objs)
|
||||
missing_notified = extra_notified - partners_to_notify
|
||||
if missing_notified:
|
||||
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, p_id) for p_id in missing_notified]}, context=context)
|
||||
1. message.parent_id = False: new thread, no quote_context
|
||||
2. get the lasts messages in the thread before message
|
||||
3. get the message header
|
||||
4. add an expandable between them
|
||||
|
||||
:param dict quote_context: options for quoting
|
||||
:return string: html quote
|
||||
"""
|
||||
add_expandable = False
|
||||
|
||||
message = self.browse(cr, uid, id, context=context)
|
||||
if not message.parent_id:
|
||||
return ''
|
||||
context_ids = self.search(cr, uid, [
|
||||
('parent_id', '=', message.parent_id.id),
|
||||
('id', '<', message.id),
|
||||
], limit=limit, context=context)
|
||||
|
||||
if len(context_ids) >= limit:
|
||||
add_expandable = True
|
||||
context_ids = context_ids[0:-1]
|
||||
|
||||
context_ids.append(message.parent_id.id)
|
||||
context_messages = self.browse(cr, uid, context_ids, context=context)
|
||||
header_message = context_messages.pop()
|
||||
|
||||
try:
|
||||
if not add_original:
|
||||
message = False
|
||||
result = MakoTemplate(self.MAIL_TEMPLATE).render_unicode(message=message,
|
||||
context_messages=context_messages,
|
||||
header_message=header_message,
|
||||
add_expandable=add_expandable,
|
||||
# context kw would clash with mako internals
|
||||
ctx=context,
|
||||
format_exceptions=True)
|
||||
result = result.strip()
|
||||
return result
|
||||
except Exception:
|
||||
_logger.exception("failed to render mako template for quoting message")
|
||||
return ''
|
||||
return result
|
||||
|
||||
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.model and message.res_id:
|
||||
self._notify_followers(cr, uid, newid, message, context=context)
|
||||
message = self.read(cr, uid, newid, ['model', 'res_id', 'author_id', 'subtype_id', 'partner_ids'], context=context)
|
||||
|
||||
# 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)
|
||||
partners_to_notify = set([])
|
||||
# message has no subtype_id: pure log message -> no partners, no one notified
|
||||
if not message.get('subtype_id'):
|
||||
return True
|
||||
# all partner_ids of the mail.message have to be notified
|
||||
if message.get('partner_ids'):
|
||||
partners_to_notify |= set(message.get('partner_ids'))
|
||||
# all followers of the mail.message document have to be added as partners and notified
|
||||
if message.get('model') and message.get('res_id'):
|
||||
fol_obj = self.pool.get("mail.followers")
|
||||
fol_ids = fol_obj.search(cr, uid, [
|
||||
('res_model', '=', message.get('model')),
|
||||
('res_id', '=', message.get('res_id')),
|
||||
('subtype_ids', 'in', message.get('subtype_id')[0])
|
||||
], context=context)
|
||||
fol_objs = fol_obj.read(cr, uid, fol_ids, ['partner_id'], context=context)
|
||||
partners_to_notify |= set(fol['partner_id'][0] for fol in fol_objs)
|
||||
# when writing to a wall
|
||||
if message.get('author_id') and message.get('model') == "res.partner" and message.get('res_id') == message.get('author_id')[0]:
|
||||
partners_to_notify |= set([message.get('author_id')[0]])
|
||||
elif message.get('author_id'):
|
||||
partners_to_notify = partners_to_notify - set([message.get('author_id')[0]])
|
||||
|
||||
if partners_to_notify:
|
||||
self.write(cr, SUPERUSER_ID, [newid], {'notified_partner_ids': [(4, p_id) for p_id in partners_to_notify]}, context=context)
|
||||
|
||||
self.pool.get('mail.notification')._notify(cr, uid, newid, context=context)
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
"""Overridden to avoid duplicating fields that are unique to each email"""
|
||||
if default is None:
|
||||
default = {}
|
||||
default.update(message_id=False, headers=False)
|
||||
return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Tools
|
||||
#------------------------------------------------------
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<group>
|
||||
<field name="subject"/>
|
||||
<field name="author_id"/>
|
||||
<field name="email_from"/>
|
||||
<field name="date"/>
|
||||
<field name="type"/>
|
||||
<field name="subtype_id"/>
|
||||
|
@ -38,6 +39,7 @@
|
|||
<field name="res_id"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="partner_ids" widget="many2many_tags"/>
|
||||
<field name="notified_partner_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="body"/>
|
||||
|
|
|
@ -554,7 +554,11 @@ class mail_thread(osv.AbstractModel):
|
|||
('file2', 'bytes')}
|
||||
}
|
||||
"""
|
||||
msg_dict = {}
|
||||
msg_dict = {
|
||||
'type': 'email',
|
||||
'subtype': 'mail.mt_comment',
|
||||
'author_id': False,
|
||||
}
|
||||
if not isinstance(message, Message):
|
||||
if isinstance(message, unicode):
|
||||
# Warning: message_from_string doesn't always work correctly on unicode,
|
||||
|
@ -572,7 +576,7 @@ class mail_thread(osv.AbstractModel):
|
|||
if 'Subject' in message:
|
||||
msg_dict['subject'] = decode(message.get('Subject'))
|
||||
|
||||
# Envelope fields not stored in mail.message but made available for message_new()
|
||||
# Envelope fields not stored in mail.message but made available for message_new()
|
||||
msg_dict['from'] = decode(message.get('from'))
|
||||
msg_dict['to'] = decode(message.get('to'))
|
||||
msg_dict['cc'] = decode(message.get('cc'))
|
||||
|
@ -581,6 +585,8 @@ class mail_thread(osv.AbstractModel):
|
|||
author_ids = self._message_find_partners(cr, uid, message, ['From'], context=context)
|
||||
if author_ids:
|
||||
msg_dict['author_id'] = author_ids[0]
|
||||
else:
|
||||
msg_dict['email_from'] = message.get('from')
|
||||
partner_ids = self._message_find_partners(cr, uid, message, ['From', 'To', 'Cc'], context=context)
|
||||
msg_dict['partner_ids'] = partner_ids
|
||||
|
||||
|
@ -670,6 +676,18 @@ class mail_thread(osv.AbstractModel):
|
|||
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
|
||||
# we want to set a parent: force to set the parent_id to the oldest ancestor, to avoid having more than 1 level of thread
|
||||
elif parent_id:
|
||||
message_ids = mail_message.search(cr, SUPERUSER_ID, [('id', '=', parent_id), ('parent_id', '!=', False)], context=context)
|
||||
# avoid loops when finding ancestors
|
||||
processed_list = []
|
||||
if message_ids:
|
||||
_counter, _counter_max = 0, 200
|
||||
message = mail_message.browse(cr, SUPERUSER_ID, message_ids[0], context=context)
|
||||
while (message.parent_id and message.parent_id.id not in processed_list):
|
||||
processed_list.append(message.parent_id.id)
|
||||
message = message.parent_id
|
||||
parent_id = message.id
|
||||
|
||||
values = kwargs
|
||||
values.update({
|
||||
|
@ -690,32 +708,28 @@ class mail_thread(osv.AbstractModel):
|
|||
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', 'subject'], context=context)['partner_id'][0]
|
||||
|
||||
mail_message = self.pool.get('mail.message')
|
||||
|
||||
if not subject and parent_id:
|
||||
parent = mail_message.read(cr, uid, parent_id, ['subject'], context=context)
|
||||
if parent['subject'] and not parent['subject'].startswith('Re:'):
|
||||
subject = 'Re: %s' % parent['subject']
|
||||
|
||||
parent_id=False, attachment_ids=None, context=None):
|
||||
""" Wrapper on message_post, used only in Chatter (JS). The purpose is
|
||||
to handle attachments.
|
||||
# TDE FIXME: body is plaintext: convert it into html
|
||||
"""
|
||||
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)
|
||||
subtype='mail.mt_comment', parent_id=parent_id, context=context)
|
||||
|
||||
# Chatter: attachments linked to the document (not done JS-side), load the message
|
||||
if attachments:
|
||||
# HACK FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
|
||||
if attachment_ids:
|
||||
ir_attachment = self.pool.get('ir.attachment')
|
||||
attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [('res_model', '=', 'mail.compose.message'), ('res_id', '=', 0), ('create_uid', '=', uid), ('id', 'in', attachments)], context=context)
|
||||
if attachment_ids:
|
||||
mail_message = self.pool.get('mail.message')
|
||||
filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
|
||||
('res_model', '=', 'mail.message'),
|
||||
('res_id', '=', 0),
|
||||
('create_uid', '=', uid),
|
||||
('id', 'in', attachment_ids)], context=context)
|
||||
if filtered_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
|
||||
return new_message_id
|
||||
|
||||
#------------------------------------------------------
|
||||
# Followers API
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
sequence="10"/>
|
||||
|
||||
<!-- Left-side menu: Feeds -->
|
||||
<menuitem id="mail.mail_feeds" name="Feeds & Mailbox" parent="mail.mail_feeds_main" groups="base.group_user" sequence="10"/>
|
||||
<menuitem id="mail.mail_feeds" name="Messages" parent="mail.mail_feeds_main" groups="base.group_user" sequence="10"/>
|
||||
<menuitem id="mail_my_stuff" name="Organizer" parent="mail.mail_feeds_main"/>
|
||||
|
||||
<record id="mail_inboxfeeds" model="ir.ui.menu">
|
||||
|
@ -79,4 +79,4 @@
|
|||
<field name="parent_id" ref="mail.mail_feeds"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -2,6 +2,7 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
|||
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_user,mail.mail,model_mail_mail,base.group_user,1,1,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,,1,0,0,0
|
||||
access_mail_followers_system,mail.followers.system,model_mail_followers,base.group_system,1,1,1,1
|
||||
|
@ -12,6 +13,6 @@ access_mail_group_user,mail.group.user,model_mail_group,base.group_user,1,1,1,1
|
|||
access_mail_alias_all,mail.alias.all,model_mail_alias,,1,0,0,0
|
||||
access_mail_alias_user,mail.alias,model_mail_alias,base.group_user,1,1,1,0
|
||||
access_mail_alias_system,mail.alias,model_mail_alias,base.group_system,1,1,1,1
|
||||
access_mail_message_subtype,mail.message.subtype,model_mail_message_subtype,,1,1,1,1
|
||||
access_mail_mail_user,mail.mail,model_mail_mail,base.group_user,1,1,1,0
|
||||
access_mail_message_subtype_all,mail.message.subtype.all,model_mail_message_subtype,,1,0,0,0
|
||||
access_mail_vote_all,mail.vote.all,model_mail_vote,,1,1,1,1
|
||||
access_mail_favorite_all,mail.favorite.all,model_mail_favorite,,1,1,1,1
|
|
|
@ -359,7 +359,6 @@ openerp.mail = function (session) {
|
|||
mail.ChatterUtils.get_text2html(body),
|
||||
false,
|
||||
'comment',
|
||||
'mail.mt_comment',
|
||||
this.context.default_parent_id,
|
||||
attachments,
|
||||
this.parent_thread.context
|
||||
|
@ -438,7 +437,7 @@ openerp.mail = function (session) {
|
|||
// data of this expandable message
|
||||
this.id = datasets.id || -1,
|
||||
this.model = datasets.model || false,
|
||||
this.ancestor_id = datasets.ancestor_id || false,
|
||||
this.parent_id = datasets.parent_id || false,
|
||||
this.nb_messages = datasets.nb_messages || 0,
|
||||
this.thread_level = datasets.thread_level || 0,
|
||||
this.type = 'expandable',
|
||||
|
@ -512,10 +511,10 @@ openerp.mail = function (session) {
|
|||
* - record.attachment_ids[].url: url of each attachmentThe
|
||||
* thread view :
|
||||
* - root thread
|
||||
* - - sub message (ancestor_id = root message)
|
||||
* - - sub message (parent_id = root message)
|
||||
* - - - sub thread
|
||||
* - - - - sub sub message (parent id = sub thread)
|
||||
* - - sub message (ancestor_id = root message)
|
||||
* - - sub message (parent_id = root message)
|
||||
* - - - sub thread
|
||||
*/
|
||||
mail.ThreadMessage = session.web.Widget.extend({
|
||||
|
@ -553,7 +552,7 @@ openerp.mail = function (session) {
|
|||
// data of this message
|
||||
this.id = datasets.id || -1,
|
||||
this.model = datasets.model || false,
|
||||
this.ancestor_id = datasets.ancestor_id || false,
|
||||
this.parent_id = datasets.parent_id || false,
|
||||
this.res_id = datasets.res_id || false,
|
||||
this.type = datasets.type || false,
|
||||
this.is_author = datasets.is_author || false,
|
||||
|
@ -864,10 +863,10 @@ openerp.mail = function (session) {
|
|||
* This widget handles the display of a thread of messages. The
|
||||
* thread view:
|
||||
* - root thread
|
||||
* - - sub message (ancestor_id = root message)
|
||||
* - - sub message (parent_id = root message)
|
||||
* - - - sub thread
|
||||
* - - - - sub sub message (parent id = sub thread)
|
||||
* - - sub message (ancestor_id = root message)
|
||||
* - - sub message (parent_id = root message)
|
||||
* - - - sub thread
|
||||
*/
|
||||
mail.Thread = session.web.Widget.extend({
|
||||
|
@ -907,7 +906,7 @@ openerp.mail = function (session) {
|
|||
// data of this thread
|
||||
this.id = datasets.id || false,
|
||||
this.model = datasets.model || false,
|
||||
this.ancestor_id = datasets.ancestor_id || false,
|
||||
this.parent_id = datasets.parent_id || false,
|
||||
this.is_private = datasets.is_private || false,
|
||||
this.author_id = datasets.author_id || false,
|
||||
this.thread_level = (datasets.thread_level+1) || 0,
|
||||
|
@ -1119,8 +1118,8 @@ openerp.mail = function (session) {
|
|||
// CHM note : option for sending in flat mode by server
|
||||
var nb_indented_thread = this.options.display_indented_thread > this.thread_level ? this.options.display_indented_thread - this.thread_level : 0;
|
||||
|
||||
return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded_ids, nb_indented_thread, fetch_context, this.context.default_parent_id || undefined]
|
||||
).then(this.proxy('switch_new_message'));
|
||||
return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded_ids, nb_indented_thread, fetch_context, this.context.default_parent_id || undefined])
|
||||
.then(this.proxy('switch_new_message'));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1254,7 +1253,7 @@ openerp.mail = function (session) {
|
|||
var self=this;
|
||||
_(records).each(function (record) {
|
||||
var thread = self.browse_thread({
|
||||
'id': record.ancestor_id,
|
||||
'id': record.parent_id,
|
||||
'default_return_top_thread':true
|
||||
});
|
||||
// create object and attach to the thread object
|
||||
|
@ -1334,10 +1333,10 @@ openerp.mail = function (session) {
|
|||
var expandable = new mail.ThreadExpandable(this, {
|
||||
'id': message.id,
|
||||
'model': message.model,
|
||||
'ancestor_id': message.ancestor_id,
|
||||
'parent_id': message.parent_id,
|
||||
'nb_messages': 1,
|
||||
'thread_level': message.thread_level,
|
||||
'ancestor_id': message.ancestor_id,
|
||||
'parent_id': message.parent_id,
|
||||
'domain': message_dom,
|
||||
'options': message.options,
|
||||
}, {
|
||||
|
|
|
@ -94,6 +94,8 @@ class TestMailMockups(common.TransactionCase):
|
|||
self._build_email_kwargs_list = []
|
||||
|
||||
def _mock_build_email(self, *args, **kwargs):
|
||||
""" Mock build_email to be able to test its values. Store them into
|
||||
some internal variable for latter processing. """
|
||||
self._build_email_args_list.append(args)
|
||||
self._build_email_kwargs_list.append(kwargs)
|
||||
return self._build_email(*args, **kwargs)
|
||||
|
@ -140,7 +142,9 @@ class test_mail(TestMailMockups):
|
|||
group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
|
||||
group_employee_id = group_employee_ref and group_employee_ref[1] or False
|
||||
# Test users
|
||||
self.user_raoul_id = self.res_users.create(cr, uid, {'name': 'Raoul Grosbedon', 'login': 'raoul', 'groups_id': [(6, 0, [group_employee_id])]})
|
||||
self.user_raoul_id = self.res_users.create(cr, uid,
|
||||
{'name': 'Raoul Grosbedon', 'email': 'raoul@raoul.fr', 'login': 'raoul', 'groups_id': [(6, 0, [group_employee_id])]})
|
||||
self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
|
||||
self.user_admin = self.res_users.browse(cr, uid, uid)
|
||||
|
||||
# Mock send_get_mail_body to test its functionality without other addons override
|
||||
|
@ -163,7 +167,7 @@ class test_mail(TestMailMockups):
|
|||
|
||||
def test_00_message_process(self):
|
||||
""" Testing incoming emails processing. """
|
||||
cr, uid = self.cr, self.uid
|
||||
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
|
||||
# Incoming mail creates a new mail_group "frogs"
|
||||
self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', 'frogs')]), [])
|
||||
mail_frogs = MAIL_TEMPLATE.format(to='groups@example.com, other@gmail.com', subject='frogs', extra='')
|
||||
|
@ -201,6 +205,26 @@ 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')
|
||||
|
||||
# Do: post a new message, with a known partner
|
||||
test_msg_id = '<deadcafe.1337-2@smtp.agrolait.com>'
|
||||
TEMPLATE_MOD = MAIL_TEMPLATE_PLAINTEXT.replace('Sylvie Lelitre <sylvie.lelitre@agrolait.com>', user_raoul.email)
|
||||
mail_new = TEMPLATE_MOD.format(to='Friendly Frogs <group+frogs@example.com>', subject='extra news', extra='', msg_id=test_msg_id)
|
||||
self.mail_thread.message_process(cr, uid, None, mail_new)
|
||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
|
||||
# Test: author_id set, not email_from
|
||||
self.assertEqual(new_mail.author_id, user_raoul.partner_id, 'message process wrong author found')
|
||||
self.assertFalse(new_mail.email_from, 'message process should not set the email_from when an author is found')
|
||||
|
||||
# Do: post a new message, with a unknown partner
|
||||
test_msg_id = '<deadcafe.1337-3@smtp.agrolait.com>'
|
||||
TEMPLATE_MOD = MAIL_TEMPLATE_PLAINTEXT.replace('Sylvie Lelitre <sylvie.lelitre@agrolait.com>', '_abcd_')
|
||||
mail_new = TEMPLATE_MOD.format(to='Friendly Frogs <group+frogs@example.com>', subject='super news', extra='', msg_id=test_msg_id)
|
||||
self.mail_thread.message_process(cr, uid, None, mail_new)
|
||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
|
||||
# Test: author_id set, not email_from
|
||||
self.assertFalse(new_mail.author_id, 'message process shnould not have found a partner for _abcd_ email address')
|
||||
self.assertIn('_abcd_', new_mail.email_from, 'message process should set en email_from when not finding a partner_id')
|
||||
|
||||
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,
|
||||
|
@ -315,7 +339,25 @@ class test_mail(TestMailMockups):
|
|||
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):
|
||||
def test_20_message_quote_context(self):
|
||||
""" Tests designed for message_post. """
|
||||
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
||||
|
||||
msg1_id = self.mail_message.create(cr, uid, {'body': 'Thread header about Zap Brannigan', 'subject': 'My subject'})
|
||||
msg2_id = self.mail_message.create(cr, uid, {'body': 'First answer, should not be displayed', 'subject': 'Re: My subject', 'parent_id': msg1_id})
|
||||
msg3_id = self.mail_message.create(cr, uid, {'body': 'Second answer', 'subject': 'Re: My subject', 'parent_id': msg1_id})
|
||||
msg4_id = self.mail_message.create(cr, uid, {'body': 'Third answer', 'subject': 'Re: My subject', 'parent_id': msg1_id})
|
||||
msg_new_id = self.mail_message.create(cr, uid, {'body': 'My answer I am propagating', 'subject': 'Re: My subject', 'parent_id': msg1_id})
|
||||
|
||||
result = self.mail_message.message_quote_context(cr, uid, msg_new_id, limit=3)
|
||||
self.assertIn('Thread header about Zap Brannigan', result, 'Thread header content should be in quote.')
|
||||
self.assertIn('Second answer', result, 'Answer should be in quote.')
|
||||
self.assertIn('Third answer', result, 'Answer should be in quote.')
|
||||
self.assertIn('expandable', result, 'Expandable should be present.')
|
||||
self.assertNotIn('First answer, should not be displayed', result, 'Old answer should not be in quote.')
|
||||
self.assertNotIn('My answer I am propagating', result, 'Thread header content should be in quote.')
|
||||
|
||||
def test_21_message_post(self):
|
||||
""" Tests designed for message_post. """
|
||||
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'})
|
||||
|
@ -361,11 +403,11 @@ class test_mail(TestMailMockups):
|
|||
# the html2plaintext uses etree or beautiful soup, so the result may be slighly different
|
||||
# depending if you have installed beautiful soup.
|
||||
self.assertIn(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils\n', 'sent_email body_alternative is incorrect')
|
||||
# Test: mail_message: partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.partner_ids])
|
||||
# Test: mail_message: notified_partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.notified_partner_ids])
|
||||
test_pids = set([p_b_id, p_c_id])
|
||||
self.assertEqual(test_pids, message_pids, 'mail.message partners incorrect')
|
||||
# Test: notification linked to this message = group followers = partner_ids
|
||||
# Test: notification linked to this message = group followers = notified_partner_ids
|
||||
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
|
||||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
||||
|
@ -394,11 +436,11 @@ class test_mail(TestMailMockups):
|
|||
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
|
||||
self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect')
|
||||
self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect')
|
||||
# Test: mail_message: partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.partner_ids])
|
||||
# Test: mail_message: notified_partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.notified_partner_ids])
|
||||
test_pids = set([p_b_id, p_c_id, p_d_id])
|
||||
self.assertEqual(message_pids, test_pids, 'mail.message partners incorrect')
|
||||
# Test: notifications linked to this message = group followers = partner_ids
|
||||
# Test: notifications linked to this message = group followers = notified_partner_ids
|
||||
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
|
||||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
||||
|
@ -412,6 +454,11 @@ class test_mail(TestMailMockups):
|
|||
self.assertIn((attach.name, attach.datas.decode('base64')), _attachments,
|
||||
'mail.message attachment name / data incorrect')
|
||||
|
||||
# 3. Reply to the last message, check that its parent will be the first message
|
||||
msg_id3 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Test', parent_id=msg_id2)
|
||||
message = self.mail_message.browse(cr, uid, msg_id3)
|
||||
self.assertEqual(message.parent_id.id, msg_id, 'message_post did not flatten the thread structure')
|
||||
|
||||
def test_25_message_compose_wizard(self):
|
||||
""" Tests designed for the mail.compose.message wizard. """
|
||||
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
||||
|
@ -462,12 +509,12 @@ class test_mail(TestMailMockups):
|
|||
# Test: mail.message: subject, body inside pre
|
||||
self.assertEqual(message.subject, False, 'mail.message incorrect subject')
|
||||
self.assertEqual(message.body, _msg_body, 'mail.message incorrect body')
|
||||
# Test: mail.message: partner_ids = entries in mail.notification: group_pigs fans (a, b) + mail.compose.message partner_ids (c, d)
|
||||
msg_pids = [partner.id for partner in message.partner_ids]
|
||||
# Test: mail.message: notified_partner_ids = entries in mail.notification: group_pigs fans (a, b) + mail.compose.message partner_ids (c, d)
|
||||
msg_pids = [partner.id for partner in message.notified_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')
|
||||
self.assertEqual(set(msg_pids), set(test_pids), 'mail.message notified_partner_ids incorrect')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: reply to last comment with attachments
|
||||
|
@ -526,20 +573,6 @@ class test_mail(TestMailMockups):
|
|||
|
||||
def test_30_message_read(self):
|
||||
""" Tests for message_read and expandables. """
|
||||
|
||||
def _print_debug(message, debug=True, prefix=''):
|
||||
if debug:
|
||||
print prefix, message
|
||||
|
||||
def _print_msg(message, debug=True, prefix=''):
|
||||
if not debug:
|
||||
return
|
||||
if message.get('type') == 'expandable':
|
||||
print prefix, 'expandable', message
|
||||
else:
|
||||
print prefix, 'message', message.get('body'), message.get('id'), message.get('ancestor_id')
|
||||
|
||||
_debug = False
|
||||
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
||||
pigs_domain = [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]
|
||||
|
||||
|
@ -574,7 +607,6 @@ class test_mail(TestMailMockups):
|
|||
# CASE1: message_read with domain, threaded
|
||||
# We simulate an entire flow, using the expandables to test them
|
||||
# ----------------------------------------
|
||||
_print_debug('\nCASE1: message_read with domain, threaded\n', _debug)
|
||||
|
||||
# Do: read last message, threaded
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=1, thread_level=1)
|
||||
|
@ -582,11 +614,10 @@ class test_mail(TestMailMockups):
|
|||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
|
||||
self.assertEqual(set([msg_id2, msg_id10]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
|
||||
self.assertEqual(read_msg_list[1].get('ancestor_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
# Data: get expandables
|
||||
new_threads_exp, new_msg_exp = None, None
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('id') == -1:
|
||||
new_threads_exp = msg
|
||||
elif msg.get('type') == 'expandable':
|
||||
|
@ -596,15 +627,12 @@ class test_mail(TestMailMockups):
|
|||
self.assertIsNotNone(new_msg_exp, 'message_read on last Pigs message should have returned a new messages expandable')
|
||||
domain = new_msg_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
_print_debug('Executing %s' % domain, _debug)
|
||||
self.assertIn(('id', 'child_of', msg_id2), domain, 'new messages expandable domain should contain a child_of condition')
|
||||
self.assertIn(('id', '>=', msg_id4), domain, 'new messages expandable domain should contain an id greater than condition')
|
||||
self.assertIn(('id', '<=', msg_id8), domain, 'new messages expandable domain should contain an id less than condition')
|
||||
self.assertEqual(new_msg_exp.get('ancestor_id'), msg_id2, 'new messages expandable should have ancestor_id set to the thread header')
|
||||
self.assertEqual(new_msg_exp.get('parent_id'), msg_id2, 'new messages expandable should have ancestor_id set to the thread header')
|
||||
# Do: message_read with domain, thread_level=0, parent_id=msg_id2 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=200, thread_level=0, parent_id=msg_id2)
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
# Test: other message in thread have been fetch
|
||||
self.assertEqual(set([msg_id4, msg_id6, msg_id8]), set(read_msg_ids), 'message_read in Pigs thread should return all the previous messages')
|
||||
|
@ -613,21 +641,19 @@ class test_mail(TestMailMockups):
|
|||
self.assertIsNotNone(new_threads_exp, 'message_read on last Pigs message should have returned a new threads expandable')
|
||||
domain = new_threads_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
_print_debug('Executing %s' % domain, _debug)
|
||||
for condition in pigs_domain:
|
||||
self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
|
||||
self.assertFalse(new_threads_exp.get('ancestor_id'), 'new threads expandable should not have an ancestor_id')
|
||||
self.assertFalse(new_threads_exp.get('parent_id'), 'new threads expandable should not have an ancestor_id')
|
||||
# Do: message_read with domain, thread_level=1 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
|
||||
self.assertEqual(set([msg_id1, msg_id9]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
|
||||
self.assertEqual(read_msg_list[1].get('ancestor_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
|
||||
# Data: get expandables
|
||||
new_threads_exp, new_msg_exp = None, None
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('id') == -1:
|
||||
new_threads_exp = msg
|
||||
elif msg.get('type') == 'expandable':
|
||||
|
@ -637,15 +663,12 @@ class test_mail(TestMailMockups):
|
|||
self.assertIsNotNone(new_msg_exp, 'message_read on Pigs message should have returned a new messages expandable')
|
||||
domain = new_msg_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
_print_debug('Executing %s' % domain, _debug)
|
||||
self.assertIn(('id', 'child_of', msg_id1), domain, 'new messages expandable domain should contain a child_of condition')
|
||||
self.assertIn(('id', '>=', msg_id3), domain, 'new messages expandable domain should contain an id greater than condition')
|
||||
self.assertIn(('id', '<=', msg_id7), domain, 'new messages expandable domain should contain an id less than condition')
|
||||
self.assertEqual(new_msg_exp.get('ancestor_id'), msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
|
||||
self.assertEqual(new_msg_exp.get('parent_id'), msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
|
||||
# Do: message_read with domain, thread_level=0, parent_id=msg_id1 (should be imposed by JS)
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=200, thread_level=0, parent_id=msg_id1)
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
|
||||
# Test: other message in thread have been fetch
|
||||
self.assertEqual(set([msg_id3, msg_id5, msg_id7]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
|
||||
|
@ -654,7 +677,6 @@ class test_mail(TestMailMockups):
|
|||
self.assertIsNotNone(new_threads_exp, 'message_read should have returned a new threads expandable')
|
||||
domain = new_threads_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
_print_debug('Executing %s' % domain, _debug)
|
||||
for condition in pigs_domain:
|
||||
self.assertIn(condition, domain, 'general expandable domain should contain the message_read domain parameter')
|
||||
# Do: message_read with domain, thread_level=1 (should be imposed by JS)
|
||||
|
@ -663,13 +685,10 @@ class test_mail(TestMailMockups):
|
|||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
|
||||
self.assertEqual(len(read_msg_list), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
|
||||
self.assertEqual([msg_id0], read_msg_ids, 'message_read after 2 More should return only 1 last message')
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: message_read with domain, flat
|
||||
# ----------------------------------------
|
||||
_print_debug('\nCASE2: message_read with domain, flat\n', _debug)
|
||||
|
||||
# Do: read 2 lasts message, flat
|
||||
read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=2, thread_level=0)
|
||||
|
@ -677,12 +696,11 @@ class test_mail(TestMailMockups):
|
|||
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is not set, 1 expandable
|
||||
self.assertEqual(len(read_msg_list), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
|
||||
self.assertEqual(set([msg_id9, msg_id10]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
|
||||
self.assertFalse(read_msg_list[0].get('ancestor_id'), 'message_read flat should set the ancestor as False')
|
||||
self.assertFalse(read_msg_list[1].get('ancestor_id'), 'message_read flat should set the ancestor as False')
|
||||
self.assertFalse(read_msg_list[0].get('parent_id'), 'message_read flat should set the ancestor as False')
|
||||
self.assertFalse(read_msg_list[1].get('parent_id'), 'message_read flat should set the ancestor as False')
|
||||
# Data: get expandables
|
||||
new_threads_exp, new_msg_exp = None, None
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('id') == -1:
|
||||
new_threads_exp = msg
|
||||
|
||||
|
@ -690,7 +708,6 @@ class test_mail(TestMailMockups):
|
|||
self.assertIsNotNone(new_threads_exp, 'message_read flat on the 2 last Pigs messages should have returns a new threads expandable')
|
||||
domain = new_threads_exp.get('domain', [])
|
||||
# Test: expandable, conditions in domain
|
||||
_print_debug('Executing %s' % domain, _debug)
|
||||
for condition in pigs_domain:
|
||||
self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
|
||||
# Do: message_read with domain, thread_level=0 (should be imposed by JS)
|
||||
|
@ -700,8 +717,6 @@ class test_mail(TestMailMockups):
|
|||
self.assertEqual(len(read_msg_list), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
|
||||
self.assertEqual([msg_id0, msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8], read_msg_ids,
|
||||
'message_read, More on flat, should return all remaning messages')
|
||||
for msg in read_msg_list:
|
||||
_print_msg(msg, _debug)
|
||||
|
||||
def test_40_needaction(self):
|
||||
""" Tests for mail.message needaction. """
|
||||
|
@ -760,22 +775,11 @@ class test_mail(TestMailMockups):
|
|||
reply_msg = MAIL_TEMPLATE.format(to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: 1',
|
||||
extra='In-Reply-To: %s' % msg1.message_id)
|
||||
self.mail_group.message_process(cr, uid, None, reply_msg)
|
||||
# TDE note: temp various asserts because of the random bug about msg1.child_ids
|
||||
msg_ids = self.mail_message.search(cr, uid, [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], limit=1)
|
||||
new_msg = self.mail_message.browse(cr, uid, msg_ids[0])
|
||||
# if new_msg.parent_id.id != msg1.id:
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
self.assertEqual(new_msg.parent_id, msg1, 'Newly processed mail_message (%d) should have msg1 as parent (msg2 is %d)' % (new_msg.id, msg2.id))
|
||||
|
||||
# 2. References header
|
||||
reply_msg2 = MAIL_TEMPLATE.format(to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: Re: 1',
|
||||
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id)
|
||||
self.mail_group.message_process(cr, uid, None, reply_msg2)
|
||||
# TDE note: temp various asserts because of the random bug about msg1.child_ids
|
||||
msg_ids = self.mail_message.search(cr, uid, [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], limit=1)
|
||||
new_msg = self.mail_message.browse(cr, uid, msg_ids[0])
|
||||
self.assertEqual(new_msg.parent_id, msg1, 'Newly processed mail_message should have msg1 as parent')
|
||||
|
||||
# 3. Subject contains [<ID>] + model passed to message+process -> only attached to group, not to mail
|
||||
reply_msg3 = MAIL_TEMPLATE.format(to='Pretty Pigs <group+pigs@example.com>, other@gmail.com',
|
||||
|
@ -795,34 +799,46 @@ class test_mail(TestMailMockups):
|
|||
|
||||
def test_60_message_vote(self):
|
||||
""" Test designed for the vote/unvote feature. """
|
||||
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)
|
||||
msg1 = group_pigs.message_post(body='My Body', subject='1')
|
||||
msg1 = self.mail_message.browse(cr, uid, msg1)
|
||||
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
|
||||
# Data: post a message on Pigs
|
||||
msg_id = group_pigs.message_post(body='My Body', subject='1')
|
||||
msg = self.mail_message.browse(cr, uid, msg_id)
|
||||
|
||||
# Create user Bert Tartopoils
|
||||
user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert', 'login': 'bert'})
|
||||
user_bert = self.res_users.browse(cr, uid, user_bert_id)
|
||||
|
||||
# Test: msg1 and msg2 have void vote_user_ids
|
||||
self.assertFalse(msg1.vote_user_ids, 'newly created message msg1 has not void vote_user_ids')
|
||||
# Do: Admin vote for msg1
|
||||
self.mail_message.vote_toggle(cr, uid, [msg1.id])
|
||||
msg1.refresh()
|
||||
# Test: msg1 has Admin as voter
|
||||
self.assertEqual(set(msg1.vote_user_ids), set([user_admin]), 'after voting, Admin is not the voter')
|
||||
# Do: Bert vote for msg1
|
||||
self.mail_message.vote_toggle(cr, user_bert_id, [msg1.id])
|
||||
msg1.refresh()
|
||||
# Test: msg1 has Admin and Bert as voters
|
||||
self.assertEqual(set(msg1.vote_user_ids), set([user_admin, user_bert]), 'after voting, Admin and Bert are not the voters')
|
||||
# Do: Admin unvote for msg1
|
||||
self.mail_message.vote_toggle(cr, uid, [msg1.id])
|
||||
msg1.refresh()
|
||||
# Test: msg1 has Bert as voter
|
||||
self.assertEqual(set(msg1.vote_user_ids), set([user_bert]), 'after unvoting for Admin, Bert is not the voter')
|
||||
# Do: Admin vote for msg
|
||||
self.mail_message.vote_toggle(cr, uid, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg has Admin as voter
|
||||
self.assertEqual(set(msg.vote_user_ids), set([user_admin]), 'mail_message vote: after voting, Admin should be in the voter')
|
||||
# Do: Bert vote for msg
|
||||
self.mail_message.vote_toggle(cr, user_raoul.id, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg has Admin and Bert as voters
|
||||
self.assertEqual(set(msg.vote_user_ids), set([user_admin, user_raoul]), 'mail_message vote: after voting, Admin and Bert should be in the voters')
|
||||
# Do: Admin unvote for msg
|
||||
self.mail_message.vote_toggle(cr, uid, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg has Bert as voter
|
||||
self.assertEqual(set(msg.vote_user_ids), set([user_raoul]), 'mail_message vote: after unvoting, Bert should be in the voter')
|
||||
|
||||
def test_70_message_favorite(self):
|
||||
""" Tests for favorites. """
|
||||
self.assertTrue(1 == 1, 'Test not implemented, do not replace by return True')
|
||||
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
|
||||
# Data: post a message on Pigs
|
||||
msg_id = group_pigs.message_post(body='My Body', subject='1')
|
||||
msg = self.mail_message.browse(cr, uid, msg_id)
|
||||
|
||||
# Do: Admin stars msg
|
||||
self.mail_message.favorite_toggle(cr, uid, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg starred by Admin
|
||||
self.assertEqual(set(msg.favorite_user_ids), set([user_admin]), 'mail_message favorite: after starring, Admin should be in favorite_user_ids')
|
||||
# Do: Bert stars msg
|
||||
self.mail_message.favorite_toggle(cr, user_raoul.id, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg starred by Admin and Raoul
|
||||
self.assertEqual(set(msg.favorite_user_ids), set([user_admin, user_raoul]), 'mail_message favorite: after starring, Admin and Raoul should be in favorite_user_ids')
|
||||
# Do: Admin unvote for msg
|
||||
self.mail_message.favorite_toggle(cr, uid, [msg.id])
|
||||
msg.refresh()
|
||||
# Test: msg starred by Raoul
|
||||
self.assertEqual(set(msg.favorite_user_ids), set([user_raoul]), 'mail_message favorite: after unstarring, Raoul should be in favorite_user_ids')
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue