diff --git a/addons/account/account.py b/addons/account/account.py index 3e07f151de3..c9dd1950347 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -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), diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 549363ce269..48082451f35 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -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.'), diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 0508a7cadfe..16393f0ea49 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -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'), diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 1b614a1ee85..d9e95f15079 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -1862,7 +1862,7 @@ - + @@ -2414,32 +2414,6 @@ form new - - ir.actions.server - True - 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) - - New Company Financial Setting - account.account.graph diff --git a/addons/account/i18n/zh_CN.po b/addons/account/i18n/zh_CN.po index a51b7c7930a..49c2d2b8c1e 100644 --- a/addons/account/i18n/zh_CN.po +++ b/addons/account/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:35+0000\n" -"PO-Revision-Date: 2012-07-11 03:05+0000\n" -"Last-Translator: Wei \"oldrev\" Li \n" +"PO-Revision-Date: 2012-10-25 16:26+0000\n" +"Last-Translator: AllanWong <18895563@qq.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:15+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: account #: view:account.invoice.report:0 @@ -37,7 +37,7 @@ msgstr "其它设置" msgid "" "Determine the display order in the report 'Accounting \\ Reporting \\ " "Generic Reporting \\ Taxes \\ Taxes Report'" -msgstr "确定以下报表的显示顺序:”会计-报表-通用报表-税-税报表“" +msgstr "确定以下报表的显示顺序:”会计-报表-通用报表-税务-税务报表“" #. module: account #: view:account.move.reconcile:0 @@ -91,7 +91,7 @@ msgstr "应收账款账龄" #. module: account #: model:process.transition,name:account.process_transition_invoiceimport0 msgid "Import from invoice or payment" -msgstr "从发票或支付款导入" +msgstr "从发票或付款单导入" #. module: account #: model:ir.model,name:account.model_wizard_multi_charts_accounts @@ -139,6 +139,7 @@ msgstr "核销" #: field:account.move,ref:0 #: field:account.move.line,ref:0 #: field:account.subscription,ref:0 +#: xsl:account.transfer:0 msgid "Reference" msgstr "关联" @@ -155,13 +156,13 @@ msgid "" msgstr "如果设置为false,该付款条款将会被隐藏。" #. module: account -#: code:addons/account/account_invoice.py:1428 +#: code:addons/account/account_invoice.py:1430 #, python-format msgid "Warning!" msgstr "警告!" #. module: account -#: code:addons/account/account.py:3112 +#: code:addons/account/account.py:3129 #, python-format msgid "Miscellaneous Journal" msgstr "其它凭证簿" @@ -218,10 +219,10 @@ msgstr "选择凭证行核销" msgid "" "Check this box if you don't want any VAT related to this Tax Code to appear " "on invoices" -msgstr "勾选此项使发票上不显示增值税" +msgstr "勾选此项隐藏发票上与此税号相关的增值税信息" #. module: account -#: code:addons/account/account_invoice.py:1241 +#: code:addons/account/account_invoice.py:1254 #, python-format msgid "Invoice '%s' is paid partially: %s%s of %s%s (%s%s remaining)" msgstr "发票'%s'已部分支付了%s%s ,总金额为:%s%s, 尚余%s%s未付" @@ -237,7 +238,7 @@ msgid "Belgian Reports" msgstr "比利时报表" #. module: account -#: code:addons/account/account_move_line.py:1200 +#: code:addons/account/account_move_line.py:1215 #, python-format msgid "You can not add/modify entries in a closed journal." msgstr "不能在已关闭的账簿添加或修改分录" @@ -283,7 +284,7 @@ msgid "St." msgstr "St." #. module: account -#: code:addons/account/account_invoice.py:551 +#: code:addons/account/account_invoice.py:560 #, python-format msgid "Invoice line account company does not match with invoice company." msgstr "发票明细的科目公司与发票头的公司不匹配。" @@ -560,8 +561,10 @@ msgid "The accountant confirms the statement." msgstr "财务人员确认的报表" #. module: account +#: report:account.account.balance:0 #: selection:account.balance.report,display_account:0 #: selection:account.common.account.report,display_account:0 +#: report:account.general.ledger_landscape:0 #: selection:account.report.general.ledger,display_account:0 #: selection:account.tax,type_tax_use:0 #: selection:account.tax.template,type_tax_use:0 @@ -617,7 +620,7 @@ msgid "Main Sequence must be different from current !" msgstr "序列号必须唯一" #. module: account -#: code:addons/account/account_move_line.py:1251 +#: code:addons/account/account_move_line.py:1266 #, python-format msgid "No period found or more than one period found for the given date." msgstr "根据输入的凭证日期没有找到期间或找到了多个期间" @@ -628,7 +631,7 @@ msgid "Tax Code Amount" msgstr "税金额" #. module: account -#: code:addons/account/account.py:3116 +#: code:addons/account/account.py:3133 #, python-format msgid "SAJ" msgstr "SAJ" @@ -655,8 +658,8 @@ msgid "Journal Period" msgstr "账簿的会计期间" #. module: account -#: code:addons/account/account_move_line.py:750 -#: code:addons/account/account_move_line.py:803 +#: code:addons/account/account_move_line.py:766 +#: code:addons/account/account_move_line.py:819 #, python-format msgid "To reconcile the entries company should be the same for all entries" msgstr "要核销这些凭证,这些凭证所属公司必须一致" @@ -733,6 +736,7 @@ msgid "You can only change currency for Draft Invoice !" msgstr "你只能对发票草稿修改币种" #. module: account +#: model:ir.actions.report.xml,name:account.account_financial_report #: model:ir.ui.menu,name:account.menu_account_report msgid "Financial Report" msgstr "财务报表" @@ -748,12 +752,13 @@ msgstr "财务报表" #: view:account.journal:0 #: field:account.journal,type:0 #: field:account.move.reconcile,type:0 +#: xsl:account.transfer:0 #: field:report.invoice.created,type:0 msgid "Type" msgstr "类型" #. module: account -#: code:addons/account/account_invoice.py:738 +#: code:addons/account/account_invoice.py:747 #, python-format msgid "" "Taxes are missing!\n" @@ -880,12 +885,13 @@ msgid "Create 3 Months Periods" msgstr "创建季度" #. module: account +#: report:account.aged_trial_balance:0 #: report:account.overdue:0 msgid "Due" msgstr "到期" #. module: account -#: code:addons/account/account.py:1345 +#: code:addons/account/account.py:1353 #, python-format msgid "" "You cannot validate this journal entry because account \"%s\" does not " @@ -963,7 +969,7 @@ msgid "" msgstr "如果这税科目是一个税编码科目,这字段金额要征税。如果这税科目是一个税基编码,这字段的金额不用征税。" #. module: account -#: code:addons/account/account.py:2596 +#: code:addons/account/account.py:2613 #, python-format msgid "I can not locate a parent code for the template account!" msgstr "无法为该科目模板定位其父科目" @@ -996,10 +1002,10 @@ msgid "Code" msgstr "编码" #. module: account -#: code:addons/account/account.py:2268 +#: code:addons/account/account.py:2285 #: code:addons/account/account_bank_statement.py:357 #: code:addons/account/account_invoice.py:73 -#: code:addons/account/account_invoice.py:688 +#: code:addons/account/account_invoice.py:697 #: code:addons/account/account_move_line.py:173 #, python-format msgid "No Analytic Journal !" @@ -1061,7 +1067,7 @@ msgid "" msgstr "根据您国家定义这些类型,该类型包含有关科目及其具体的信息。" #. module: account -#: code:addons/account/account_move_line.py:842 +#: code:addons/account/account_move_line.py:856 #, python-format msgid "" "You have to provide an account for the write off/exchange difference entry !" @@ -1109,7 +1115,7 @@ msgstr "未平财务凭证" #. module: account #: model:account.account.type,name:account.data_account_type_bank #: selection:account.bank.accounts.wizard,account_type:0 -#: code:addons/account/account.py:3003 +#: code:addons/account/account.py:3020 #, python-format msgid "Bank" msgstr "银行" @@ -1201,7 +1207,7 @@ msgid "The move of this entry line." msgstr "分录明细的变动" #. module: account -#: code:addons/account/account_move_line.py:1302 +#: code:addons/account/account_move_line.py:1317 #, python-format msgid "" "You can not use this general account in this journal, check the tab 'Entry " @@ -1222,7 +1228,7 @@ msgid "Entry Label" msgstr "分录标签" #. module: account -#: code:addons/account/account.py:1129 +#: code:addons/account/account.py:1136 #, python-format msgid "You can not modify/delete a journal with entries for this period !" msgstr "您不能修改/删除这账簿和在此会计期间的分录!" @@ -1307,14 +1313,15 @@ msgid "Taxes" msgstr "税" #. module: account -#: code:addons/account/wizard/account_financial_report.py:69 -#: code:addons/account/wizard/account_report_common.py:144 +#: code:addons/account/wizard/account_financial_report.py:70 +#: code:addons/account/wizard/account_report_common.py:145 #, python-format msgid "Select a starting and an ending period" msgstr "选择会计期间的开始和结束时间" #. module: account #: model:account.financial.report,name:account.account_financial_report_profitandloss0 +#: model:ir.actions.act_window,name:account.action_account_report_pl msgid "Profit and Loss" msgstr "损益类" @@ -1369,6 +1376,7 @@ msgid "Journal Items Analysis" msgstr "账簿明细分析" #. module: account +#: report:account.aged_trial_balance:0 #: model:ir.ui.menu,name:account.next_id_22 msgid "Partners" msgstr "业务伙伴" @@ -1393,8 +1401,10 @@ msgid "Central Journal" msgstr "汇总账簿" #. module: account +#: report:account.account.balance:0 #: selection:account.balance.report,display_account:0 #: selection:account.common.account.report,display_account:0 +#: report:account.general.ledger_landscape:0 #: selection:account.partner.balance,display_partner:0 #: selection:account.report.general.ledger,display_account:0 msgid "With balance is not equal to 0" @@ -1508,7 +1518,7 @@ msgstr "已核销处理" #. module: account #: field:account.journal.view,columns_id:0 msgid "Columns" -msgstr "列" +msgstr "栏目" #. module: account #: report:account.overdue:0 @@ -1619,6 +1629,7 @@ msgid "Separated Journal Sequences" msgstr "分散的账簿序列" #. module: account +#: field:account.bank.statement,user_id:0 #: view:account.invoice:0 msgid "Responsible" msgstr "负责人" @@ -1647,7 +1658,7 @@ msgid "Year Sum" msgstr "年合计" #. module: account -#: code:addons/account/account_invoice.py:1429 +#: code:addons/account/account_invoice.py:1431 #, python-format msgid "" "You selected an Unit of Measure which is not compatible with the product." @@ -1720,7 +1731,7 @@ msgid "Customer Ref:" msgstr "客户关联:" #. module: account -#: code:addons/account/account_cash_statement.py:292 +#: code:addons/account/account_cash_statement.py:293 #, python-format msgid "User %s does not have rights to access %s journal !" msgstr "用户 %s 没有权限访问 %s!" @@ -2039,7 +2050,7 @@ msgid "Pro-forma" msgstr "形式发票" #. module: account -#: code:addons/account/account.py:1461 +#: code:addons/account/account.py:1478 #, python-format msgid "" "There is no default default debit account defined \n" @@ -2063,7 +2074,7 @@ msgid "Search Chart of Account Templates" msgstr "搜索科目一览表模板" #. module: account -#: code:addons/account/account_move_line.py:1277 +#: code:addons/account/account_move_line.py:1292 #, python-format msgid "" "Can not create an automatic sequence for this piece!\n" @@ -2114,7 +2125,7 @@ msgid "Description" msgstr "说明" #. module: account -#: code:addons/account/account.py:3119 +#: code:addons/account/account.py:3136 #, python-format msgid "ECNJ" msgstr "ECNJ" @@ -2133,7 +2144,7 @@ msgid "Income Account" msgstr "收益科目" #. module: account -#: code:addons/account/account_invoice.py:370 +#: code:addons/account/account_invoice.py:379 #, python-format msgid "There is no Accounting Journal of type Sale/Purchase defined!" msgstr "没定义销售/采购 的账簿!" @@ -2173,6 +2184,7 @@ msgstr "产品模板" #. module: account #: report:account.account.balance:0 #: field:account.aged.trial.balance,fiscalyear_id:0 +#: report:account.aged_trial_balance:0 #: field:account.balance.report,fiscalyear_id:0 #: report:account.central.journal:0 #: field:account.central.journal,fiscalyear_id:0 @@ -2182,6 +2194,7 @@ msgstr "产品模板" #: field:account.common.report,fiscalyear_id:0 #: view:account.entries.report:0 #: field:account.entries.report,fiscalyear_id:0 +#: report:account.financial.report:0 #: field:account.fiscalyear,name:0 #: report:account.general.journal:0 #: field:account.general.journal,fiscalyear_id:0 @@ -2232,7 +2245,7 @@ msgid "Account Line" msgstr "发票明细" #. module: account -#: code:addons/account/account.py:1468 +#: code:addons/account/account.py:1485 #, python-format msgid "" "There is no default default credit account defined \n" @@ -2263,7 +2276,7 @@ msgid "Main Sequence" msgstr "主序列" #. module: account -#: code:addons/account/account_bank_statement.py:402 +#: code:addons/account/account_bank_statement.py:403 #, python-format msgid "" "In order to delete a bank statement, you must first cancel it to delete " @@ -2337,7 +2350,7 @@ msgid "Account Tax Code" msgstr "税编码" #. module: account -#: code:addons/account/account_invoice.py:572 +#: code:addons/account/account_invoice.py:581 #, python-format msgid "" "Can't find any account journal of %s type for this company.\n" @@ -2423,7 +2436,7 @@ msgid "Account Model Entries" msgstr "凭证模板" #. module: account -#: code:addons/account/account.py:3117 +#: code:addons/account/account.py:3134 #, python-format msgid "EXJ" msgstr "EXJ" @@ -2484,7 +2497,6 @@ msgid "Account move line reconcile (writeoff)" msgstr "凭证行核销(注销)" #. module: account -#: model:account.account.type,name:account.account_type_tax #: report:account.invoice:0 #: field:account.invoice,amount_tax:0 #: field:account.move.line,account_tax_id:0 @@ -2516,7 +2528,7 @@ msgid "Accounts" msgstr "科目" #. module: account -#: code:addons/account/account_invoice.py:369 +#: code:addons/account/account_invoice.py:378 #, python-format msgid "Configuration Error!" msgstr "设置错误!" @@ -2636,6 +2648,7 @@ msgstr "系统在指定日期前自动生成分录。" #. module: account #: view:account.aged.trial.balance:0 #: model:ir.actions.act_window,name:account.action_account_aged_balance_view +#: model:ir.actions.report.xml,name:account.account_aged_partner_balance #: model:ir.ui.menu,name:account.menu_aged_trial_balance msgid "Aged Partner Balance" msgstr "业务伙伴以前的余额表" @@ -2685,14 +2698,14 @@ msgid "This wizard will create recurring accounting entries" msgstr "该向导将创建一个定期分录" #. module: account -#: code:addons/account/account.py:1321 +#: code:addons/account/account.py:1329 #, python-format msgid "No sequence defined on the journal !" msgstr "没定义账簿的序列!" #. module: account -#: code:addons/account/account.py:2268 -#: code:addons/account/account_invoice.py:688 +#: code:addons/account/account.py:2285 +#: code:addons/account/account_invoice.py:697 #: code:addons/account/account_move_line.py:173 #, python-format msgid "You have to define an analytic journal on the '%s' journal!" @@ -2795,7 +2808,7 @@ msgid "Base Code Amount" msgstr "税基金额" #. module: account -#: code:addons/account/account_invoice.py:392 +#: code:addons/account/account_invoice.py:401 #, python-format msgid "" "You can not delete an invoice which is open or paid. We suggest you to " @@ -2808,7 +2821,7 @@ msgid "Default Sale Tax" msgstr "默认销售税" #. module: account -#: code:addons/account/account_invoice.py:1013 +#: code:addons/account/account_invoice.py:1025 #, python-format msgid "Invoice '%s' is validated." msgstr "发票 '%s' 已审核" @@ -2846,7 +2859,7 @@ msgid "Fiscal Position" msgstr "财务结构" #. module: account -#: code:addons/account/account_invoice.py:735 +#: code:addons/account/account_invoice.py:744 #, python-format msgid "" "Tax base different!\n" @@ -2996,7 +3009,7 @@ msgid "View" msgstr "视图" #. module: account -#: code:addons/account/account.py:3363 +#: code:addons/account/account.py:3380 #: code:addons/account/account_bank.py:90 #, python-format msgid "BNK" @@ -3040,7 +3053,7 @@ msgstr "业务伙伴会计帐本(往来帐)" #. module: account #: help:account.journal.column,sequence:0 msgid "Gives the sequence order to journal column." -msgstr "指定账簿的序列" +msgstr "指定账簿栏目的序列" #. module: account #: help:account.account,currency_id:0 @@ -3065,7 +3078,7 @@ msgstr "科目一览表模板" #. module: account #: model:ir.actions.act_window,name:account.action_wizard_multi_chart msgid "Set Your Accounting Options" -msgstr "" +msgstr "设置您的会计选项" #. module: account #: view:report.account.sales:0 @@ -3193,7 +3206,7 @@ msgid "Starting Balance" msgstr "期初余额" #. module: account -#: code:addons/account/account_invoice.py:1332 +#: code:addons/account/account_invoice.py:1345 #, python-format msgid "No Partner Defined !" msgstr "未定义业务伙伴!" @@ -3247,7 +3260,7 @@ msgid "Chart of Tax" msgstr "税一览表" #. module: account -#: code:addons/account/account_cash_statement.py:314 +#: code:addons/account/account_cash_statement.py:315 #, python-format msgid "The closing balance should be the same than the computed balance!" msgstr "期末余额与计算出来的余额不平衡." @@ -3328,6 +3341,7 @@ msgstr "数量" #. module: account #: field:account.aged.trial.balance,period_length:0 +#: report:account.aged_trial_balance:0 msgid "Period Length (days)" msgstr "期间(天数)" @@ -3374,7 +3388,7 @@ msgid "Detail" msgstr "详情" #. module: account -#: code:addons/account/account_invoice.py:839 +#: code:addons/account/account_invoice.py:850 #, python-format msgid "" "Can not create the invoice !\n" @@ -3391,9 +3405,16 @@ msgid "VAT :" msgstr "增值税 :" #. module: account +#: report:account.account.balance:0 +#: report:account.aged_trial_balance:0 #: report:account.central.journal:0 +#: report:account.financial.report:0 +#: report:account.general.journal:0 #: report:account.general.ledger:0 +#: report:account.general.ledger_landscape:0 #: field:account.installer,charts:0 +#: report:account.journal.period.print:0 +#: report:account.journal.period.print.sale.purchase:0 #: report:account.partner.balance:0 #: report:account.third_party_ledger:0 #: report:account.third_party_ledger_other:0 @@ -3414,7 +3435,7 @@ msgid "Centralised counterpart" msgstr "汇总副本" #. module: account -#: code:addons/account/account_move_line.py:584 +#: code:addons/account/account_move_line.py:575 #, python-format msgid "You can not create journal items on a \"view\" account %s %s" msgstr "凭证中不能使用 “视图” 类型的会计科目 %s %s" @@ -3439,6 +3460,7 @@ msgstr "如果您不选择会计年度将使用所有开启的会计年度" #: report:account.analytic.account.journal:0 #: selection:account.balance.report,filter:0 #: field:account.bank.statement,date:0 +#: field:account.bank.statement.line,date:0 #: selection:account.central.journal,filter:0 #: selection:account.common.account.report,filter:0 #: selection:account.common.journal.report,filter:0 @@ -3466,10 +3488,17 @@ msgstr "如果您不选择会计年度将使用所有开启的会计年度" #: field:account.subscription.line,date:0 #: report:account.third_party_ledger:0 #: report:account.third_party_ledger_other:0 +#: xsl:account.transfer:0 #: selection:account.vat.declaration,filter:0 #: selection:accounting.report,filter:0 #: selection:accounting.report,filter_cmp:0 +#: code:addons/account/report/account_general_ledger.py:305 +#: code:addons/account/report/account_general_ledger.py:308 +#: code:addons/account/report/account_journal.py:195 +#: code:addons/account/report/account_journal.py:198 +#: code:addons/account/report/common_report_header.py:97 #: field:analytic.entries.report,date:0 +#, python-format msgid "Date" msgstr "日期" @@ -3486,7 +3515,6 @@ msgstr "反核销" #. module: account #: view:account.analytic.line:0 -#: field:account.bank.statement,user_id:0 #: view:account.journal:0 #: field:account.journal,user_id:0 #: view:analytic.entries.report:0 @@ -3500,7 +3528,7 @@ msgid "Chart of Accounts Template" msgstr "科目一览表模板" #. module: account -#: code:addons/account/account.py:2280 +#: code:addons/account/account.py:2297 #, python-format msgid "" "Maturity date of entry line generated by model line '%s' of model '%s' is " @@ -3511,7 +3539,7 @@ msgstr "" "请在业务伙伴里定义它" #. module: account -#: code:addons/account/account_move_line.py:837 +#: code:addons/account/account_move_line.py:846 #, python-format msgid "Some entries are already reconciled !" msgstr "部分分录已核销!" @@ -3542,6 +3570,8 @@ msgstr "预算" #: selection:account.vat.declaration,filter:0 #: selection:accounting.report,filter:0 #: selection:accounting.report,filter_cmp:0 +#: code:addons/account/report/common_report_header.py:100 +#, python-format msgid "No Filters" msgstr "无筛选" @@ -3623,7 +3653,7 @@ msgid "Analytic Items" msgstr "分析明细" #. module: account -#: code:addons/account/account_move_line.py:1153 +#: code:addons/account/account_move_line.py:1168 #, python-format msgid "Unable to change tax !" msgstr "无法更改税目!" @@ -3654,7 +3684,7 @@ msgid "Mapping" msgstr "图表" #. module: account -#: code:addons/account/account_invoice.py:921 +#: code:addons/account/account_invoice.py:932 #, python-format msgid "" "You cannot create an invoice on a centralised journal. Uncheck the " @@ -3668,6 +3698,7 @@ msgstr "无法在合并(centralised)凭证簿上创建发票,请在凭证 #: report:account.analytic.account.inverted.balance:0 #: field:account.bank.statement,name:0 #: field:account.chart.template,name:0 +#: report:account.financial.report:0 #: field:account.model.line,name:0 #: field:account.move.line,name:0 #: field:account.move.reconcile,name:0 @@ -3681,7 +3712,7 @@ msgid "Account Aged Trial balance Report" msgstr "过期的试算表" #. module: account -#: code:addons/account/account_move_line.py:591 +#: code:addons/account/account_move_line.py:582 #, python-format msgid "You can not create journal items on a closed account %s %s" msgstr "凭证中不能使用关闭的会计科目 %s %s" @@ -4001,7 +4032,7 @@ msgid "Month" msgstr "月份" #. module: account -#: code:addons/account/account_move_line.py:1216 +#: code:addons/account/account_move_line.py:1231 #, python-format msgid "" "You can not do this modification on a confirmed entry! You can just change " @@ -4060,7 +4091,7 @@ msgid "Account Base Code" msgstr "税基编码" #. module: account -#: code:addons/account/account_analytic_line.py:93 +#: code:addons/account/account_analytic_line.py:91 #, python-format msgid "There is no expense account defined for this product: \"%s\" (id:%d)" msgstr "未定义此产品“%s“ (id:%d)的费用科目" @@ -4269,7 +4300,7 @@ msgid "Allow Reconciliation" msgstr "允许核销" #. module: account -#: code:addons/account/account.py:1077 +#: code:addons/account/account.py:1082 #, python-format msgid "" "You can not modify company of this period as some journal items exists." @@ -4303,7 +4334,7 @@ msgid "Recurring Models" msgstr "定期模型" #. module: account -#: code:addons/account/account_move_line.py:1251 +#: code:addons/account/account_move_line.py:1266 #, python-format msgid "Encoding error" msgstr "输入错误" @@ -4315,6 +4346,7 @@ msgstr "4" #. module: account #: view:account.invoice:0 +#: xsl:account.transfer:0 msgid "Change" msgstr "改变" @@ -4359,7 +4391,7 @@ msgid "Example" msgstr "例子" #. module: account -#: code:addons/account/account_invoice.py:828 +#: code:addons/account/account_invoice.py:839 #, python-format msgid "" "Please verify the price of the invoice !\n" @@ -4373,7 +4405,7 @@ msgid "Keep empty to use the income account" msgstr "留空为使用利润科目" #. module: account -#: code:addons/account/account.py:3299 +#: code:addons/account/account.py:3316 #, python-format msgid "Purchase Tax %.2f%%" msgstr "采购税 %.2f%%" @@ -4401,7 +4433,7 @@ msgstr "科目一览表" #: selection:account.bank.statement.line,type:0 #: view:account.invoice:0 #: view:account.invoice.report:0 -#: code:addons/account/account_invoice.py:337 +#: code:addons/account/account_invoice.py:346 #, python-format msgid "Customer" msgstr "客户" @@ -4417,7 +4449,7 @@ msgid "Cancelled Invoice" msgstr "已取消的发票" #. module: account -#: code:addons/account/account.py:1567 +#: code:addons/account/account.py:1584 #, python-format msgid "" "Couldn't create move with currency different from the secondary currency of " @@ -4469,7 +4501,7 @@ msgid "Income Account on Product Template" msgstr "产品模板的收入科目" #. module: account -#: code:addons/account/account.py:3120 +#: code:addons/account/account.py:3137 #, python-format msgid "MISC" msgstr "杂项" @@ -4494,11 +4526,13 @@ msgstr "新的会计年度" #: view:account.invoice:0 #: view:account.tax.template:0 #: selection:account.vat.declaration,based_on:0 +#: code:addons/account/report/account_tax_report.py:68 #: model:ir.actions.act_window,name:account.act_res_partner_2_account_invoice_opened #: model:ir.actions.act_window,name:account.action_invoice_tree #: model:ir.actions.report.xml,name:account.account_invoices #: view:report.invoice.created:0 #: field:res.partner,invoice_ids:0 +#, python-format msgid "Invoices" msgstr "发票列表" @@ -4637,26 +4671,24 @@ msgid "Journal Items" msgstr "会计凭证行" #. module: account -#: code:addons/account/account.py:1088 -#: code:addons/account/account.py:1090 -#: code:addons/account/account.py:1321 -#: code:addons/account/account.py:1563 -#: code:addons/account/account.py:1567 -#: code:addons/account/account.py:3368 -#: code:addons/account/account_move_line.py:807 -#: code:addons/account/account_move_line.py:830 -#: code:addons/account/account_move_line.py:832 -#: code:addons/account/account_move_line.py:835 -#: code:addons/account/account_move_line.py:837 +#: code:addons/account/account.py:1095 +#: code:addons/account/account.py:1097 +#: code:addons/account/account.py:1329 +#: code:addons/account/account.py:1580 +#: code:addons/account/account.py:1584 +#: code:addons/account/account.py:3385 +#: code:addons/account/account_move_line.py:823 +#: code:addons/account/account_move_line.py:843 +#: code:addons/account/account_move_line.py:846 #: code:addons/account/report/common_report_header.py:92 #: code:addons/account/wizard/account_change_currency.py:38 #: code:addons/account/wizard/account_change_currency.py:59 #: code:addons/account/wizard/account_change_currency.py:64 #: code:addons/account/wizard/account_change_currency.py:70 -#: code:addons/account/wizard/account_financial_report.py:69 +#: code:addons/account/wizard/account_financial_report.py:70 #: code:addons/account/wizard/account_move_bank_reconcile.py:49 -#: code:addons/account/wizard/account_report_common.py:144 -#: code:addons/account/wizard/account_report_common.py:150 +#: code:addons/account/wizard/account_report_common.py:145 +#: code:addons/account/wizard/account_report_common.py:151 #, python-format msgid "Error" msgstr "错误" @@ -4759,7 +4791,7 @@ msgid "Beginning of Period Date" msgstr "期间开始日期" #. module: account -#: code:addons/account/account.py:1351 +#: code:addons/account/account.py:1361 #, python-format msgid "" "You can not modify a posted entry of this journal !\n" @@ -4785,7 +4817,7 @@ msgid "Child Tax Accounts" msgstr "子税科目" #. module: account -#: code:addons/account/account.py:1090 +#: code:addons/account/account.py:1097 #, python-format msgid "Start period should be smaller then End period" msgstr "开始日期应小于会计期间的结束日期" @@ -4806,6 +4838,7 @@ msgstr "辅助核算余额 -" #. module: account #: report:account.account.balance:0 #: field:account.aged.trial.balance,target_move:0 +#: report:account.aged_trial_balance:0 #: field:account.balance.report,target_move:0 #: report:account.central.journal:0 #: field:account.central.journal,target_move:0 @@ -4849,6 +4882,8 @@ msgstr "会计期间类型" #: view:account.invoice:0 #: field:account.invoice,payment_ids:0 #: selection:account.vat.declaration,based_on:0 +#: code:addons/account/report/account_tax_report.py:70 +#, python-format msgid "Payments" msgstr "付款" @@ -4892,7 +4927,7 @@ msgstr "科目报表" #. module: account #: field:account.journal.column,name:0 msgid "Column Name" -msgstr "列名称" +msgstr "栏目名称" #. module: account #: view:account.general.journal:0 @@ -4922,7 +4957,7 @@ msgid "Line 1:" msgstr "第一行" #. module: account -#: code:addons/account/account.py:1307 +#: code:addons/account/account.py:1315 #, python-format msgid "Integrity Error !" msgstr "完整性错误!" @@ -4955,6 +4990,7 @@ msgstr "核销结果" #. module: account #: model:account.financial.report,name:account.account_financial_report_balancesheet0 +#: model:ir.actions.act_window,name:account.action_account_report_bs #: model:ir.ui.menu,name:account.menu_account_report_bs msgid "Balance Sheet" msgstr "资产负债表" @@ -5031,6 +5067,7 @@ msgstr "报表" #: view:account.move.line:0 #: field:account.tax,amount:0 #: field:account.tax.template,amount:0 +#: xsl:account.transfer:0 #: view:analytic.entries.report:0 #: field:analytic.entries.report,amount:0 msgid "Amount" @@ -5158,7 +5195,6 @@ msgstr "科目合并的科目报表" #. module: account #: field:account.bank.statement.line,name:0 -#: field:account.invoice,reference:0 msgid "Communication" msgstr "沟通" @@ -5210,13 +5246,13 @@ msgid "End of Year Entries Journal" msgstr "账簿的结账分录" #. module: account -#: code:addons/account/account.py:3446 +#: code:addons/account/account.py:3463 #: code:addons/account/account_bank_statement.py:338 -#: code:addons/account/account_invoice.py:427 -#: code:addons/account/account_invoice.py:527 -#: code:addons/account/account_invoice.py:542 -#: code:addons/account/account_invoice.py:550 -#: code:addons/account/account_invoice.py:572 +#: code:addons/account/account_invoice.py:436 +#: code:addons/account/account_invoice.py:536 +#: code:addons/account/account_invoice.py:551 +#: code:addons/account/account_invoice.py:559 +#: code:addons/account/account_invoice.py:581 #: code:addons/account/wizard/account_move_journal.py:63 #, python-format msgid "Configuration Error !" @@ -5290,7 +5326,6 @@ msgid "Customer Invoices And Refunds" msgstr "客户发票和退款" #. module: account -#: field:account.analytic.line,amount_currency:0 #: field:account.entries.report,amount_currency:0 #: field:account.model.line,amount_currency:0 #: field:account.move.line,amount_currency:0 @@ -5456,7 +5491,7 @@ msgid "Generate Opening Entries" msgstr "产生开启分录" #. module: account -#: code:addons/account/account_move_line.py:759 +#: code:addons/account/account_move_line.py:775 #, python-format msgid "Already Reconciled!" msgstr "已核销!" @@ -5489,14 +5524,14 @@ msgid "Child Accounts" msgstr "子科目" #. module: account -#: code:addons/account/account_move_line.py:1214 +#: code:addons/account/account_move_line.py:1229 #, python-format msgid "Move name (id): %s (%s)" msgstr "会计凭证号 (id): %s (%s)" #. module: account #: view:account.move.line.reconcile:0 -#: code:addons/account/account_move_line.py:857 +#: code:addons/account/account_move_line.py:871 #, python-format msgid "Write-Off" msgstr "补差额" @@ -5516,7 +5551,7 @@ msgstr "收入" #: selection:account.bank.statement.line,type:0 #: view:account.invoice:0 #: view:account.invoice.report:0 -#: code:addons/account/account_invoice.py:339 +#: code:addons/account/account_invoice.py:348 #, python-format msgid "Supplier" msgstr "供应商" @@ -5546,7 +5581,7 @@ msgid "Account n°" msgstr "科目编码" #. module: account -#: code:addons/account/account_invoice.py:88 +#: code:addons/account/account_invoice.py:91 #, python-format msgid "Free Reference" msgstr "无限制的单号" @@ -5561,7 +5596,9 @@ msgstr "定价" #: selection:account.common.partner.report,result_selection:0 #: selection:account.partner.balance,result_selection:0 #: selection:account.partner.ledger,result_selection:0 +#: code:addons/account/report/account_aged_partner_balance.py:376 #: code:addons/account/report/account_partner_balance.py:301 +#: code:addons/account/report/account_partner_ledger.py:399 #, python-format msgid "Receivable and Payable Accounts" msgstr "应收款与应付款科目" @@ -5657,7 +5694,7 @@ msgid "Filter by" msgstr "筛选" #. module: account -#: code:addons/account/account.py:2256 +#: code:addons/account/account.py:2273 #, python-format msgid "You have a wrong expression \"%(...)s\" in your model !" msgstr "模型中存在错误的表达式 \"%(...)s\"" @@ -5668,8 +5705,8 @@ msgid "Entry Date" msgstr "分录日期" #. module: account -#: code:addons/account/account_move_line.py:1155 -#: code:addons/account/account_move_line.py:1238 +#: code:addons/account/account_move_line.py:1170 +#: code:addons/account/account_move_line.py:1253 #, python-format msgid "You can not use an inactive account!" msgstr "您不能使用一个停用的科目!" @@ -5710,8 +5747,8 @@ msgid "Number of Days" msgstr "天数" #. module: account -#: code:addons/account/account_bank_statement.py:402 -#: code:addons/account/account_invoice.py:392 +#: code:addons/account/account_bank_statement.py:403 +#: code:addons/account/account_invoice.py:401 #: code:addons/account/wizard/account_period_close.py:51 #, python-format msgid "Invalid action !" @@ -5773,7 +5810,7 @@ msgid "Multipication factor for Base code" msgstr "税率" #. module: account -#: code:addons/account/wizard/account_report_common.py:150 +#: code:addons/account/wizard/account_report_common.py:151 #, python-format msgid "not implemented" msgstr "尚未实现" @@ -5810,6 +5847,8 @@ msgstr "辅助核算分析" #. module: account #: selection:account.aged.trial.balance,direction_selection:0 +#: code:addons/account/report/account_aged_partner_balance.py:381 +#, python-format msgid "Past" msgstr "过去" @@ -6083,6 +6122,8 @@ msgstr "百分比" #. module: account #: selection:account.report.general.ledger,sortby:0 +#: code:addons/account/report/account_general_ledger.py:307 +#, python-format msgid "Journal & Partner" msgstr "账簿 & 业务伙伴" @@ -6092,7 +6133,7 @@ msgid "Power" msgstr "强制" #. module: account -#: code:addons/account/account.py:3368 +#: code:addons/account/account.py:3385 #, python-format msgid "Cannot generate an unused journal code." msgstr "不能生成一个未使用的凭证代码。" @@ -6132,6 +6173,7 @@ msgid "Applicable Type" msgstr "适用类型" #. module: account +#: field:account.invoice,reference:0 #: field:account.invoice.line,invoice_id:0 msgid "Invoice Reference" msgstr "发票" @@ -6350,8 +6392,8 @@ msgid "You can not remove an account containing journal items." msgstr "您不能删除已经存在凭证的账户。" #. module: account -#: code:addons/account/account_analytic_line.py:145 -#: code:addons/account/account_move_line.py:933 +#: code:addons/account/account_analytic_line.py:143 +#: code:addons/account/account_move_line.py:947 #, python-format msgid "Entries: " msgstr "凭证: " @@ -6367,7 +6409,7 @@ msgid "Currency of the related account journal." msgstr "货币的关联账户凭证。" #. module: account -#: code:addons/account/account.py:1563 +#: code:addons/account/account.py:1580 #, python-format msgid "Couldn't create move between different companies" msgstr "无法创建公司之间的过帐" @@ -6407,13 +6449,13 @@ msgstr "草稿状态" #. module: account #: view:account.move.line:0 -#: code:addons/account/account_move_line.py:1043 +#: code:addons/account/account_move_line.py:1058 #, python-format msgid "Total debit" msgstr "借方合计" #. module: account -#: code:addons/account/account_move_line.py:808 +#: code:addons/account/account_move_line.py:824 #, python-format msgid "Entry \"%s\" is not valid !" msgstr "凭证\"%s\"无效!" @@ -6481,25 +6523,26 @@ msgstr "损益(费用账户)" #: code:addons/account/account.py:622 #: code:addons/account/account.py:624 #: code:addons/account/account.py:963 -#: code:addons/account/account.py:1052 -#: code:addons/account/account.py:1129 -#: code:addons/account/account.py:1344 -#: code:addons/account/account.py:1351 -#: code:addons/account/account.py:2280 -#: code:addons/account/account.py:2596 -#: code:addons/account/account_analytic_line.py:92 -#: code:addons/account/account_analytic_line.py:101 +#: code:addons/account/account.py:1057 +#: code:addons/account/account.py:1136 +#: code:addons/account/account.py:1352 +#: code:addons/account/account.py:1359 +#: code:addons/account/account.py:1361 +#: code:addons/account/account.py:2297 +#: code:addons/account/account.py:2613 +#: code:addons/account/account_analytic_line.py:90 +#: code:addons/account/account_analytic_line.py:99 #: code:addons/account/account_bank_statement.py:301 #: code:addons/account/account_bank_statement.py:314 #: code:addons/account/account_bank_statement.py:352 -#: code:addons/account/account_cash_statement.py:292 -#: code:addons/account/account_cash_statement.py:314 -#: code:addons/account/account_invoice.py:808 -#: code:addons/account/account_invoice.py:839 -#: code:addons/account/account_invoice.py:1030 -#: code:addons/account/account_move_line.py:1200 -#: code:addons/account/account_move_line.py:1216 -#: code:addons/account/account_move_line.py:1218 +#: code:addons/account/account_cash_statement.py:293 +#: code:addons/account/account_cash_statement.py:315 +#: code:addons/account/account_invoice.py:819 +#: code:addons/account/account_invoice.py:850 +#: code:addons/account/account_invoice.py:1042 +#: code:addons/account/account_move_line.py:1215 +#: code:addons/account/account_move_line.py:1231 +#: code:addons/account/account_move_line.py:1233 #: code:addons/account/wizard/account_invoice_refund.py:108 #: code:addons/account/wizard/account_invoice_refund.py:110 #: code:addons/account/wizard/account_open_closed_fiscalyear.py:39 @@ -6531,8 +6574,8 @@ msgid "Printed" msgstr "已打印" #. module: account -#: code:addons/account/account_move_line.py:584 -#: code:addons/account/account_move_line.py:591 +#: code:addons/account/account_move_line.py:575 +#: code:addons/account/account_move_line.py:582 #, python-format msgid "Error :" msgstr "错误:" @@ -6588,7 +6631,7 @@ msgid "Display Ledger Report with One partner per page" msgstr "一页一个业务伙伴的分类帐" #. module: account -#: code:addons/account/account_move_line.py:1218 +#: code:addons/account/account_move_line.py:1233 #, python-format msgid "" "You can not do this modification on a reconciled entry! You can just change " @@ -6743,7 +6786,7 @@ msgid "Total:" msgstr "合计:" #. module: account -#: code:addons/account/account.py:2229 +#: code:addons/account/account.py:2246 #, python-format msgid "" "You can specify year, month and date in the name of the model using the " @@ -6780,7 +6823,7 @@ msgid "Taxes used in Sales" msgstr "销售中用到的税" #. module: account -#: code:addons/account/account_invoice.py:495 +#: code:addons/account/account_invoice.py:504 #: code:addons/account/wizard/account_invoice_refund.py:145 #, python-format msgid "Data Insufficient !" @@ -6806,7 +6849,7 @@ msgstr "销售" #: view:account.journal.column:0 #: model:ir.model,name:account.model_account_journal_column msgid "Journal Column" -msgstr "账簿列" +msgstr "账簿栏目" #. module: account #: selection:account.invoice.report,state:0 @@ -6852,14 +6895,14 @@ msgid "Source Document" msgstr "源单据" #. module: account -#: code:addons/account/account.py:1432 +#: code:addons/account/account.py:1449 #, python-format msgid "You can not delete a posted journal entry \"%s\"!" msgstr "你不能删除一个已复核的会计凭证“%s” !" #. module: account #: selection:account.partner.ledger,filter:0 -#: code:addons/account/report/account_partner_ledger.py:59 +#: code:addons/account/report/account_partner_ledger.py:60 #: model:ir.actions.act_window,name:account.act_account_acount_move_line_open_unreconciled #, python-format msgid "Unreconciled Entries" @@ -6955,8 +6998,8 @@ msgid "Are you sure you want to open this invoice ?" msgstr "你确定要打开这发票?" #. module: account -#: code:addons/account/account_invoice.py:528 -#: code:addons/account/account_invoice.py:543 +#: code:addons/account/account_invoice.py:537 +#: code:addons/account/account_invoice.py:552 #, python-format msgid "" "Can not find a chart of account, you should create one from the " @@ -6969,7 +7012,7 @@ msgid "Opening Entries Expense Account" msgstr "未分配利润科目" #. module: account -#: code:addons/account/account_move_line.py:999 +#: code:addons/account/account_move_line.py:1014 #, python-format msgid "Accounting Entries" msgstr "会计分录" @@ -7100,7 +7143,7 @@ msgid "" msgstr "这字段只用于,如果您开发自己的模块允许开发者在自定义域创建特定的税" #. module: account -#: code:addons/account/account.py:1088 +#: code:addons/account/account.py:1095 #, python-format msgid "You should have chosen periods that belongs to the same company" msgstr "同一家公司你应该选择一个会计期间" @@ -7131,8 +7174,8 @@ msgid "Reporting" msgstr "报表" #. module: account -#: code:addons/account/account_move_line.py:759 -#: code:addons/account/account_move_line.py:842 +#: code:addons/account/account_move_line.py:775 +#: code:addons/account/account_move_line.py:856 #: code:addons/account/wizard/account_invoice_state.py:44 #: code:addons/account/wizard/account_invoice_state.py:68 #: code:addons/account/wizard/account_state_open.py:37 @@ -7221,7 +7264,7 @@ msgid "Sign on Reports" msgstr "报表上的符号" #. module: account -#: code:addons/account/wizard/account_fiscalyear_close.py:73 +#: code:addons/account/wizard/account_fiscalyear_close.py:88 #, python-format msgid "The periods to generate opening entries were not found" msgstr "用于生成期初余额会计凭证的期间不存在" @@ -7232,7 +7275,7 @@ msgid "Root/View" msgstr "根/视图" #. module: account -#: code:addons/account/account.py:3121 +#: code:addons/account/account.py:3138 #, python-format msgid "OPEJ" msgstr "OPEJ" @@ -7267,13 +7310,14 @@ msgid "Optional Information" msgstr "可选信息" #. module: account -#: code:addons/account/wizard/account_fiscalyear_close.py:84 +#: code:addons/account/wizard/account_fiscalyear_close.py:100 #, python-format msgid "The journal must have default credit and debit account" msgstr "这账簿必须要有默认贷方和借方科目" #. module: account #: report:account.general.journal:0 +#: xsl:account.transfer:0 msgid ":" msgstr ":" @@ -7300,13 +7344,13 @@ msgid "Maturity Date" msgstr "到期日期" #. module: account -#: code:addons/account/account_move_line.py:1302 +#: code:addons/account/account_move_line.py:1317 #, python-format msgid "Bad account !" msgstr "无效科目!" #. module: account -#: code:addons/account/account.py:3108 +#: code:addons/account/account.py:3125 #, python-format msgid "Sales Journal" msgstr "销售账簿" @@ -7323,7 +7367,7 @@ msgid "Invoice Tax" msgstr "发票税" #. module: account -#: code:addons/account/account_move_line.py:1277 +#: code:addons/account/account_move_line.py:1292 #, python-format msgid "No piece number !" msgstr "没会计期间!" @@ -7375,7 +7419,7 @@ msgstr "到" #. module: account #: selection:account.move.line,centralisation:0 -#: code:addons/account/account.py:1518 +#: code:addons/account/account.py:1535 #, python-format msgid "Currency Adjustment" msgstr "汇兑损益调整" @@ -7423,13 +7467,15 @@ msgstr "5" #: selection:account.common.partner.report,result_selection:0 #: selection:account.partner.balance,result_selection:0 #: selection:account.partner.ledger,result_selection:0 +#: code:addons/account/report/account_aged_partner_balance.py:374 #: code:addons/account/report/account_partner_balance.py:299 +#: code:addons/account/report/account_partner_ledger.py:397 #, python-format msgid "Payable Accounts" msgstr "应付款科目" #. module: account -#: code:addons/account/account_invoice.py:732 +#: code:addons/account/account_invoice.py:741 #, python-format msgid "Global taxes defined, but they are not in invoice lines !" msgstr "定义了全局税,但发票行中没有!" @@ -7473,7 +7519,7 @@ msgstr "报表名称" #: selection:account.bank.accounts.wizard,account_type:0 #: selection:account.entries.report,type:0 #: selection:account.journal,type:0 -#: code:addons/account/account.py:3003 +#: code:addons/account/account.py:3020 #, python-format msgid "Cash" msgstr "现金" @@ -7485,15 +7531,15 @@ msgid "Account Destination" msgstr "目标科目" #. module: account -#: code:addons/account/account.py:1431 -#: code:addons/account/account.py:1460 -#: code:addons/account/account.py:1467 -#: code:addons/account/account_invoice.py:920 -#: code:addons/account/account_move_line.py:1104 -#: code:addons/account/wizard/account_automatic_reconcile.py:152 -#: code:addons/account/wizard/account_fiscalyear_close.py:73 -#: code:addons/account/wizard/account_fiscalyear_close.py:83 -#: code:addons/account/wizard/account_fiscalyear_close.py:86 +#: code:addons/account/account.py:1448 +#: code:addons/account/account.py:1477 +#: code:addons/account/account.py:1484 +#: code:addons/account/account_invoice.py:931 +#: code:addons/account/account_move_line.py:1119 +#: code:addons/account/wizard/account_automatic_reconcile.py:148 +#: code:addons/account/wizard/account_fiscalyear_close.py:88 +#: code:addons/account/wizard/account_fiscalyear_close.py:99 +#: code:addons/account/wizard/account_fiscalyear_close.py:102 #: code:addons/account/wizard/account_move_journal.py:165 #: code:addons/account/wizard/account_report_aged_partner_balance.py:56 #: code:addons/account/wizard/account_report_aged_partner_balance.py:58 @@ -7640,13 +7686,14 @@ msgstr "固定" #: code:addons/account/account.py:645 #: code:addons/account/account.py:664 #: code:addons/account/account.py:787 -#: code:addons/account/account.py:1077 -#: code:addons/account/account_invoice.py:732 -#: code:addons/account/account_invoice.py:735 -#: code:addons/account/account_invoice.py:738 +#: code:addons/account/account.py:1082 +#: code:addons/account/account_invoice.py:741 +#: code:addons/account/account_invoice.py:744 +#: code:addons/account/account_invoice.py:747 #: code:addons/account/account_move_line.py:97 -#: code:addons/account/account_move_line.py:750 -#: code:addons/account/account_move_line.py:803 +#: code:addons/account/account_move_line.py:766 +#: code:addons/account/account_move_line.py:819 +#: code:addons/account/wizard/account_fiscalyear_close.py:62 #, python-format msgid "Warning !" msgstr "警告 !" @@ -7698,7 +7745,7 @@ msgid "Select a currency to apply on the invoice" msgstr "在发票上选择合适的币别" #. module: account -#: code:addons/account/account.py:3446 +#: code:addons/account/account.py:3463 #, python-format msgid "" "The bank account defined on the selected chart of accounts hasn't a code." @@ -7711,7 +7758,7 @@ msgid "Can not %s draft/proforma/cancel invoice." msgstr "不能注销 %s 草稿/形式/取消的发票" #. module: account -#: code:addons/account/account_invoice.py:810 +#: code:addons/account/account_invoice.py:821 #, python-format msgid "No Invoice Lines !" msgstr "没有发票明细" @@ -7789,7 +7836,7 @@ msgid "Deferral Method" msgstr "递延方法" #. module: account -#: code:addons/account/account_invoice.py:379 +#: code:addons/account/account_invoice.py:388 #, python-format msgid "Invoice '%s' is paid." msgstr "发票 '%s' 已支付。" @@ -7851,7 +7898,7 @@ msgid "Associated Partner" msgstr "相关业务伙伴" #. module: account -#: code:addons/account/account_invoice.py:1332 +#: code:addons/account/account_invoice.py:1345 #, python-format msgid "You must first select a partner !" msgstr "你必须首先选择一个业务伙伴!" @@ -7902,7 +7949,7 @@ msgid "" msgstr "税目一览表是用来生成您定期的税单。请您按照贵国的税法设置。" #. module: account -#: code:addons/account/account_invoice.py:428 +#: code:addons/account/account_invoice.py:437 #, python-format msgid "" "Can not find a chart of accounts for this company, you should create one." @@ -7924,7 +7971,7 @@ msgid "Choose Fiscal Year" msgstr "选择会计年度" #. module: account -#: code:addons/account/account.py:3111 +#: code:addons/account/account.py:3128 #, python-format msgid "Purchase Refund Journal" msgstr "采购红字发票账簿" @@ -8011,7 +8058,7 @@ msgid "Compute Code for Taxes Included Prices" msgstr "含税价格计算代码" #. module: account -#: code:addons/account/account_invoice.py:1030 +#: code:addons/account/account_invoice.py:1042 #, python-format msgid "" "You can not cancel an invoice which is partially paid! You need to " @@ -8139,7 +8186,7 @@ msgid "current month" msgstr "本月" #. module: account -#: code:addons/account/account.py:1052 +#: code:addons/account/account.py:1057 #, python-format msgid "" "No period defined for this date: %s !\n" @@ -8222,10 +8269,12 @@ msgstr "红字发票账簿" #. module: account #: report:account.account.balance:0 #: report:account.central.journal:0 +#: report:account.financial.report:0 #: report:account.general.journal:0 #: report:account.general.ledger:0 #: report:account.general.ledger_landscape:0 #: report:account.partner.balance:0 +#: report:account.third_party_ledger:0 msgid "Filter By" msgstr "筛选" @@ -8258,7 +8307,7 @@ msgid "The partner account used for this invoice." msgstr "这发票用这业务伙伴科目" #. module: account -#: code:addons/account/account.py:3296 +#: code:addons/account/account.py:3313 #, python-format msgid "Tax %.2f%%" msgstr "税 %.2f%%" @@ -8281,7 +8330,7 @@ msgid "Payment Term Line" msgstr "付款条款明细" #. module: account -#: code:addons/account/account.py:3109 +#: code:addons/account/account.py:3126 #, python-format msgid "Purchase Journal" msgstr "采购账簿" @@ -8366,7 +8415,7 @@ msgid "Unpaid Invoices" msgstr "未支付的发票" #. module: account -#: code:addons/account/account_invoice.py:495 +#: code:addons/account/account_invoice.py:504 #, python-format msgid "The payment term of supplier does not have a payment term line!" msgstr "这个供应商的付款条件没有付款条件行!" @@ -8472,7 +8521,7 @@ msgid "Keep empty for all open fiscal years" msgstr "保留空为打开所有的会计年度" #. module: account -#: code:addons/account/account_move_line.py:1105 +#: code:addons/account/account_move_line.py:1120 #, python-format msgid "The account move (%s) for centralisation has been confirmed!" msgstr "合并的凭证 (%s) 已确认!" @@ -8485,7 +8534,7 @@ msgid "" msgstr "如果它是一个多货币凭证,这金额表示一个可选的其它货币金额." #. module: account -#: code:addons/account/account.py:1307 +#: code:addons/account/account.py:1315 #, python-format msgid "" "You can not validate a non-balanced entry !\n" @@ -8561,7 +8610,7 @@ msgid "Contact Address" msgstr "联系地址" #. module: account -#: code:addons/account/account.py:2256 +#: code:addons/account/account.py:2273 #, python-format msgid "Wrong model !" msgstr "模型有误!" @@ -8598,12 +8647,14 @@ msgstr "合同列表" #: field:account.cashbox.line,starting_id:0 #: field:account.entries.report,reconcile_id:0 #: field:account.financial.report,balance:0 +#: field:account.financial.report,credit:0 +#: field:account.financial.report,debit:0 msgid "unknown" msgstr "未知的" #. module: account #: field:account.fiscalyear.close,journal_id:0 -#: code:addons/account/account.py:3113 +#: code:addons/account/account.py:3130 #, python-format msgid "Opening Entries Journal" msgstr "账簿的开账分录" @@ -8622,7 +8673,7 @@ msgid "" msgstr "这科目用于损益(如果是利润:金额就加,损失:金额就减)用作计算损益报表" #. module: account -#: code:addons/account/account_invoice.py:808 +#: code:addons/account/account_invoice.py:819 #, python-format msgid "Please define sequence on the journal related to this invoice." msgstr "请为这张发票对应的凭证簿选择编号规则" @@ -8708,7 +8759,7 @@ msgid "Period from" msgstr "会计期间从" #. module: account -#: code:addons/account/account.py:3110 +#: code:addons/account/account.py:3127 #, python-format msgid "Sales Refund Journal" msgstr "销售红字发票账簿" @@ -8755,7 +8806,7 @@ msgid "Purchase Tax(%)" msgstr "进项税(%)" #. module: account -#: code:addons/account/account_invoice.py:810 +#: code:addons/account/account_invoice.py:821 #, python-format msgid "Please create some invoice lines." msgstr "请创建发票明细。" @@ -8771,7 +8822,7 @@ msgid "Display Detail" msgstr "显示明细" #. module: account -#: code:addons/account/account.py:3118 +#: code:addons/account/account.py:3135 #, python-format msgid "SCNJ" msgstr "SCNJ" @@ -8805,8 +8856,6 @@ msgstr "结束会计期间" #: field:account.account.template,financial_report_ids:0 #: model:ir.actions.act_window,name:account.action_account_financial_report_tree #: model:ir.actions.act_window,name:account.action_account_report -#: model:ir.actions.act_window,name:account.action_account_report_bs -#: model:ir.actions.act_window,name:account.action_account_report_pl #: model:ir.ui.menu,name:account.menu_account_reports msgid "Financial Reports" msgstr "会计报表" @@ -8821,6 +8870,7 @@ msgstr "会计报表" #: field:account.common.journal.report,period_from:0 #: field:account.common.partner.report,period_from:0 #: field:account.common.report,period_from:0 +#: report:account.financial.report:0 #: report:account.general.journal:0 #: field:account.general.journal,period_from:0 #: report:account.general.ledger:0 @@ -8841,6 +8891,7 @@ msgstr "开始会计期间" #. module: account #: field:account.aged.trial.balance,direction_selection:0 +#: report:account.aged_trial_balance:0 msgid "Analysis Direction" msgstr "分析趋势" @@ -8860,7 +8911,7 @@ msgstr "账簿视图" #. module: account #: view:account.move.line:0 -#: code:addons/account/account_move_line.py:1046 +#: code:addons/account/account_move_line.py:1061 #, python-format msgid "Total credit" msgstr "贷方合计" @@ -8926,6 +8977,7 @@ msgstr "银行对账单" #: report:account.analytic.account.inverted.balance:0 #: report:account.central.journal:0 #: field:account.entries.report,balance:0 +#: report:account.financial.report:0 #: report:account.general.journal:0 #: report:account.general.ledger:0 #: report:account.general.ledger_landscape:0 @@ -9002,7 +9054,7 @@ msgstr "" "此界面用于会计输入正式的单据。如果需要输入一张客户发票,首先选择好账簿和会计期间,然后首先输入利润科目的分录,系统会自动处理相关的税和应收款。" #. module: account -#: code:addons/account/wizard/account_automatic_reconcile.py:152 +#: code:addons/account/wizard/account_automatic_reconcile.py:148 #, python-format msgid "You must select accounts to reconcile" msgstr "您必须选择核销科目" @@ -9026,7 +9078,6 @@ msgstr "" "定时间段内是否允许过账" #. module: account -#: report:account.third_party_ledger:0 #: report:account.third_party_ledger_other:0 msgid "Filters By" msgstr "筛选" @@ -9048,7 +9099,7 @@ msgid "Move" msgstr "凭证" #. module: account -#: code:addons/account/account_move_line.py:1153 +#: code:addons/account/account_move_line.py:1168 #, python-format msgid "You can not change the tax, you should remove and recreate lines !" msgstr "您不能更改此税目,请移除并重新创建凭证!" @@ -9104,7 +9155,7 @@ msgid "Consolidated Children" msgstr "合并子科目" #. module: account -#: code:addons/account/wizard/account_fiscalyear_close.py:87 +#: code:addons/account/wizard/account_fiscalyear_close.py:103 #, python-format msgid "" "The journal must have centralised counterpart without the Skipping draft " @@ -9165,6 +9216,7 @@ msgstr "没有定期开账/关账期间,请创建一个再设置期初余额 #: field:account.common.journal.report,period_to:0 #: field:account.common.partner.report,period_to:0 #: field:account.common.report,period_to:0 +#: report:account.financial.report:0 #: report:account.general.journal:0 #: field:account.general.journal,period_to:0 #: report:account.general.ledger:0 @@ -9223,6 +9275,7 @@ msgstr "周期性凭证" #. module: account #: report:account.account.balance:0 #: field:account.aged.trial.balance,date_from:0 +#: report:account.aged_trial_balance:0 #: field:account.balance.report,date_from:0 #: report:account.central.journal:0 #: field:account.central.journal,date_from:0 @@ -9230,6 +9283,7 @@ msgstr "周期性凭证" #: field:account.common.journal.report,date_from:0 #: field:account.common.partner.report,date_from:0 #: field:account.common.report,date_from:0 +#: report:account.financial.report:0 #: field:account.fiscalyear,date_start:0 #: report:account.general.journal:0 #: field:account.general.journal,date_from:0 @@ -9272,7 +9326,7 @@ msgid "Unreconciled" msgstr "反核销" #. module: account -#: code:addons/account/account_invoice.py:828 +#: code:addons/account/account_invoice.py:839 #, python-format msgid "Bad total !" msgstr "坏的合计!" @@ -9333,7 +9387,7 @@ msgid "Comparison" msgstr "比较" #. module: account -#: code:addons/account/account_invoice.py:372 +#: code:addons/account/account_invoice.py:381 #, python-format msgid "Unknown Error" msgstr "未知错误" @@ -9370,6 +9424,7 @@ msgstr "使凭证生效" #: report:account.analytic.account.inverted.balance:0 #: report:account.central.journal:0 #: field:account.entries.report,credit:0 +#: report:account.financial.report:0 #: report:account.general.journal:0 #: report:account.general.ledger:0 #: report:account.general.ledger_landscape:0 @@ -9470,9 +9525,11 @@ msgstr "过去30天的成本凭证" #: view:accounting.report:0 #: selection:accounting.report,filter:0 #: selection:accounting.report,filter_cmp:0 +#: code:addons/account/report/common_report_header.py:99 #: model:ir.actions.act_window,name:account.action_account_period_form #: model:ir.ui.menu,name:account.menu_action_account_period_form #: model:ir.ui.menu,name:account.next_id_23 +#, python-format msgid "Periods" msgstr "会计期间" @@ -9636,6 +9693,7 @@ msgstr "已登账" #: field:account.common.journal.report,date_to:0 #: field:account.common.partner.report,date_to:0 #: field:account.common.report,date_to:0 +#: report:account.financial.report:0 #: field:account.fiscalyear,date_stop:0 #: report:account.general.journal:0 #: field:account.general.journal,date_to:0 @@ -9683,7 +9741,7 @@ msgid "No detail" msgstr "不详" #. module: account -#: code:addons/account/account_analytic_line.py:102 +#: code:addons/account/account_analytic_line.py:100 #, python-format msgid "There is no income account defined for this product: \"%s\" (id:%d)" msgstr "没有为此产品 \"%s\" (id:%d):定义利润科目" @@ -9719,6 +9777,7 @@ msgid "Verification Total" msgstr "检查合计数" #. module: account +#: report:account.aged_trial_balance:0 #: report:account.analytic.account.balance:0 #: report:account.analytic.account.inverted.balance:0 #: report:account.analytic.account.quantity_cost_ledger:0 @@ -9739,6 +9798,7 @@ msgstr "所有账簿" #. module: account #: field:account.account,company_id:0 +#: report:account.account.balance:0 #: field:account.aged.trial.balance,company_id:0 #: field:account.analytic.journal,company_id:0 #: field:account.balance.report,company_id:0 @@ -9753,7 +9813,9 @@ msgstr "所有账簿" #: field:account.entries.report,company_id:0 #: field:account.fiscal.position,company_id:0 #: field:account.fiscalyear,company_id:0 +#: report:account.general.journal:0 #: field:account.general.journal,company_id:0 +#: report:account.general.ledger_landscape:0 #: field:account.installer,company_id:0 #: field:account.invoice,company_id:0 #: field:account.invoice.line,company_id:0 @@ -9763,6 +9825,8 @@ msgstr "所有账簿" #: view:account.journal:0 #: field:account.journal,company_id:0 #: field:account.journal.period,company_id:0 +#: report:account.journal.period.print:0 +#: report:account.journal.period.print.sale.purchase:0 #: field:account.model,company_id:0 #: field:account.move,company_id:0 #: field:account.move.line,company_id:0 @@ -9916,6 +9980,7 @@ msgstr "供应商发票" #: report:account.analytic.account.inverted.balance:0 #: report:account.central.journal:0 #: field:account.entries.report,debit:0 +#: report:account.financial.report:0 #: report:account.general.journal:0 #: report:account.general.ledger:0 #: report:account.general.ledger_landscape:0 @@ -9949,6 +10014,8 @@ msgstr "错误!您不能创建递归的科目模板。" #. module: account #: selection:account.print.journal,sort_selection:0 +#: code:addons/account/report/account_journal.py:197 +#, python-format msgid "Journal Entry Number" msgstr "会计凭证编号" @@ -9966,7 +10033,7 @@ msgid "" msgstr "如果会计科目已经有过会计凭证,且现在是‘关闭’类型,不能改为其他类型。" #. module: account -#: code:addons/account/account_move_line.py:832 +#: code:addons/account/account_move_line.py:843 #, python-format msgid "Entry is already reconciled" msgstr "分录已核销" @@ -10003,8 +10070,10 @@ msgstr "" "内部类型用于对不同类型的科目进行控制:视图科目不能做凭证,合并科目用于在多公司合并中指定子科目,应收应付科目用于业务伙伴,关闭科目用于不再使用的科目。" #. module: account +#: report:account.account.balance:0 #: selection:account.balance.report,display_account:0 #: selection:account.common.account.report,display_account:0 +#: report:account.general.ledger_landscape:0 #: selection:account.report.general.ledger,display_account:0 msgid "With movements" msgstr "进展" @@ -10122,8 +10191,8 @@ msgid "Statistic Reports" msgstr "统计报表" #. module: account -#: code:addons/account/account_move_line.py:1155 -#: code:addons/account/account_move_line.py:1238 +#: code:addons/account/account_move_line.py:1170 +#: code:addons/account/account_move_line.py:1253 #, python-format msgid "Bad account!" msgstr "无效科目!" @@ -10151,7 +10220,7 @@ msgid "Accounts Mapping" msgstr "科目一览" #. module: account -#: code:addons/account/account_invoice.py:364 +#: code:addons/account/account_invoice.py:373 #, python-format msgid "Invoice '%s' is waiting for validation." msgstr "发票'%s'是等待复核。" @@ -10406,6 +10475,7 @@ msgstr "account.addtmpl.wizard" #. module: account #: field:account.aged.trial.balance,result_selection:0 +#: report:account.aged_trial_balance:0 #: field:account.common.partner.report,result_selection:0 #: report:account.partner.balance:0 #: field:account.partner.balance,result_selection:0 @@ -10479,6 +10549,8 @@ msgstr "到期日期" #. module: account #: selection:account.aged.trial.balance,direction_selection:0 +#: code:addons/account/report/account_aged_partner_balance.py:383 +#, python-format msgid "Future" msgstr "前景" diff --git a/addons/account/installer.py b/addons/account/installer.py index 6173ea9213e..05a0f6b455e 100644 --- a/addons/account/installer.py +++ b/addons/account/installer.py @@ -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 = {} diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py index 00d5e520c42..fa2d071695b 100644 --- a/addons/account/report/account_invoice_report.py +++ b/addons/account/report/account_invoice_report.py @@ -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), diff --git a/addons/account_analytic_plans/i18n/ru.po b/addons/account_analytic_plans/i18n/ru.po index 37d01818a6f..71b557f0169 100644 --- a/addons/account_analytic_plans/i18n/ru.po +++ b/addons/account_analytic_plans/i18n/ru.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-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 \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 diff --git a/addons/account_asset/account_asset.py b/addons/account_asset/account_asset.py index 4c6f9b7a637..585798a5235 100644 --- a/addons/account_asset/account_asset.py +++ b/addons/account_asset/account_asset.py @@ -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"\ diff --git a/addons/account_check_writing/i18n/pl.po b/addons/account_check_writing/i18n/pl.po new file mode 100644 index 00000000000..c95da4456ca --- /dev/null +++ b/addons/account_check_writing/i18n/pl.po @@ -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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \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 \n" +"Language-Team: Polish \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 "" diff --git a/addons/account_payment/account_payment.py b/addons/account_payment/account_payment.py index fceff99b3f2..84eeddfb5db 100644 --- a/addons/account_payment/account_payment.py +++ b/addons/account_payment/account_payment.py @@ -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)]}), diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index 3ae421308b5..f25318727df 100644 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -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."), diff --git a/addons/account_voucher/report/account_voucher_sales_receipt.py b/addons/account_voucher/report/account_voucher_sales_receipt.py index 53aa5cd4a0d..fdadfc6bc94 100644 --- a/addons/account_voucher/report/account_voucher_sales_receipt.py +++ b/addons/account_voucher/report/account_voucher_sales_receipt.py @@ -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'), diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml index 665ad4fb17f..abe47935849 100644 --- a/addons/account_voucher/voucher_sales_purchase_view.xml +++ b/addons/account_voucher/voucher_sales_purchase_view.xml @@ -64,7 +64,7 @@ -
TOTAL
+
+
Total
@@ -53,4 +53,4 @@ - \ No newline at end of file + diff --git a/addons/l10n_ar/l10n_ar_wizard.xml b/addons/l10n_ar/l10n_ar_wizard.xml index 9a2fa377155..3c94d3db7a8 100644 --- a/addons/l10n_ar/l10n_ar_wizard.xml +++ b/addons/l10n_ar/l10n_ar_wizard.xml @@ -2,13 +2,9 @@ - - Generate Chart of Accounts from a Chart Template - 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. - - automatic - + + open + diff --git a/addons/l10n_at/l10n_chart_at_wizard.xml b/addons/l10n_at/l10n_chart_at_wizard.xml index b23d9be6cb5..efc68ce13e9 100644 --- a/addons/l10n_at/l10n_chart_at_wizard.xml +++ b/addons/l10n_at/l10n_chart_at_wizard.xml @@ -1,12 +1,8 @@ - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_be/l10n_be_wizard.yml b/addons/l10n_be/l10n_be_wizard.yml index 178009be7ff..0b16827225f 100644 --- a/addons/l10n_be/l10n_be_wizard.yml +++ b/addons/l10n_be/l10n_be_wizard.yml @@ -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 = { diff --git a/addons/l10n_ca/l10n_ca_wizard.xml b/addons/l10n_ca/l10n_ca_wizard.xml index 3bdc380325d..efc68ce13e9 100644 --- a/addons/l10n_ca/l10n_ca_wizard.xml +++ b/addons/l10n_ca/l10n_ca_wizard.xml @@ -1,13 +1,9 @@ - - Generate Chart of Accounts from a Chart Template - 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. - - automatic - + + open + diff --git a/addons/l10n_ch/wizard.xml b/addons/l10n_ch/wizard.xml index 084159aa36d..792bd21a2fc 100644 --- a/addons/l10n_ch/wizard.xml +++ b/addons/l10n_ch/wizard.xml @@ -1,13 +1,7 @@ - - Generate Chart of Accounts for l10n_ch - 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. - - 4 - automatic + + open diff --git a/addons/l10n_cl/l10n_cl_wizard.xml b/addons/l10n_cl/l10n_cl_wizard.xml index fd0d29f1edb..bcbd9a43f27 100644 --- a/addons/l10n_cl/l10n_cl_wizard.xml +++ b/addons/l10n_cl/l10n_cl_wizard.xml @@ -1,14 +1,9 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic - + + open + diff --git a/addons/l10n_cn/l10n_chart_cn_wizard.xml b/addons/l10n_cn/l10n_chart_cn_wizard.xml index 0a098120682..6919eb199b6 100644 --- a/addons/l10n_cn/l10n_chart_cn_wizard.xml +++ b/addons/l10n_cn/l10n_chart_cn_wizard.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_cr/l10n_wizard.xml b/addons/l10n_cr/l10n_wizard.xml index ef37667b318..6919eb199b6 100644 --- a/addons/l10n_cr/l10n_wizard.xml +++ b/addons/l10n_cr/l10n_wizard.xml @@ -1,10 +1,8 @@ - - - - automatic - + + open + diff --git a/addons/l10n_de/l10n_de_wizard.xml b/addons/l10n_de/l10n_de_wizard.xml index 3a0dcd34bd3..efc68ce13e9 100644 --- a/addons/l10n_de/l10n_de_wizard.xml +++ b/addons/l10n_de/l10n_de_wizard.xml @@ -1,12 +1,9 @@ - - Generiert Kontenplan aus Vorlage - 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. - - automatic - + + open + diff --git a/addons/l10n_ec/l10n_chart_ec_wizard.xml b/addons/l10n_ec/l10n_chart_ec_wizard.xml index 9906cf9828c..6919eb199b6 100644 --- a/addons/l10n_ec/l10n_chart_ec_wizard.xml +++ b/addons/l10n_ec/l10n_chart_ec_wizard.xml @@ -1,13 +1,8 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic - + + open + diff --git a/addons/l10n_es/l10n_es_wizard.xml b/addons/l10n_es/l10n_es_wizard.xml index ec30f9e9e25..52aaa88fdab 100644 --- a/addons/l10n_es/l10n_es_wizard.xml +++ b/addons/l10n_es/l10n_es_wizard.xml @@ -1,9 +1,7 @@ - - - - automatic + + open diff --git a/addons/l10n_fr/l10n_fr_wizard.xml b/addons/l10n_fr/l10n_fr_wizard.xml index 897da1d5414..bcbd9a43f27 100644 --- a/addons/l10n_fr/l10n_fr_wizard.xml +++ b/addons/l10n_fr/l10n_fr_wizard.xml @@ -1,12 +1,9 @@ - - - - automatic - + + open + diff --git a/addons/l10n_gr/l10n_gr_wizard.xml b/addons/l10n_gr/l10n_gr_wizard.xml index 4fa564e2155..6919eb199b6 100644 --- a/addons/l10n_gr/l10n_gr_wizard.xml +++ b/addons/l10n_gr/l10n_gr_wizard.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_gt/l10n_gt_base.xml b/addons/l10n_gt/l10n_gt_base.xml index 4ba27d6a5c4..8caf6ebe48c 100644 --- a/addons/l10n_gt/l10n_gt_base.xml +++ b/addons/l10n_gt/l10n_gt_base.xml @@ -1,14 +1,8 @@ - - Generar la nomenclatura contable a partir de un modelo - 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. - - - automatic + + open diff --git a/addons/l10n_hn/l10n_hn_base.xml b/addons/l10n_hn/l10n_hn_base.xml index a12d93db034..b8b85c3f2a7 100644 --- a/addons/l10n_hn/l10n_hn_base.xml +++ b/addons/l10n_hn/l10n_hn_base.xml @@ -2,13 +2,7 @@ - - Generar la nomenclatura contable a partir de un modelo - 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. - - + open diff --git a/addons/l10n_in/l10n_in_wizard.xml b/addons/l10n_in/l10n_in_wizard.xml index 20d35aa09a2..bcbd9a43f27 100644 --- a/addons/l10n_in/l10n_in_wizard.xml +++ b/addons/l10n_in/l10n_in_wizard.xml @@ -1,13 +1,8 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py b/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py index 085a2679db2..b7c3926d727 100644 --- a/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py +++ b/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py @@ -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), diff --git a/addons/l10n_in_hr_payroll/report/payment_advice_report.py b/addons/l10n_in_hr_payroll/report/payment_advice_report.py index 838334913a5..a264368be94 100644 --- a/addons/l10n_in_hr_payroll/report/payment_advice_report.py +++ b/addons/l10n_in_hr_payroll/report/payment_advice_report.py @@ -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), diff --git a/addons/l10n_in_hr_payroll/report/payslip_report.py b/addons/l10n_in_hr_payroll/report/payslip_report.py index b688af4329b..a78d9850667 100644 --- a/addons/l10n_in_hr_payroll/report/payslip_report.py +++ b/addons/l10n_in_hr_payroll/report/payslip_report.py @@ -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), diff --git a/addons/l10n_it/l10n_chart_it_generic.xml b/addons/l10n_it/l10n_chart_it_generic.xml index 52269c71962..792bd21a2fc 100644 --- a/addons/l10n_it/l10n_chart_it_generic.xml +++ b/addons/l10n_it/l10n_chart_it_generic.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_lu/l10n_lu_wizard.xml b/addons/l10n_lu/l10n_lu_wizard.xml index 32351428bb6..6919eb199b6 100644 --- a/addons/l10n_lu/l10n_lu_wizard.xml +++ b/addons/l10n_lu/l10n_lu_wizard.xml @@ -1,10 +1,8 @@ - - - - automatic - + + open + diff --git a/addons/l10n_ma/l10n_ma_wizard.xml b/addons/l10n_ma/l10n_ma_wizard.xml index 428a17e081a..6919eb199b6 100644 --- a/addons/l10n_ma/l10n_ma_wizard.xml +++ b/addons/l10n_ma/l10n_ma_wizard.xml @@ -1,10 +1,8 @@ - - - - automatic - + + open + diff --git a/addons/l10n_mx/i18n/es_MX.po b/addons/l10n_mx/i18n/es_MX.po index eec525b5f53..305ec408af2 100644 --- a/addons/l10n_mx/i18n/es_MX.po +++ b/addons/l10n_mx/i18n/es_MX.po @@ -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 diff --git a/addons/l10n_mx/l10n_chart_mx_wizard.xml b/addons/l10n_mx/l10n_chart_mx_wizard.xml index aeea1f3cd69..6919eb199b6 100644 --- a/addons/l10n_mx/l10n_chart_mx_wizard.xml +++ b/addons/l10n_mx/l10n_chart_mx_wizard.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_nl/l10n_nl_wizard.xml b/addons/l10n_nl/l10n_nl_wizard.xml index bcdd183b12c..6919eb199b6 100644 --- a/addons/l10n_nl/l10n_nl_wizard.xml +++ b/addons/l10n_nl/l10n_nl_wizard.xml @@ -1,19 +1,8 @@ - - - Genereer Grootboekrekingschema vanuit het Nederlandse Grootboek Template - 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. - - - automatic - + + open + diff --git a/addons/l10n_pe/l10n_pe_wizard.xml b/addons/l10n_pe/l10n_pe_wizard.xml index e1189fbcc2d..3c94d3db7a8 100644 --- a/addons/l10n_pe/l10n_pe_wizard.xml +++ b/addons/l10n_pe/l10n_pe_wizard.xml @@ -2,12 +2,8 @@ - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_pl/l10n_chart_pl_wizard.xml b/addons/l10n_pl/l10n_chart_pl_wizard.xml index aded9e3b2a3..6919eb199b6 100644 --- a/addons/l10n_pl/l10n_chart_pl_wizard.xml +++ b/addons/l10n_pl/l10n_chart_pl_wizard.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_ro/l10n_chart_ro_wizard.xml b/addons/l10n_ro/l10n_chart_ro_wizard.xml index bafb7b26f82..6919eb199b6 100644 --- a/addons/l10n_ro/l10n_chart_ro_wizard.xml +++ b/addons/l10n_ro/l10n_chart_ro_wizard.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_syscohada/l10n_syscohada_wizard.xml b/addons/l10n_syscohada/l10n_syscohada_wizard.xml index 7174ef438b7..792bd21a2fc 100644 --- a/addons/l10n_syscohada/l10n_syscohada_wizard.xml +++ b/addons/l10n_syscohada/l10n_syscohada_wizard.xml @@ -1,11 +1,7 @@ - - Generate Chart of Accounts from a Chart Template - 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. - - automatic - + + open + diff --git a/addons/l10n_th/account_data.xml b/addons/l10n_th/account_data.xml index d5885d4b92b..d730caa8404 100644 --- a/addons/l10n_th/account_data.xml +++ b/addons/l10n_th/account_data.xml @@ -643,14 +643,9 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic - + + open + diff --git a/addons/l10n_tr/l10n_tr_wizard.xml b/addons/l10n_tr/l10n_tr_wizard.xml index e7ae8dc2d82..59668347bed 100644 --- a/addons/l10n_tr/l10n_tr_wizard.xml +++ b/addons/l10n_tr/l10n_tr_wizard.xml @@ -1,16 +1,8 @@ - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_uk/l10n_uk_wizard.xml b/addons/l10n_uk/l10n_uk_wizard.xml index cb947163ab3..1b8d528c0e8 100644 --- a/addons/l10n_uk/l10n_uk_wizard.xml +++ b/addons/l10n_uk/l10n_uk_wizard.xml @@ -1,41 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - wizard.multi.charts.accounts - - - - - - - - - - Generate UK Chart of Accounts from a Chart Template - ir.actions.act_window - wizard.multi.charts.accounts - - form - form - new - - - - - 10 - once + open diff --git a/addons/l10n_us/l10n_us_wizard.xml b/addons/l10n_us/l10n_us_wizard.xml index 8c306f155fe..6919eb199b6 100644 --- a/addons/l10n_us/l10n_us_wizard.xml +++ b/addons/l10n_us/l10n_us_wizard.xml @@ -1,12 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - automatic + + open diff --git a/addons/l10n_uy/l10n_uy_wizard.xml b/addons/l10n_uy/l10n_uy_wizard.xml index 6543664b2b6..49cbeca89f9 100644 --- a/addons/l10n_uy/l10n_uy_wizard.xml +++ b/addons/l10n_uy/l10n_uy_wizard.xml @@ -1,9 +1,8 @@ - - - automatic + + open diff --git a/addons/l10n_ve/l10n_chart_ve_wizard.xml b/addons/l10n_ve/l10n_chart_ve_wizard.xml index 823fa833313..6919eb199b6 100644 --- a/addons/l10n_ve/l10n_chart_ve_wizard.xml +++ b/addons/l10n_ve/l10n_chart_ve_wizard.xml @@ -1,15 +1,7 @@ - - - Generate Chart of Accounts from a Chart Template - 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. - - - automatic + + open diff --git a/addons/mail/data/mail_demo.xml b/addons/mail/data/mail_demo.xml index 7bda32c002b..bda93fc485d 100644 --- a/addons/mail/data/mail_demo.xml +++ b/addons/mail/data/mail_demo.xml @@ -8,6 +8,7 @@ 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. comment + @@ -16,6 +17,7 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company comment + @@ -24,22 +26,25 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company Thanks, but where is Christine's office, if I may ask? (I'm new here) comment + + mail.group + + Building B3, second floor on the right :-) + + comment + + + + mail.group Great news, I need to buy a new fridge, I think I can pay it with the eco-vouchers! comment - - - - mail.group - - Building B3, second floor on the right :-) - - comment + diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py index 52d26ebb51b..416afa219d6 100644 --- a/addons/mail/mail_followers.py +++ b/addons/mail/mail_followers.py @@ -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) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 6e67c957590..6eb4edf25e3 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -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 = """
+ % 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)} +
+ + <%def name="display_message(message)"> +
+ Subject: ${message.subject}
+ Body: ${message.body} +
+ + + <%def name="display_expandable()"> +
This is an expandable.
+ + """ + + 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 #------------------------------------------------------ diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index efd1c581fe5..93b35797fd5 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -29,6 +29,7 @@ + @@ -38,6 +39,7 @@ + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 59db6a18bc0..e0d4e102603 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -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 diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index d674814e1be..07b24725b05 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -45,7 +45,7 @@ sequence="10"/> - + @@ -79,4 +79,4 @@
-
\ No newline at end of file +
diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv index c609667c26e..52c6c605109 100644 --- a/addons/mail/security/ir.model.access.csv +++ b/addons/mail/security/ir.model.access.csv @@ -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 \ No newline at end of file diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 7103b1c1db9..27ffdebfc5a 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -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, }, { diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 7668d743eab..ea0db38fd26 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -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
\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
\n', 'plaintext mail incorrectly parsed') + # Do: post a new message, with a known partner + test_msg_id = '' + TEMPLATE_MOD = MAIL_TEMPLATE_PLAINTEXT.replace('Sylvie Lelitre ', user_raoul.email) + mail_new = TEMPLATE_MOD.format(to='Friendly Frogs ', 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 = '' + TEMPLATE_MOD = MAIL_TEMPLATE_PLAINTEXT.replace('Sylvie Lelitre ', '_abcd_') + mail_new = TEMPLATE_MOD.format(to='Friendly Frogs ', 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 , 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 , 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 [] + model passed to message+process -> only attached to group, not to mail reply_msg3 = MAIL_TEMPLATE.format(to='Pretty Pigs , 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') diff --git a/addons/mail/tests/test_mail_access_rights.py b/addons/mail/tests/test_mail_access_rights.py index 544191205b8..7b90e07b9b5 100644 --- a/addons/mail/tests/test_mail_access_rights.py +++ b/addons/mail/tests/test_mail_access_rights.py @@ -51,7 +51,40 @@ class test_mail_access_rights(test_mail.TestMailMockups): self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id) self.partner_raoul_id = self.user_raoul.partner_id.id - def test_00_mail_message_read_access_rights(self): + def test_00_mail_message_search_access_rights(self): + """ Test mail_message search override about access rights. """ + cr, uid, group_pigs_id = self.cr, self.uid, self.group_pigs_id + partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id + user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id + # Data: comment subtype for mail.message creation + ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'mail', 'mt_comment') + subtype_id = ref and ref[1] or False + + # Data: Birds group, private + group_birds_id = self.mail_group.create(self.cr, self.uid, {'name': 'Birds', 'public': 'private'}) + # Data: raoul is member of Pigs + self.mail_group.message_subscribe(cr, uid, [group_pigs_id], [partner_raoul_id]) + # Data: various author_ids, partner_ids, documents + msg_id1 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A', 'subtype_id': subtype_id}) + msg_id2 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B', 'partner_ids': [(6, 0, [partner_bert_id])], 'subtype_id': subtype_id}) + msg_id3 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'subtype_id': subtype_id}) + msg_id4 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_bert_id])], 'subtype_id': subtype_id}) + msg_id5 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+R Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_raoul_id])], 'subtype_id': subtype_id}) + msg_id6 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Birds', 'model': 'mail.group', 'res_id': group_birds_id, 'subtype_id': subtype_id}) + msg_id7 = self.mail_message.create(cr, user_bert_id, {'subject': '_Test', 'body': 'B', 'subtype_id': subtype_id}) + msg_id8 = self.mail_message.create(cr, user_bert_id, {'subject': '_Test', 'body': 'B+R', 'partner_ids': [(6, 0, [partner_raoul_id])], 'subtype_id': subtype_id}) + + # Test: Bert: 2 messages that have Bert in partner_ids + 2 messages as author + msg_ids = self.mail_message.search(cr, user_bert_id, [('subject', 'like', '_Test')]) + self.assertEqual(set([msg_id2, msg_id4, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed') + # Test: Raoul: 3 messages on Pigs Raoul can read (employee can read group with default values), 0 on Birds (private group) + msg_ids = self.mail_message.search(cr, user_raoul_id, [('subject', 'like', '_Test'), ('body', 'like', 'A')]) + self.assertEqual(set([msg_id3, msg_id4, msg_id5]), set(msg_ids), 'mail_message search failed') + # Test: Admin: all messages + msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', '_Test')]) + self.assertEqual(set([msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed') + + def test_05_mail_message_read_access_rights(self): """ Test basic mail_message read access rights. """ cr, uid = self.cr, self.uid partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id @@ -98,10 +131,6 @@ class test_mail_access_rights(test_mail.TestMailMockups): self.assertRaises(except_orm, self.mail_message.read, cr, user_bert_id, message_id) - def test_05_mail_message_search_access_rights(self): - """ Test mail_message search override about access rights. """ - self.assertTrue(1 == 1, 'Test not implemented, do not replace by return True') - def test_10_mail_flow_access_rights(self): """ Test a Chatter-looks alike flow. """ cr, uid = self.cr, self.uid diff --git a/addons/membership/membership.py b/addons/membership/membership.py index 87af723f2f9..5e3816419f8 100644 --- a/addons/membership/membership.py +++ b/addons/membership/membership.py @@ -150,11 +150,11 @@ class membership_line(osv.osv): 'account_invoice_line': fields.many2one('account.invoice.line', 'Account Invoice line', readonly=True), 'account_invoice_id': fields.related('account_invoice_line', 'invoice_id', type='many2one', relation='account.invoice', string='Invoice', readonly=True), 'state': fields.function(_state, - string='Membership State', type='selection', + string='Membership Status', type='selection', selection=STATE, store = { 'account.invoice': (_get_membership_lines, ['state'], 10), 'res.partner': (_get_partners, ['membership_state'], 12), - }, help="""It indicates the membership state. + }, help="""It indicates the membership status. -Non Member: A member who has not applied for any membership. -Cancelled Member: A member who has cancelled his membership. -Old Member: A member whose membership date has expired. @@ -323,7 +323,7 @@ class Partner(osv.osv): help = 'The price negotiated by the partner'), 'membership_state': fields.function( __get_membership_state, - string = 'Current Membership State', type = 'selection', + string = 'Current Membership Status', type = 'selection', selection = STATE, store = { 'account.invoice': (_get_invoice_partner, ['state'], 10), diff --git a/addons/mrp/i18n/zh_CN.po b/addons/mrp/i18n/zh_CN.po index 6ef704ac2b9..74bed25d597 100644 --- a/addons/mrp/i18n/zh_CN.po +++ b/addons/mrp/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:49+0000\n" -"PO-Revision-Date: 2012-02-13 09:52+0000\n" -"Last-Translator: Jeff Wang \n" +"PO-Revision-Date: 2012-10-25 17:08+0000\n" +"Last-Translator: ccdos \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:06+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: mrp #: view:mrp.routing.workcenter:0 @@ -89,7 +89,7 @@ msgstr "单位成本" #. module: mrp #: view:mrp.production:0 msgid "Scrap Products" -msgstr "原料消耗" +msgstr "报废原料" #. module: mrp #: model:ir.actions.act_window,name:mrp.mrp_routing_action @@ -135,7 +135,7 @@ msgstr "生产订单编号" #. module: mrp #: view:mrp.production:0 msgid "Finished Products" -msgstr "已完工数量" +msgstr "产成品" #. module: mrp #: view:mrp.production:0 @@ -209,7 +209,7 @@ msgstr "输入一个费用产品用于跟踪辅助核算会计中的成本" #. module: mrp #: model:process.node,note:mrp.process_node_purchaseprocure0 msgid "For purchased material" -msgstr "用于采购原料" +msgstr "用于外购的物料" #. module: mrp #: model:ir.actions.act_window,help:mrp.product_form_config_action @@ -1288,7 +1288,7 @@ msgstr "如果产品的供应方法是外购,系统创建采购订单。" #. module: mrp #: model:ir.model,name:mrp.model_procurement_order msgid "Procurement" -msgstr "需求单" +msgstr "需求" #. module: mrp #: model:ir.actions.act_window,name:mrp.action_view_mrp_product_price_wizard diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 3ae27bf2c41..f8b53583a8c 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -499,12 +499,12 @@ class mrp_production(osv.osv): [('draft', 'New'), ('cancel', 'Cancelled'), ('picking_except', 'Picking Exception'), ('confirmed', 'Waiting Goods'), ('ready', 'Ready to Produce'), ('in_production', 'Production Started'), ('done', 'Done')], string='Status', readonly=True, - help="When the production order is created the state is set to 'Draft'.\n\ - If the order is confirmed the state is set to 'Waiting Goods'.\n\ - If any exceptions are there, the state is set to 'Picking Exception'.\n\ - If the stock is available then the state is set to 'Ready to Produce'.\n\ - When the production gets started then the state is set to 'In Production'.\n\ - When the production is over, the state is set to 'Done'."), + help="When the production order is created the status is set to 'Draft'.\n\ + If the order is confirmed the status is set to 'Waiting Goods'.\n\ + If any exceptions are there, the status is set to 'Picking Exception'.\n\ + If the stock is available then the status is set to 'Ready to Produce'.\n\ + When the production gets started then the status is set to 'In Production'.\n\ + When the production is over, the status is set to 'Done'."), 'hour_total': fields.function(_production_calc, type='float', string='Total Hours', multi='workorder', store=True), 'cycle_total': fields.function(_production_calc, type='float', string='Total Cycles', multi='workorder', store=True), 'user_id':fields.many2one('res.users', 'Responsible'), diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index 57531c8b4bb..42a6f6ca833 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -620,10 +620,10 @@
- +